Joining 5 bit variables and splitting them into 8 bit ones later?

# Thread: Joining 5 bit variables and splitting them into 8 bit ones later?

1. ## Joining 5 bit variables and splitting them into 8 bit ones later?

Hello.
I'm using a MAX7219 dot matrix display, 8x8 pixels, 4 daisy chained.
I want to display some numbers on it. I can use 7x7 pixel font, so 4 digits will fit.
But I want to use 6x7 pixel font, so can fit 5 digits on screen.
Each letter graphics are stored in 6 bit codes, like this, for number 8

001110
011011
011011
001110
011011
011011
001110

But data to MAX7219 is being sent into 8 bit increments. So if I send it directly, there will be big gaps and each bit displayed only on single 8x8 matrix. So I need to add these 6 bits to each other, and then split them again into 8 bits. Like this:

001110 001110 001110 001110 should become
00111000 11100011 10001110
Any ideas?

2. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

Don't quite have the thought fully formed, but I'm thinking along the lines of:
Code:
```FullDigit VAR LONG
FullDigit = ((Byte1 << 23) + (Byte2 << 17) + (Byte3 << 11)...```
This might compact the bits(?)

You need 42 bits, but a LONG only has 32. There's an extra line that would have to be dealt with independently. Again, this isn't a "Solution", just food for thought.

3. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

What if I create 32 bit array, write bits in sequence and then read it in appropriate chunks?

4. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

Something like this?
Code:
```' 001110 001110 001110 001110
FullDisp VAR LONG
FullDisp.31 = 0
FullDisp.30 = 0
FullDisp.29 = 1
FullDisp.28 = 1
FullDisp.27 = 1
FullDisp.26 = 0
FullDisp.25 = 0
... ... ... ... ... ...```

5. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

Yes, but have no idea if can use another variable instead of 31 and other digits.
Like displayvar.X=Y

6. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

I suspect this is what you want:
Code:
`displayvar.0[X]=Y`
But I also suspect we've covered this before so instead of me trying to repeat what's already been covered in detail I just leave it all to Melanie :-)

7. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

So it should look like this, right? (have no access to PBP at this moment).
Code:
```SCREEN32 VAR BIT[32] 'MAIN VARIABLE
LINE1=%10101 'VARIABLE WITH BIT DATA
FOR X=0 TO 4 'READ BITS
SCREEN32[X+1]=LINE1.0(X) 'WRITE INTO ARRAY
NEXT```

8. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

So here it is, almost finished (not tested in PBP yet, written in notepad).
Digit data are stored as 4 bit width sequences, each char compromising of 4x8 pixels (width & height). They are stored by pairs in eeprom (1st address holds bitmaps for 1 & 2, 2nd address - for 3 & 4 and so on).
This routine should display value of 4 digit CNTR variable on screen. It does that by reading 4 bit graphic data from eeprom, adding 1 space between pixels and assembling into 32 bit array, which later should be cut into 4 bytes and sent to MAX7219. For simplicity, code is shown for sending only 1 line. However, I'm stuck, how to read values from 32 bit array and convert them into bytes.
Code:
```LINE VAR BIT[32] 'line of MAX7219 buffer
DBIT var byte    'digit bit eeprom address
DOFF var byte    'digit offset 0 for first, 4 for next
DSHF var byte    'Shift value for next digit data
CNTR var word    'Input variable
Y var byte    'Temporary digit variable
X var byte    'digit scan variable
Z var byte    'digit row variable
BT var bit    'bit variable for font hold

' decoder routine
DECODER:
DSHF=0    'reset char shift variable
for x=0 to 3 'read all 4 digits
Y=CNTR DIG X 'EXTRACT VARIABLE DIGIT
IF Y=1 THEN DBIT=0: DOFF=0 'set the font offset
IF Y=2 THEN DBIT=0: DOFF=4
IF Y=3 THEN DBIT=8: DOFF=0
IF Y=4 THEN DBIT=8: DOFF=4
IF Y=5 THEN DBIT=16: DOFF=0
IF Y=6 THEN DBIT=16: DOFF=4
IF Y=7 THEN DBIT=24: DOFF=0
IF Y=8 THEN DBIT=24: DOFF=4
IF Y=9 THEN DBIT=32: DOFF=0
IF Y=0 THEN DBIT=32: DOFF=4

for Z=0 to 4 'read font data and write into rows
LINE[Z+DSHF]=BT 'write into array
next
DSHF=DSHF+5    'increment char shift variable

'now here should extract bits from array and convert into bytes
'to send to MAX7219, but how?
next```
Last edited by CuriousOne; - 15th December 2020 at 22:44.

9. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

I decided to return to this code, and have some advancement, but having issues into reading bits from array into an variable.
I have a SCREEN[32] bit array, which should be read into 4 consecutive variables - SEGA, SEGB, SEGC, SEGD.
I know how to access individual bits within variable, but complete byte?

