PDA

View Full Version : How to read from single LOOKUP table into different variables?



CuriousOne
- 10th October 2021, 16:50
I'm making my own "library" for ST7920 display, which allows to display 18x4 lines of custom charset, in dimensions of 16x2 LCD display.
Since there is no string variable support in PBP, I want to find a simple way to display different text labels with ease.
For this, I want to use LOOKUP statement, something like this:

LOOKUP A,["Hello!"],B

Where "Hello" will be a string with length of 18 characters (full width of display) and there will be 4 of such strings (one per line)
18*4=72 bytes, and as manual says, up to 255 bytes can be used, so this is OK. But there is another issue.
Due to nature of ST7920, display update is done via "words" - 2 byte sequences, so I have to read data with lookup into 2 standalone variables.
It would be great, if it was possible to do

LOOKUP A,["Hello!"],B,C

to get B and C loaded with appropriate values, but as I know, such statement is not supported.

This means, that I have either to have that "hello" lookup table in code twice, and read even chars from one and odd - from another OR
I have to introduce an intermediate array (which is again introduces memory limitation issues) and fill it with data and then send to display

Any ideas?

I don't want to use internal or external eeprom for storing text strings, because I want them to be editable right into code via keyboard, not via updating external firmware.

mpgmike
- 11th October 2021, 00:45
First thought is that you need a generic Buffer sized to the length you want to send. For example:


LCD_Buffer VAR BYTE[18]

I use the ARRAYWRITE command for what I think you're asking. Here is a piece of code that fills in blanks to my Buffer and loads them for a UART send:


Send_Vac: ;Send Current Vacuum Reading to Nextion
tVac = Vac ;Create a Temporary Variable We Can Modify
ARRAYWRITE NexBuf, ["vac.val="] ;Start Nextion Command Sequence, Occupies NexBuf[0] >> [7]
IF tVac > 100 THEN ;If 3 Digits
b0 = tVac / 100 ; Get the Xxx Value
NexBuf[8] = b0 + $30 ; Convert it to ASCii
tVac = tVac - (b0 * 100) ; Subtract the Xxx Value from tVac
IF tVac < 10 THEN ;If xXx = 0
NexBuf[9] = $30 ;If tVac < 10, it's Zero (ASCii)
ENDIF ;IF tVac < 10
ELSE ;tVac < 100
NexBuf[8] = $30 ;If tVac < 100, 1st Digit is Zero (ASCii)
ENDIF ;IF tVac > 100
IF tVac > 10 THEN ;If Now Double Digit
b0 = tVac / 10 ;Get the xXx Value
NexBuf[9] = b0 + $30 ;Convert it to ASCii
tVac = tVac - (b0 * 10) ;Subtract the xXx Value from tVac
ELSE ;tVac < 10
NexBuf[9] = $30 ;If tVac < 10, it's Zero (ASCii)
ENDIF ;IF tVac > 10
NexBuf[10] = tVac + $30 ;Convert xxX to ASCii & Write to Buffer
FOR b0 = 11 TO 13 ;Generate "End of Message" Sequence: $FF, $FF, $FF
NexBuf[b0] = $FF ;Load it to Buffer
NEXT b0 ;FOR b0 = 11 TO 13
NexBuf[14] = 0 ;Tells Us To Turn UART TX INT Off
RotX = 0 ;NexFlags.RotX -- Clear RotX Flag
GOTO Start_TX ;No RETURN Needed, Using GOTO Command

richard
- 11th October 2021, 01:17
why all the fiddling ?
why not ?

ARRAYWRITE NexBuf, ["vac.val=",dec3 tvac,255,255,255,0]
RotX = 0 ;NexFlags.RotX -- Clear RotX Flag
GOTO Start_TX ;No RETURN Needed, Using GOTO Command




eg



;----[16F886 Hardware Configuration]--------------------------------------------#CONFIG
cfg1 = _INTRC_OSC_NOCLKOUT ; INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN
cfg1&= _WDT_ON ; WDT enabled
cfg1&= _PWRTE_OFF ; PWRT disabled
cfg1&= _MCLRE_OFF ; RE3/MCLR pin function is digital input, MCLR internally tied to VDD
cfg1&= _CP_OFF ; Program memory code protection is disabled
cfg1&= _CPD_OFF ; Data memory code protection is disabled
cfg1&= _BOR_OFF ; BOR disabled
cfg1&= _IESO_ON ; Internal/External Switchover mode is enabled
cfg1&= _FCMEN_ON ; Fail-Safe Clock Monitor is enabled
cfg1&= _LVP_OFF ; RB3 pin has digital I/O, HV on MCLR must be used for programming
cfg1&= _DEBUG_OFF ; In-Circuit Debugger disabled, RB6/ICSPCLK and RB7/ICSPDAT are general purpose I/O pins
__CONFIG _CONFIG1, cfg1




