PDA

View Full Version : how to "shift" a data into led matrix display ?



CuriousOne
- 8th January 2015, 18:56
Hello.

I have 5x7 led matrix display connected to 16F876. I want to display some text on, scrolling from right to left. I have prepared a set of data, which has 1 where dot should be lit, and 0 - where it should not. This data looks like array of bits, with length of 64 bits and height of 8 bits. In "normal" basic, I can use MID$(VAR, START, LENGTH) variable to "read" through te array, but how can I do this in PBP ?

Amoque
- 9th January 2015, 03:04
I use a 5 element byte array: Read one byte from data and output to display vertically in column 5 (rightmost). Loop several times... Move the byte in column five to array element four (the next column to the left) and load the next byte into element 5. Loop several times... Continue shifting each byte to the left as you load new bytes on the right.

So... each byte of data represents one column of a 5x7 alphanumeric character (you're only using 7 of the 8 bits), Read all five columns, then put a 0 in column 5 (for the space between letters) then read the next five columns...

CuriousOne
- 9th January 2015, 04:53
Yes but how put data in code, in normal basic I would do a thing like this:

R1$="000101110101010101010101" : whole data for row 1
R2$="110101010101111110000011" : whole data for row 2

and so on

then I would make a loop:

FOR A=0 TO 64-5
LINE1$=MID$(R1$,A,5) ' read 5 pixels from row variable and shift it left on next read
LINE2$=MID$(R2$,A,5) ' next lines and so on
GOSUB DISPLAY
NEXT A

CuriousOne
- 9th January 2015, 09:53
OK, trying to do it with arrays:



line1 var bit[12]
arraywrite line1,[%0,%1,%1,%1,%0,%0,%0,%0,%1,%1,%1,%0]


arraywrite gives error, while line1[0]=1 works fine

is there a way to use arraywrite with bit array?

HenrikOlsson
- 9th January 2015, 10:35
Hi,
Don't use a bit-array, use a BYTE-array instead.


Line1 VAR BYTE [8]
ArrayWrite Line1, [%10101010, %10101010, %10101010, %10101010, %10101010, %10101010, %10101010, %10101010]


To access an individual bit in the above array you can use the format

myBit VAR bit
i VAR BYTE
myBit = Line1.0[i] ' Where i of course is the index, or bit number in the array.


/Henrik.

CuriousOne
- 9th January 2015, 11:26
Using bit arrays will make adding of information simpler - it can be visualized during entering the graphical data. Say I want to draw a circle, in BIT, it will look like

001100
010010
010010
001100

Here is the working code, but it has two problems:

1. It is dead huge - 3.3k, so had to use 16F876A
2. If I decrease refresh time, for display to less flicker, some non-needed pixels also come on, but at lower brightness. I suspect, this is because MCU isn't giving "true" gnd connection?




L1 var PORTB.0
L2 VAR PORTB.1
L3 VAR PORTB.2
L4 VAR PORTB.3
L5 VAR PORTB.4
L6 VAR PORTB.5
L7 VAR PORTC.1

C1 VAR PORTC.5
C2 VAR PORTC.4
C3 VAR PORTC.6
C4 VAR PORTC.2
C5 VAR PORTC.3
DEFINE OSC 4

DRO VAR BYTE 'char redraw timing
SVLA VAR BYTE 'char scroll value
SVLA=0
TRIALI VAR BYTE 'char holdon timing


'define arrays

line1 var bit[12]
line2 var bit[12]
line3 var bit[12]
line4 var bit[12]
line5 var bit[12]
line6 var bit[12]
line7 var bit[12]

'write data to array

'line 1
line1[0]=0
line1[1]=1
line1[2]=1
line1[3]=1
line1[4]=0
line1[5]=0
line1[6]=0
line1[7]=1
line1[8]=1
line1[9]=1
line1[10]=0
line1[11]=0

'line 2
line2[0]=1
line2[1]=0
line2[2]=0
line2[3]=0
line2[4]=1
line2[5]=0
line2[6]=1
line2[7]=0
line2[8]=0
line2[9]=0
line2[10]=1
line2[11]=0

'line 3
line3[0]=0
line3[1]=0
line3[2]=0
line3[3]=0
line3[4]=1
line3[5]=0
line3[6]=0
line3[7]=0
line3[8]=0
line3[9]=0
line3[10]=1
line3[11]=0

'line 4
line4[0]=0
line4[1]=1
line4[2]=1
line4[3]=1
line4[4]=1
line4[5]=0
line4[6]=0
line4[7]=0
line4[8]=0
line4[9]=0
line4[10]=1
line4[11]=0

'line 5
line5[0]=1
line5[1]=0
line5[2]=0
line5[3]=0
line5[4]=1
line5[5]=0
line5[6]=1
line5[7]=0
line5[8]=0
line5[9]=0
line5[10]=1
line5[11]=0

'line 6
line6[0]=1
line6[1]=0
line6[2]=0
line6[3]=0
line6[4]=1
line6[5]=0
line6[6]=1
line6[7]=0
line6[8]=0
line6[9]=0
line6[10]=1
line6[11]=0

'line 7
line7[0]=0
line7[1]=1
line7[2]=1
line7[3]=1
line7[4]=0
line7[5]=0
line7[6]=0
line7[7]=1
line7[8]=1
line7[9]=1
line7[10]=0
line7[11]=0


DRO=2 'time refresh set

'turn off display
HIGH L1
HIGH L2
HIGH L3
HIGH L4
HIGH L5
HIGH L6
HIGH L7
LOW C1
LOW C2
LOW C3
LOW C4
LOW C5

cikleri:
FOR SVLA=0 TO 6 'scroll through the array
FOR TRIALI=1 TO 30 'time to show individual char
low L1 'ENABLE LINE 1
IF LINE1[0+SVLA]=1 THEN
HIGH C1
ELSE
LOW C1
ENDIF

IF LINE1[1+SVLA]=1 THEN
HIGH C2
ELSE
LOW C2
ENDIF

IF LINE1[2+SVLA]=1 THEN
HIGH C3
ELSE
LOW C3
ENDIF

IF LINE1[3+SVLA]=1 THEN
HIGH C4
ELSE
LOW C4
ENDIF

IF LINE1[4+SVLA]=1 THEN
HIGH C5
ELSE
LOW C5
ENDIF
PAUSE DRO
HIGH L1

low L2 'ENABLE LINE 2
IF LINE2[0+SVLA]=1 THEN
HIGH C1
ELSE
LOW C1
ENDIF

IF LINE2[1+SVLA]=1 THEN
HIGH C2
ELSE
LOW C2
ENDIF

IF LINE2[2+SVLA]=1 THEN
HIGH C3
ELSE
LOW C3
ENDIF

IF LINE2[3+SVLA]=1 THEN
HIGH C4
ELSE
LOW C4
ENDIF

IF LINE2[4+SVLA]=1 THEN
HIGH C5
ELSE
LOW C5
ENDIF
PAUSE DRO
HIGH L2

low L3 'ENABLE LINE 3
IF LINE3[0+SVLA]=1 THEN
HIGH C1
ELSE
LOW C1
ENDIF

IF LINE3[1+SVLA]=1 THEN
HIGH C2
ELSE
LOW C2
ENDIF

IF LINE3[2+SVLA]=1 THEN
HIGH C3
ELSE
LOW C3
ENDIF

IF LINE3[3+SVLA]=1 THEN
HIGH C4
ELSE
LOW C4
ENDIF

IF LINE3[4+SVLA]=1 THEN
HIGH C5
ELSE
LOW C5
ENDIF
PAUSE DRO
HIGH L3

low L4 'ENABLE LINE 4
IF LINE4[0+SVLA]=1 THEN
HIGH C1
ELSE
LOW C1
ENDIF

IF LINE4[1+SVLA]=1 THEN
HIGH C2
ELSE
LOW C2
ENDIF

IF LINE4[2+SVLA]=1 THEN
HIGH C3
ELSE
LOW C3
ENDIF

IF LINE4[3+SVLA]=1 THEN
HIGH C4
ELSE
LOW C4
ENDIF

IF LINE4[4+SVLA]=1 THEN
HIGH C5
ELSE
LOW C5
ENDIF
PAUSE DRO
HIGH L4

low L5 'ENABLE LINE 5
IF LINE5[0+SVLA]=1 THEN
HIGH C1
ELSE
LOW C1
ENDIF

IF LINE5[1+SVLA]=1 THEN
HIGH C2
ELSE
LOW C2
ENDIF

IF LINE5[2+SVLA]=1 THEN
HIGH C3
ELSE
LOW C3
ENDIF

IF LINE5[3+SVLA]=1 THEN
HIGH C4
ELSE
LOW C4
ENDIF

IF LINE5[4+SVLA]=1 THEN
HIGH C5
ELSE
LOW C5
ENDIF
PAUSE DRO
HIGH L5

low L6 'ENABLE LINE 6
IF LINE6[0+SVLA]=1 THEN
HIGH C1
ELSE
LOW C1
ENDIF

IF LINE6[1+SVLA]=1 THEN
HIGH C2
ELSE
LOW C2
ENDIF

IF LINE6[2+SVLA]=1 THEN
HIGH C3
ELSE
LOW C3
ENDIF

IF LINE6[3+SVLA]=1 THEN
HIGH C4
ELSE
LOW C4
ENDIF

IF LINE6[4+SVLA]=1 THEN
HIGH C5
ELSE
LOW C5
ENDIF
PAUSE DRO
HIGH L6

low L7 'ENABLE LINE 7
IF LINE7[0+SVLA]=1 THEN
HIGH C1
ELSE
LOW C1
ENDIF

IF LINE7[1+SVLA]=1 THEN
HIGH C2
ELSE
LOW C2
ENDIF

IF LINE7[2+SVLA]=1 THEN
HIGH C3
ELSE
LOW C3
ENDIF

IF LINE7[3+SVLA]=1 THEN
HIGH C4
ELSE
LOW C4
ENDIF

IF LINE7[4+SVLA]=1 THEN
HIGH C5
ELSE
LOW C5
ENDIF
PAUSE DRO
HIGH L7
NEXT

PAUSE 5
NEXT
'ROTATE BACK

FOR SVLA=6 TO 0 STEP -1
FOR TRIALI=1 TO 30
low L1 'ENABLE LINE 1
IF LINE1[0+SVLA]=1 THEN
HIGH C1
ELSE
LOW C1
ENDIF

IF LINE1[1+SVLA]=1 THEN
HIGH C2
ELSE
LOW C2
ENDIF

IF LINE1[2+SVLA]=1 THEN
HIGH C3
ELSE
LOW C3
ENDIF

IF LINE1[3+SVLA]=1 THEN
HIGH C4
ELSE
LOW C4
ENDIF

IF LINE1[4+SVLA]=1 THEN
HIGH C5
ELSE
LOW C5
ENDIF
PAUSE DRO
HIGH L1

low L2 'ENABLE LINE 2
IF LINE2[0+SVLA]=1 THEN
HIGH C1
ELSE
LOW C1
ENDIF

IF LINE2[1+SVLA]=1 THEN
HIGH C2
ELSE
LOW C2
ENDIF

IF LINE2[2+SVLA]=1 THEN
HIGH C3
ELSE
LOW C3
ENDIF

IF LINE2[3+SVLA]=1 THEN
HIGH C4
ELSE
LOW C4
ENDIF

IF LINE2[4+SVLA]=1 THEN
HIGH C5
ELSE
LOW C5
ENDIF
PAUSE DRO
HIGH L2

low L3 'ENABLE LINE 3
IF LINE3[0+SVLA]=1 THEN
HIGH C1
ELSE
LOW C1
ENDIF

IF LINE3[1+SVLA]=1 THEN
HIGH C2
ELSE
LOW C2
ENDIF

IF LINE3[2+SVLA]=1 THEN
HIGH C3
ELSE
LOW C3
ENDIF

IF LINE3[3+SVLA]=1 THEN
HIGH C4
ELSE
LOW C4
ENDIF

IF LINE3[4+SVLA]=1 THEN
HIGH C5
ELSE
LOW C5
ENDIF
PAUSE DRO
HIGH L3

low L4 'ENABLE LINE 4
IF LINE4[0+SVLA]=1 THEN
HIGH C1
ELSE
LOW C1
ENDIF

IF LINE4[1+SVLA]=1 THEN
HIGH C2
ELSE
LOW C2
ENDIF

IF LINE4[2+SVLA]=1 THEN
HIGH C3
ELSE
LOW C3
ENDIF

IF LINE4[3+SVLA]=1 THEN
HIGH C4
ELSE
LOW C4
ENDIF

IF LINE4[4+SVLA]=1 THEN
HIGH C5
ELSE
LOW C5
ENDIF
PAUSE DRO
HIGH L4

low L5 'ENABLE LINE 5
IF LINE5[0+SVLA]=1 THEN
HIGH C1
ELSE
LOW C1
ENDIF

IF LINE5[1+SVLA]=1 THEN
HIGH C2
ELSE
LOW C2
ENDIF

IF LINE5[2+SVLA]=1 THEN
HIGH C3
ELSE
LOW C3
ENDIF

IF LINE5[3+SVLA]=1 THEN
HIGH C4
ELSE
LOW C4
ENDIF

IF LINE5[4+SVLA]=1 THEN
HIGH C5
ELSE
LOW C5
ENDIF
PAUSE DRO
HIGH L5

low L6 'ENABLE LINE 6
IF LINE6[0+SVLA]=1 THEN
HIGH C1
ELSE
LOW C1
ENDIF

IF LINE6[1+SVLA]=1 THEN
HIGH C2
ELSE
LOW C2
ENDIF

IF LINE6[2+SVLA]=1 THEN
HIGH C3
ELSE
LOW C3
ENDIF

IF LINE6[3+SVLA]=1 THEN
HIGH C4
ELSE
LOW C4
ENDIF

IF LINE6[4+SVLA]=1 THEN
HIGH C5
ELSE
LOW C5
ENDIF
PAUSE DRO
HIGH L6

low L7 'ENABLE LINE 7
IF LINE7[0+SVLA]=1 THEN
HIGH C1
ELSE
LOW C1
ENDIF

IF LINE7[1+SVLA]=1 THEN
HIGH C2
ELSE
LOW C2
ENDIF

IF LINE7[2+SVLA]=1 THEN
HIGH C3
ELSE
LOW C3
ENDIF

IF LINE7[3+SVLA]=1 THEN
HIGH C4
ELSE
LOW C4
ENDIF

IF LINE7[4+SVLA]=1 THEN
HIGH C5
ELSE
LOW C5
ENDIF
PAUSE DRO
HIGH L7
NEXT

PAUSE 5
NEXT

GOTO CIKLERI

HenrikOlsson
- 9th January 2015, 12:42
Double post, moderator please remove if possible.
/Henrik.

HenrikOlsson
- 9th January 2015, 12:43
Wow, yeah, that's some pretty ineffecient code - no offense.

* Try and never write the same snippet of code more than once, if more than a very simple command and it's needed more than a single time make it a subroutine. You have a VERY long piece of code copy/pasted twice (as far as I can see).
* Avoid using HIGH/LOW, set the TRIS registers to the correct value and write directly to the PORT register (or LAT register on 18F parts). Doing that single thing saves 540 words in your program.
* Instead of the IF/THEN thing for each bit just do C1 = LINE1[0+SVLA] etc.

Something like:


' Variables etc as before but make sure to set TRIS registers properly!

DRO=2 'time refresh set

'turn off display
L1 = 1
L2 = 1
L3 = 1
L4 = 1
L5 = 1
L6 = 1
L7 = 1
C1 = 0
C2 = 0
C3 = 0
C4 = 0
C5 = 0

cikleri:
FOR SVLA=0 TO 6 'scroll through the array
GOSUB ScanIt
PAUSE 5
NEXT

'ROTATE BACK
FOR SVLA=6 TO 0 STEP -1
GOSUB ScanIt
PAUSE 5
NEXT

GOTO CIKLERI

ScanIt:
FOR TRIALI = 0 TO 29 'time to show individual char
L1 = 0 'ENABLE LINE 1
C1 = LINE1[0+SVLA]
C2 = LINE1[1+SVLA]
C3 = line1[2+SVLA]
C4 = line1[3+SVLA]
C5 = line1[4+SVLA]
PAUSE DRO

L1 = 1
L2 = 0 'ENABLE LINE 2

C1 = LINE2[0+SVLA]
C2 = LINE2[1+SVLA]
C3 = line2[2+SVLA]
C4 = line2[3+SVLA]
C5 = line2[4+SVLA]
PAUSE DRO

L2 = 1
L3 = 0 'ENABLE LINE 3

C1 = LINE3[0+SVLA]
C2 = LINE3[1+SVLA]
C3 = line3[2+SVLA]
C4 = line3[3+SVLA]
C5 = line3[4+SVLA]
PAUSE DRO

L3 = 1
L4 = 0 'ENABLE LINE 4

C1 = LINE4[0+SVLA]
C2 = LINE4[1+SVLA]
C3 = line4[2+SVLA]
C4 = line4[3+SVLA]
C5 = line4[4+SVLA]
PAUSE DRO

L4 = 1
L5 = 0 'ENABLE LINE 5

C1 = LINE5[0+SVLA]
C2 = LINE5[1+SVLA]
C3 = line5[2+SVLA]
C4 = line5[3+SVLA]
C5 = line5[4+SVLA]
PAUSE DRO

L5 = 1
L6 = 0 'ENABLE LINE 6

C1 = LINE6[0+SVLA]
C2 = LINE6[1+SVLA]
C3 = line6[2+SVLA]
C4 = line6[3+SVLA]
C5 = line6[4+SVLA]
PAUSE DRO

L6 = 1
L7 = 0 'ENABLE LINE 7

C1 = LINE7[0+SVLA]
C2 = LINE7[1+SVLA]
C3 = line7[2+SVLA]
C4 = line7[3+SVLA]
C5 = line7[4+SVLA]
PAUSE DRO
L7 = 1
NEXT
RETURN


Went from 3161 to 775 words and that's just a first go.
I'm sure the rest can be handled with some array manipulation and indexing to reduce the size even further but I don't have time right now.

/Henrik.

CuriousOne
- 9th January 2015, 12:48
It is not twice, it just scrolls right to left and left to right. Thanks a lot, will have a look!

HenrikOlsson
- 9th January 2015, 13:18
Hi,
As far as I can see the FOR TRIALI=1 TO 30 / NEXT loop (which is the bulk of the code) is repeated twice. One time for right-to-left and one time for left-to-right.
/Henrik.

CuriousOne
- 9th January 2015, 13:35
Fitted your code, you're genius!

now even with double amount of bitmap data added, whole code is only 920 bytes!

HenrikOlsson
- 9th January 2015, 14:21
No I'm definitely not but thanks anyway :-)
Might be interesting to put the bitmap data in FLASH instead of RAM (well, you're already putting it in FLASH but then loading it to RAM....). It probably won't be as straight forward but should be doable, perhaps using READCODE. Then again, if it works and does what it needs to there no need to bother....

/Henrik.

CuriousOne
- 9th January 2015, 15:09
Yes I will have to read data from EEPROM, since this is just short demo and I need a lot of data, speaking in pixels, it will be 200*5*7, quite much for solely PIC to handle.

Here's the sample video how it works:

https://www.youtube.com/watch?v=36eRYMNKqVk&feature=youtu.be

But have no idea how to handle these parasitic lights, if I increase DRO variable, then these half lit segments go away, but then flicker is noticeable.

CuriousOne
- 9th January 2015, 15:48
Checked in details, these parasitic lit segments are on even with larger DRO values. Tried to disable internal pull-up resistors - no change. Even tried to interlace update, do a 1,3,5,7,2,4,6 row sequence - no difference.

CuriousOne
- 9th January 2015, 16:09
Solved, just added this to each line draw end routine:

c1=0
c2=0
c3=0
c4=0
c5=0