If I understand correctly, the code should look like this
Code:
```FOR X=0 to 7
SEGA.0(X)=SCREEN[X]
SEGB.0(8+X)=SCREEN[X]
SEGC.0(16+X)=SCREEN[16+X]
SEGD.0(24+X)=SCREEN[24+X]
NEXT```
Is this correct?

10. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

Houston, we're having a problem!

Below is the code which works, but it works only if bits in array are aligned to bytes. If I want to shift them to make them less spaced (characters used have 4 pixel width, +1 pixel for spacing), image becomes garbled and shifted in wrong direction, as shown on attached pictures. What I'm doing wrong?

Code:
```DATA \$60,\$90,\$90,\$90,\$90,\$90,\$90,\$60 '0  'digits, left justified 4 bits used in each 8 bits
DATA \$20,\$60,\$A0,\$20,\$20,\$20,\$20,\$F0 '1
DATA \$60,\$90,\$90,\$10,\$60,\$80,\$80,\$F0 '2
DATA \$60,\$90,\$10,\$60,\$10,\$90,\$90,\$60 '3
DATA \$90,\$90,\$90,\$70,\$10,\$10,\$10,\$10 '4
DATA \$F0,\$80,\$80,\$E0,\$10,\$90,\$90,\$60 '5
DATA \$60,\$90,\$80,\$E0,\$90,\$90,\$90,\$60 '6
DATA \$F0,\$10,\$10,\$20,\$20,\$40,\$40,\$40 '7
DATA \$60,\$90,\$90,\$60,\$90,\$90,\$90,\$60 '8
DATA \$60,\$90,\$90,\$70,\$10,\$90,\$90,\$60 '9

INVAR=1234
FOR I=0 TO 7 'Read digit data from apropriate positions in EEPROM into own CHAR variables

READ 6+I+8*INVAR DIG 3, CHAR1
READ 6+I+8*INVAR DIG 2, CHAR2
READ 6+I+8*INVAR DIG 1, CHAR3
READ 6+I+8*INVAR DIG 0, CHAR4

FOR Y=0 TO 7 'write CHAR DATA INTO ARRAY WITH OFFSET
SCREEN32[Y]=CHAR1.0(Y)
SCREEN32[Y+8]=CHAR2.0(Y) 'OFSETS ARE SET HERE
SCREEN32[Y+16]=CHAR3.0(Y)
SCREEN32[Y+24]=CHAR4.0(Y)
NEXT

'read array data into 8 bit variables

FOR C=0 to 7
SEGA.0(C)=SCREEN32[C]
SEGB.0(C)=SCREEN32[8+C]
SEGC.0(C)=SCREEN32[16+C]
SEGD.0(C)=SCREEN32[24+C]
NEXT

'WRITE ARRAY DATA INTO DISPLAY AND GO TO NEXT LINE
shiftout datapin,clockpin,1,[1+I, SEGA]
shiftout datapin,clockpin,1,[1+I, SEGB]
shiftout datapin,clockpin,1,[1+I, SEGC]
shiftout datapin,clockpin,1,[1+I, SEGD]

NEXT
END```

11. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

you are dealing with a matrix that fills like this

its not a particularly easy format to leverage font images that traverse cells , and you cannot read back the data from the matrix
to make life easy i would make a memory array [frame buffer] mapped to the matrix like this

it's then quite straight forward to overlay a font chr into any location
and then create a simple routine to write the frame buffer to the display
in the bit order the matrix demands
Last edited by richard; - 4th January 2021 at 03:06.

12. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

Well, I already have buffer, but 32x1 pixels in size, because the data is sent to display line by line.
But the problem is different, I can't understand why this works only per 8 bit: SCREEN32[Y+8]=CHAR2.0(Y) - if I enter any other number instead of 8, which is not multiple of 8, say 5 or 17, everything becomes garbled, while it should not. So, maybe I'm writing in array incorrectly?

I was able to solve this problem by replacing array with string of Boolean logic operations, but I'd like to keep array, because later I want to display more letters, with variable width...
Code:
```char1=char1 | char2>>5
char2=char2 <<3 | char3>>2
char2=char2 | char4>>7
char3=char4<<1
char4=0```

13. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

Oh, and by the way, is there any possibility to increase SPI speed? I'm running 16F886 @ 8mhz, and update rate is clearly not good - forget about scrolling letters and other stuff like that.

14. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

Oh, and by the way, is there any possibility to increase SPI speed? I'm running 16F886 @ 8mhz, and update rate is clearly not good - forget about scrolling letters and other stuff like that.
yes don't use shiftout, on a chip that has a mssp module it's an order of magnitude or two slower than spi
its like having a dog and barking yourself

Well, I already have buffer, but 32x1 pixels in size, because the data is sent to display line by line.
yet characters persist over 8 lines and you are ignoring that present data, furthermore there is no way to recover that data from the chip
you figure it out

15. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

after some thought ,