cfg2 = _BOR40V ; Brown-out Reset set to 4.0V
cfg2&= _WRT_OFF ; Write protection off
__CONFIG _CONFIG2, cfg2




#ENDCONFIG




'chip configs
TRISA=000000 'SET A TO OUTPUT 1=input
TRISC=001101 'set half C for in/out
TRISB=011000 'set PortB to output
ANSELH=000000 ' ADC OFF B
ANSEL=0000000 'configure PortA as digital except first 2
ADCON1=000000 'adc justify
OSCCON=110101 'SET FREQUENCY TO 8MHZ
WPUB=000000 'turn off Pullups
CM1CON0=0 'DISABLE COMPARATORS
CM2CON0=0 'SAME HERE
'CCP1CON=000000 ' configure pwm
'PSTRCON=010110 'disable C pwm




DEFINE OSC 8
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50
'lcd config
pause 1000
' Set LCD Data port
DEFINE LCD_DREG PORTC
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 1
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 44
lcdout $fe, $1, "ready "
pause 1000


DPIN Var PORTA.2 ' I2C data pin
CPIN Var PORTA.1 ' I2C clock pin
B Var word
B0 Var byte
B2 Var byte
NexBuf Var byte[16]
tVac Var word


Send_Vac: ;Send Current Vacuum Reading to Nextion
tVac = 13 ;Create a Temporary Variable We Can Modify
ARRAYWRITE NexBuf, ["vac.val="] ;Start Nextion Command Sequence, Occupies NexBuf[0] >> [7]
IF tVac > 100 THEN ;If 3 Digits
b0 = tVac / 100 ; Get the Xxx Value
NexBuf[8] = b0 + $30 ; Convert it to ASCii
tVac = tVac - (b0 * 100) ; Subtract the Xxx Value from tVac
IF tVac < 10 THEN ;If xXx = 0
NexBuf[9] = $30 ;If tVac < 10, it's Zero (ASCii)
ENDIF ;IF tVac < 10
ELSE ;tVac < 100
NexBuf[8] = $30 ;If tVac < 100, 1st Digit is Zero (ASCii)
ENDIF ;IF tVac > 100
IF tVac > 10 THEN ;If Now Double Digit
b0 = tVac / 10 ;Get the xXx Value
NexBuf[9] = b0 + $30 ;Convert it to ASCii
tVac = tVac - (b0 * 10) ;Subtract the xXx Value from tVac
ELSE ;tVac < 10
NexBuf[9] = $30 ;If tVac < 10, it's Zero (ASCii)
ENDIF ;IF tVac > 10
NexBuf[10] = tVac + $30 ;Convert xxX to ASCii & Write to Buffer
FOR b0 = 11 TO 13 ;Generate "End of Message" Sequence: $FF, $FF, $FF
NexBuf[b0] = $FF ;Load it to Buffer
NEXT b0 ;FOR b0 = 11 TO 13
NexBuf[14] = 0 ;Tells Us To Turn UART TX INT Off
' RotX = 0 ;NexFlags.RotX -- Clear RotX Flag
lcdout $fe, $1, str NexBuf
tVac = 3
ARRAYWRITE NexBuf, ["vac.val=",dec3 tvac,255,255,255,0] ;Start Nextion Command Sequence, Occupies NexBuf[0] >> [7]
lcdout $fe, $c0, str NexBuf

richard
- 11th October 2021, 01:22
LOOKUP A,["Hello!"],B,C


in what way would B differ from C

surely if a=0 then b==c = "H"
surely if a=1 then b==c = "e"

makes zero sense

CuriousOne
- 11th October 2021, 05:20
I want to get two consecutive bytes from one "Hello!" string. How more clear I can say this in other way?

I'll try once again. I need output of this kind from Hello!
A=H
B=e
A=l
B=l
A=o
B=!

CuriousOne
- 11th October 2021, 05:23
First thought is that you need a generic Buffer sized to the length you want to send. For example:


Currently I'm doing it this way:



topline var byte [18]
topline[0]=88
topline[1]=64
topline[2]=192
topline[3]=0
topline[4]=255
topline[5]=200
topline[6]=0
topline[7]=88
topline[8]=104
topline[9]=40
topline[10]=64
topline[11]=24
topline[12]=0
topline[13]=255
topline[14]=152
topline[15]=72
topline[16]=40
topline[17]=32


