View Full Version : Joining 5 bit variables and splitting them into 8 bit ones later?
CuriousOne
- 13th December 2020, 06:40
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?
mpgmike
- 14th December 2020, 19:15
Don't quite have the thought fully formed, but I'm thinking along the lines of:
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.
CuriousOne
- 14th December 2020, 20:44
What if I create 32 bit array, write bits in sequence and then read it in appropriate chunks?
mpgmike
- 15th December 2020, 05:55
Something like this?
' 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
... ... ... ... ... ...
CuriousOne
- 15th December 2020, 07:27
Yes, but have no idea if can use another variable instead of 31 and other digits.
Like displayvar.X=Y
HenrikOlsson
- 15th December 2020, 16:51
I suspect this is what you want:
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 :-)
http://www.picbasic.co.uk/forum/showthread.php?t=544
CuriousOne
- 15th December 2020, 19:39
So it should look like this, right? (have no access to PBP at this moment).
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
CuriousOne
- 15th December 2020, 21:40
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.
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
READ DBIT+DOFF+Z,BT 'read bit from eeprom
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
CuriousOne
- 3rd January 2021, 15:36
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
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?
CuriousOne
- 3rd January 2021, 19:37
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?
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
LOW LOAD
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]
HIGH LOAD
NEXT
END
8998
8999
richard
- 4th January 2021, 01:56
you are dealing with a matrix that fills like this
9001
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
9000
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
CuriousOne
- 4th January 2021, 06:51
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...
char1=char1 | char2>>5
char2=char2 <<3 | char3>>2
char2=char2 | char4>>7
char3=char4<<1
char4=0
CuriousOne
- 4th January 2021, 06:53
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.
richard
- 4th January 2021, 07:07
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
richard
- 4th January 2021, 07:46
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
CuriousOne
- 4th January 2021, 10:44
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.
richard
- 4th January 2021, 10:57
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
richard
- 4th January 2021, 11:16
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
https://youtu.be/DanYYBoVOBU
CuriousOne
- 4th January 2021, 12:17
Well, I'm designing fonts for last 30 years, so no surprise mine is better :D
proof of concept of what?
Any code was posted?
richard
- 4th January 2021, 12:42
basically this , modded slightly for the 4x8 font
http://www.picbasic.co.uk/forum/showthread.php?t=24171
CuriousOne
- 4th January 2021, 14:04
And this is proof of my code working :D
So if I understood correctly, there is no HSHIFTOUT statement, like HSEROUT ?
9002
CuriousOne
- 5th January 2021, 17:12
But I still have an issue - why reading from a bit array from arbitrary position (not byte justified) returns garbage?
richard
- 6th January 2021, 06:13
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/minimal-reproducible-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
; 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
CuriousOne
- 6th January 2021, 21:08
Will take a look tomorrow...
Meanwhile, added decimal point, C and F sign support...
Powered by vBulletin® Version 4.1.7 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.