Build a 32 char string and send it all to LCD

MearCat

Member
In my program (using 28X1), I am writing 8 numbers to an 16x2 LCD, but to make the numbers align correctly, I also test for the length of each string and send a space here or there to the LCD before writing the number value. I have tested the time it takes to do this and am using up to 24 SEROUT commands which is wasting a lot of processing time (up to 240ms to write to the entire 16x2 LCD.

I want to be able to create/build the ENTIRE string (32 characters long) so that I only have to use a single SEROUT command and send 32 characters in one hit.

Is this possible? If so how?

Regards,
Alan
 
Last edited:

hippy

Technical Support
Staff member
Poke then Peek would be the usual answer and you also have use of the scratchpad on the 28X1.

Create a 'buffer area' of required size for your number ( entire LCD even, or for each line ), pre-fill it with zeros or spaces, write what you wish to display there then churn it out in a fast loop.
 

MearCat

Member
Do I use a series of Words to hold the characters/numbers? If I use ther scratchpad w0 Word, can this hold characters instead of just numbers? And how do I add a Space character to the string so that it can displayed on the LCD onr OR MORE preceding spaces?
 
Last edited:

inglewoodpete

Senior Member
Hippy suggested you use Peek and Poke commands to create a buffer area. Have a look at these commands in the command manual (#2). They refer to RAM.

As hippy also suggested, clear a buffer area. This means filling (say) 32 bytes of consecutive RAM with space ($20) characters.

Then, write (ie poke) the required characters (as bytes) to the required locations. The makeup and location of each character can be calculated in a similar fashion to what you would be doing at the moment.

Once the message has been composed in RAM, use a looping routine to transmit the message to the LCD quickly. You won't be able to use a single SerOut per se, but it will be as quick and efficient as possible.

Assuming that you use RAM locations $50 to $6F as your buffer:

Code:
For b7 = 80 to 111            'RAM locations pointer: $50 to 6F
     Peek b7, b6              'Fetch a byte
     SerTxD 1, T2400_4, b6    'Send the character to the LCD (on pin 1)
Next b7
 

MearCat

Member
Scratchpad?

Is is possible to write to a LCD directly from the scratchpad or can we only use the General Purpose variables?
 

Technical

Technical Support
Staff member
Yes, use @ptr or @ptrinc as the variable

e.g.

ptr =0
serout 1,n2400,(@ptrinc,@ptrinc... etc (32 times!)

This will output scratchpad addresses 0-31
 

MearCat

Member
Yes, use @ptr or @ptrinc as the variable
e.g.
ptr =0
serout 1,n2400,(@ptrinc,@ptrinc... etc (32 times!)

This will output scratchpad addresses 0-31
Awsome!! Thanks Tech. That solves my issue brilliantly as I can compile all the characters into 32 bytes/characters of scratchpad memory and then only use a SINGLE Serout command to write them all to the LCD.

:D
 

Technical

Technical Support
Staff member
Remember that a 16x2 LCD has two lots of 16 characters at addresses 128 and 192 - not 32 characters continuous from 128. So you will probably still need two serout commands (or merge them into one very long line!).

serout 1,n2400,(254,128,@ptrinc,@ptrinc... etc (16 times!)
serout 1,n2400,(254,192,@ptrinc,@ptrinc... etc (16 times!)
 

tarzan

Senior Member
28X1 as i2cslave parallel driven LCD (4 bit mode)

If you are using a 4x20 LCD you can dump 80 bytes at once from location 128 on wards. You’ll need to account for swapping lines 2&3 before sending data to LCD. (Tested on AXE033)

I’m currently using a 28X1 as i2cslave parallel driven LCD (4 bit mode) which employs this method.

Two methods of checking on the status of Picaxe i2cslave LCD are:

Dedicated output line high while busy refreshing LCD screen low when done. Master can poll input or use interrupt.

Setting unused flag0 = 1 into @ptr at scratchpad location 0 (ptr = 0) while busy refreshing LCD screen, flag0 = 0 when done. Master can read by using hi2cin 0, (bit0).

Code:
[FONT=Times New Roman][FONT=Times New Roman][SIZE=3]#com 1[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]#picaxe 28X1[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]setfreq em20[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]HI2CSETUP I2CSLAVE, %10100000[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]eeprom  0,("RESET")[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]init_reset:[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]low portc 0  'busy signal - handshake[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]ptr = 0[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]@ptr = 0[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]flag0 = 0  'busy signal - handshake[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]@ptr = flag0[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]flag6 = 0[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]pause 200[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]let pins = 0  'Clear all output lines[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]let pins = 32  'Set to 4-bit operation.[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]pulsout 3,1  'Send data.[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]pulsout 3,1  'Send data again.[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]let pins = 128  'Set to two line operation[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]pulsout 3,1  'Send data.[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]let @ptr = 14  'Screen on, cursor on instruction[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]gosub wrins  'Write instruction to LCD[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]let @ptr = 1  'set b1 to 'clear display’ instruction[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]gosub wrins  'send instruction to LCD [/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]pause 160[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]for ptr = 0 to 4 'setup for...next loop ("RESET" - positions 0 to 4)[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]read ptr, @ptr 'read letter from EEPROM into variable @ptr[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]gosub wrchr  'send character to LCD[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]next ptr   'next loop[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]let @ptr = 12  'Hide cursor instruction [/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]gosub wrins  'Write instruction to LCD[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]ptr = 0[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]flag6 = 0[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]setintflags %01000000,%01000000[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]high portc 0 'ready signal - handshake[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]main:[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]pause 4000   'Just waitting for something to arrive[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]goto main[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]interrupt:[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]setintflags off[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]low portc 0  'busy signal - handshake [/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]flag0 = 0  'busy signal - handshake[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]@ptr = flag0[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]pause 23   'SHOULD NOT NEED THIS PAUSE? Hide byte 14 issue. (Delete this line for 28X1 VA.3 or better)[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]get 1,@ptr[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]gosub wrins  'Write instruction to LCD[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]if @ptr <= 28 then done[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]for ptr = 2 to hi2clast[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]get ptr,@ptr[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]if @ptr >= 128 and @ptr <= 231 then :gosub wrins endif[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]gosub wrchr [/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]next ptr[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]done:[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]ptr = 0[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]hi2cflag = 0  'reset flag[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]setintflags %01000000,%01000000[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]high portc 0 'ready signal - handshake[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]flag0 = 1  'ready signal - handshake[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]@ptr = flag0[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]return[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]wrchr:[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]let pins = @ptr & 240'Mask the high nibble of b1 into b2.[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]high 2   ' Make sure RS is high[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]pulsout 3,1  ' Pulse the enable pin to send data.[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]let b2= @ptr * 16 ' Put low nibble of b1 into b2.[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]let pins = b2 & 240'Mask the high nibble of b2[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]high 2   ' Make sure RS is high[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]pulsout 3,1  ' Pulse enable pin to send data.[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]return[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]wrins:[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]let pins = @ptr & 240'Mask the high nibble of b1 into b2.[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]pulsout 3,1  ' Pulse the enable pin to send data.[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]let b2= @ptr * 16 ' Put low nibble of b1 into b2.[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]let pins = b2 & 240'Mask the high nibble of b2[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]pulsout 3,1  ' Pulse enable pin to send data.[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]high 2   ' Back to character mode[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]return[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]#rem1  [/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]Clear display and move to the start of the first line[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]2  Move the cursor and display "window" to the start of the first line[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]4  Set "right to left printing" mode[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]5  Set "scroll printing to the left" mode[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]6  Set "left to right printing" mode[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]7  Set "scroll printing to the right" mode[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]10 Turn visual LCD screen off[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]12  Hide cursor[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]13  Make cursor flash[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]14  Turn visual LCD screen (and cursor) on[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]16  Move cursor left one position[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]20  Move cursor right one position[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]24  Scroll display "window" left one position[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]28  Scroll display "window" right one position[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]128  Move cursor to the start of the first line[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]192  Move cursor to the start of the second line[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]#endrem[/SIZE][/FONT]
[/FONT]
LCD connections:

Same as in picaxe_manual3; which is still incorrectly labeled. Should be DB7 pin14,DB6 pin13,DB5 pin12,DB4 pin11.
 

Attachments

Last edited:

tarzan

Senior Member
Master code: Send contents of scratchpad, full page or you can still address each location of LCD.

Code:
[FONT=Times New Roman][FONT=Times New Roman][SIZE=3]#com 1[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]#picaxe 28X1[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]#terminal off[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]setfreq em16[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]HI2CSETUP I2CMASTER, %10100000, 9, i2cword 'replaced i2cfast_16 with 9[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]'gosub check_if_display_is_ready[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]gosub check_display_status[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]HI2COUT 1,(1)'clear display[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]scratchpad_out_page_directed: 'each line sent to proper loccation[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]'gosub check_if_display_is_ready[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]gosub check_display_status[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]ptr = 0 [/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]HI2COUT 1,(128,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,191,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,147,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,211,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptr)[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]return[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]scratchpad_out_full_page:[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]gosub check_if_display_is_ready [/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]'gosub check_display_status [/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]ptr = 0[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]HI2COUT 1,(128,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptrinc,@ptr) [/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]return[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]check_display_status:[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]ptr = 127[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]hi2cin 0,(@ptr)[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]if @ptr = 0 then check_display_status[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]return[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]check_if_display_is_ready:[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]if pin1 = 0 then check_if_display_is_ready[/SIZE][/FONT]
[FONT=Times New Roman][SIZE=3]return[/SIZE][/FONT]
[/FONT]
 

MearCat

Member
The hash character needs to precede the @ptrinc keyword so that it write to the LCD as ascii :
serout 1,n2400,(#@ptrinc,#@ptrinc... etc

However, I am compiling the string as a combination of spaces and numbers. If the number I output to the LCD is 2, then the string to send to the LCD will be " 2". If the number I output to the LCD is 20, then the string will be "20" If use serout 1,n2400,(#@ptrinc,#@ptrinc) when the number is 20, the LCD displays "20" but when the number is 2, serout 1,n2400,(#@ptrinc,#@ptrinc) the LCD displays "322". I assume this is - 32 as the BCD value of a space character, followed the actual number of "2".

How can I output an entire string properly when the string can be any combination of spaces and numbers?
 
Last edited:

Technical

Technical Support
Staff member
You are going around this the wrong way. Do not use #, simply save the number in the scratchpad as the ascii character to start with.

so instead of, for instance, saving the number 2, save the as number (2 + "0") instead. Then the scratchpad memory will directly contain ascii characters which can be output directly without #

ie instead of

let b1 = 2
put x,b1

use
let b1 = 2 + "0" ' convert to ascii
put x,b1
 

inglewoodpete

Senior Member
It will create an ASCII character - but not what you want. Technical was referring to single digit numbers.

The character "0" (zero) has an ASCII value of $30 etc etc up to "9", which has an ASCII value of $39. So values 0-9 can be converted to the equivalent ASCII character by adding the value of the ASCII character for "0", which is $30.

Eg If b1 = $02, then the ASCII value for it will be b1 = b1 + "0" = "2"

Hope that makes sense ;o) It's easy when you understand it.
 

inglewoodpete

Senior Member
The BinToAscii command splits a byte or word variable into 3 or 5 byte registers as ASCII. These characters will need to be written to the scratchpad.

Alternatively, you could write a looping routine that extracts, converts and stores each digit as ASCII in a byte or word variable. I think the subject has been discussed in the forum in the last year or two.
 
Top