But as I can see, with ARRAYWRITE it would be much simpler, thanks!

richard
- 11th October 2021, 05:59
I want to get two consecutive bytes from one "Hello!" string. How more clear I can say this in other way?


I'll try once again. I need output of this kind from Hello!
A=H
B=e
A=l
B=l
A=o
B=!


easy as


;----[16F886 Hardware Configuration]--------------------------------------------#CONFIG
cfg1 = _INTRC_OSC_NOCLKOUT ; INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN
cfg1&= _WDT_ON ; WDT enabled
cfg1&= _PWRTE_OFF ; PWRT disabled
cfg1&= _MCLRE_OFF ; RE3/MCLR pin function is digital input, MCLR internally tied to VDD
cfg1&= _CP_OFF ; Program memory code protection is disabled
cfg1&= _CPD_OFF ; Data memory code protection is disabled
cfg1&= _BOR_OFF ; BOR disabled
cfg1&= _IESO_ON ; Internal/External Switchover mode is enabled
cfg1&= _FCMEN_ON ; Fail-Safe Clock Monitor is enabled
cfg1&= _LVP_OFF ; RB3 pin has digital I/O, HV on MCLR must be used for programming
cfg1&= _DEBUG_OFF ; In-Circuit Debugger disabled, RB6/ICSPCLK and RB7/ICSPDAT are general purpose I/O pins
__CONFIG _CONFIG1, cfg1




cfg2 = _BOR40V ; Brown-out Reset set to 4.0V
cfg2&= _WRT_OFF ; Write protection off
__CONFIG _CONFIG2, cfg2




#ENDCONFIG




'chip configs
TRISA=%00000000 'SET A TO OUTPUT 1=input
TRISC=%00001101 'set half C for in/out
TRISB=%00011000 'set PortB to output
ANSELH=%00000000 ' ADC OFF B
ANSEL=%000000000 'configure PortA as digital except first 2
ADCON1=%10000000 'adc justify
OSCCON=%01110101 'SET FREQUENCY TO 8MHZ
WPUB=%00000000 'turn off Pullups
CM1CON0=0 'DISABLE COMPARATORS
CM2CON0=0 'SAME HERE
'CCP1CON=%01000000 ' configure pwm
'PSTRCON=%00010110 'disable C pwm




DEFINE OSC 8
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50
'lcd config
pause 1000
' Set LCD Data port
DEFINE LCD_DREG PORTC
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 1
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 44
lcdout $fe, $1, "ready "
pause 1000


DPIN Var PORTA.2 ' I2C data pin
CPIN Var PORTA.1 ' I2C clock pin
B Var word
B0 Var byte
B1 Var byte
lcdwbuf var word[10]
@lcdBuf = _lcdwbuf
lcdBuf Var byte ext






arraywrite lcdBuf ,["Hello World",0 ]

lcdout $fe, $1, str lcdBuf

b0 = lcdwbuf[0]
b1 = lcdwbuf[0] >> 8
lcdout $fe, $c0,b0," : ", b1
b0= lcdwbuf[3]
b1= lcdwbuf[3] >> 8
pause 1000
lcdout $fe, $c0,b0," : ", b1

CuriousOne
- 11th October 2021, 07:14
Currently I'm doing this in the following way:



FOR X=0 TO 17 step 2 'READ ARRAY INTO VARIABLE, ARRAY MEMBER CHAR=EEPROM OFFSET
Y=topline[x]
Z=topline[x+1] 'READ INTO VARIABLE AS TWINS
FOR I=0 TO 7 'HELPER LOOP FOR CHARACTER READING
READ Y+I,A 'READ EEPROM BYTES INTO VAR
READ Z+I,B
LCDOUT $FE,$80+i+c 'UPDATE Y POSITION
LCDOUT $FE,$80+x/2 'UPDATE X POSITION
if y=255 then a=0
if z=255 then b=0 'blanker for space display
LCDOUT a
LCDOUT b 'WRITE TO SCREEN
NEXT I
NEXT X


C=number of line*8 where text had to be displayed.

9091

CuriousOne
- 11th October 2021, 09:19
Oh and I'll ask here. Is it possible to do bitwise shift between array members?
I'm adding some smooth scroll options to that display, and vertical scrolling is easy, since 1 byte = 1 vertical line of pixels. But for horizontal scrolling, 1 byte = 8 horizontal pixels, so scrolling is not that smooth. I remember, I was doing this on ZX Spectrum In Assembler, but forgot how :)