Well, I already have buffer, but 32x1 pixels in size, because the data is sent to display line by line.
But the problem is different, I can't understand why this works only per 8 bit: SCREEN32[Y+8]=CHAR2.0(Y) - if I enter any other number instead of 8, which is not multiple of 8, say 5 or 17, everything becomes garbled, while it should not. So, maybe I'm writing in array incorrectly?
i assume SCREEN32 is your 32 bit array ,
SCREEN32[Y+8] is then a complete nonsense as the only valid locations are 0 to 3

similarly wtf is char2 ? if its a byte then
CHAR2.0(Y) a valid y value can only be 0 to 7

then we have this, wtf is char1 a byte a word an array ? , a pointless snippet

char1=char1 | char2>>5
char2=char2 <<3 | char3>>2
char2=char2 | char4>>7
char3=char4<<1char4=0

16. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

Yes, SCREEN32 is 32 bit array.
And why locations only can be from 0 to 3 ?
There are 32 bits, or what you want to say, that is not possible to write into specific bit of bit array?

I'm reading a bit from variable and writing it into bit of an array, to later read bits as needed.

17. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

thats what happens with snippets ,there is no context

SCREEN32 var bit[32] would have made it clear

I'm reading a bit from variable and writing it into bit of an array, to later read bits as needed.
good luck

18. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

proof of concept
btw i like your font it looks better than my 6x5 one

sorry for shaky vid , was trying to use mouse while steering phone , failed both accounts

19. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

Well, I'm designing fonts for last 30 years, so no surprise mine is better
proof of concept of what?
Any code was posted?

20. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

basically this , modded slightly for the 4x8 font

21. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

And this is proof of my code working
So if I understood correctly, there is no HSHIFTOUT statement, like HSEROUT ?

22. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

But I still have an issue - why reading from a bit array from arbitrary position (not byte justified) returns garbage?

23. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

why reading from a bit array from arbitrary position (not byte justified) returns garbage?
a minimal, complete and verifiable example MCVE
https://stackoverflow.com/help/minim...ucible-example

here is one that shows no problem at all pbp3, examination of lst file confirms reservation of the 4 bytes required for the bit array
if there was ever any doubt
Code:
```; pbp3 16f1825
define OSC 32
#CONFIG
__config        _CONFIG1,    _FOSC_INTOSC & _CP_OFF & _WDTE_OFF &  _PWRTE_ON  &  _MCLRE_ON  & _CLKOUTEN_OFF
__config      _CONFIG2, _PLLEN_ON & _LVP_OFF
#ENDCONFIG

DEFINE DEBUG_REG PORTA
DEFINE DEBUG_BIT 0
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 0

OSCCON=\$70
ANSELA=0
ANSELC=0

barray var bit[32]
bbyte var byte ext
another var word
cnt var byte
tst var bit
more var byte
@bbyte = PBA01
clear

bbyte[0]=5
bbyte[1]=\$55

lata.0=1
pause 2000
Debug "Start",13 ,10
for cnt=31 to 0      step -1
Debug #barray[cnt]
next
Debug " array by bit",13 ,10
for cnt =3  to 0      step -1
Debug bin8 bbyte[cnt]
next

barray[11] =1
Debug " array by byte in bin",13,10,"set bit 11",13 ,10
for cnt=31 to 0      step -1
Debug #barray[cnt]
next
Debug 13 ,10
for cnt =3  to 0      step -1
Debug bin8 bbyte[cnt]
next

bbyte[3] =255
Debug 13 ,10,"set byte 3",13 ,10
for cnt=31 to 0      step -1
Debug #barray[cnt]
next
Debug 13 ,10
for cnt =3  to 0      step -1
Debug bin8 bbyte[cnt]
next

barray[11] =0
Debug 13 ,10,"clr bit 11",13 ,10
for cnt=31 to 0      step -1
Debug #barray[cnt]
next
Debug 13 ,10
for cnt =3  to 0      step -1
Debug bin8 bbyte[cnt]
next

bbyte[3] =0
Debug 13 ,10,"clr byte 3",13 ,10
for cnt=31 to 0      step -1
Debug #barray[cnt]
next
Debug 13 ,10
for cnt =3  to 0      step -1
Debug bin8 bbyte[cnt]
next```
printout

Start
00000000000000000101010100000101 array by bit
00000000000000000101010100000101 array by byte in bin
set bit 11
00000000000000000101110100000101
00000000000000000101110100000101
set byte 3
11111111000000000101110100000101
11111111000000000101110100000101
clr bit 11
11111111000000000101010100000101
11111111000000000101010100000101
clr byte 3
00000000000000000101010100000101
00000000000000000101010100000101
Last edited by richard; - 6th January 2021 at 07:16.

24. ## Re: Joining 5 bit variables and splitting them into 8 bit ones later?

Will take a look tomorrow...
Meanwhile, added decimal point, C and F sign support...

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts