Adding A Nextion LCD Module
The Nextion NX3224K024 is a touch screen 320x240 color LCD module, with an onboard microcontroller. Through a simple serial interface, you can send drawing commands to the device, or receive information back from it. (Thanks to Shane Lowry for providing the NX3224K024 used in this how-to guide.)
The documentation for the LCD can be found here: nextion.tech/instruction-set/
There's better (third party) documentation here wiki.iteadstudio.com/Nextion_Instruction_Set, but it is no longer updated.
The documentation for the LCD can be found here: nextion.tech/instruction-set/
There's better (third party) documentation here wiki.iteadstudio.com/Nextion_Instruction_Set, but it is no longer updated.
The LCD requires power (5V) and ground. Connect the red wire (5V) on the LCD to the Scamp's VIN, and connect GND (black wire) to GND on the Scamp. Communication is via UART1 on a Scamp3, with <Tx1 on the Scamp3 connected to RX on the LCD (yellow wire). Similarly, >Rx1 on the Scamp3 goes to the LCD's TX (blue wire).
Note that the microcontroller on the LCD is particularly susceptible to noise on its serial interface, and its onboard firmware does not recover well from errors. So keep the wires between the LCD and your Scamp as short as possible.
|
Getting started
Out of the box, the LCD runs some demo software to show off its capabilities. While the demo software is loaded on the LCD, you can't talk to it! It ignores all commands. So you need to use the Nextion Editor software (available for free on their website) to create an appropriate configuration (TFT) file to replace the demo code. The Nextion editor is unfortunately Windows-only. A blank TFT file is provided for your convenience on the right, if you don't have the ability to run the Nextion software. This TFT gives you a blank drawing slate, and includes three embedded fonts (font ID 0..2).
|
|
Put your TFT file on a micro-SD card (making sure that it is the only TFT file on the card), insert the card into the LCD's SD slot, and power-cycle your LCD. The LCD will load in the new TFT and save it to its onboard flash. Remove the SD card, and once again power cycle the LCD. The LCD is now ready to use.
Get Talking
The LCD uses a simple serial interface to communicate with the host embedded system. By default, the LCD powers up with a baud rate rate of 9600 bps. The following word sets the Scamp's baud rate to 9600 bps.
: setbaud ( -- ) \ set the baud rate to 9600 bps for LCD
9600. baud u1baud !
;
Always make setbaud is the first word you run at startup, prior to talking to the LCD. You only need to run it once per session.
Now, since the LCD is connected to UART1, you can just use the words tx1 to send chars/bytes to the LCD, and rx1 to receive chars/bytes from the LCD.
But we can get a little fancier than that. We can use Forth to redirect comms from the console to UART1, so that all the standard character I/O words are available. At the basis of all character output is the word emit. It is referenced by Forth using the vector 'emit. By mapping the word for tx1 (UART1 transmit) to the vector for emit, all output is redirected to the UART. Similarly, by mapping rx1 to the vector for key, input comes from UART1. This word definition maps character I/O to UART1.
: lcd \ redirect output to UART1 for LCD
['] tx1 \ lookup the address of the word tx1
'emit ! \ store it to the vector for emit
['] rx1 \ lookup the address of the word rx1
'key ! \ store it to the vector for key
['] rx1? \ lookup the address of the word rx1?
'key? ! \ store it to the vector for key?
;
Similarly, this word maps character I/O back to the console. Important: lcd and console should always be used in pairs. Using lcd by itself will transfer I/O to the LCD, but you won't be able to talk to your Scamp (since it will be listing on UART1 and not the console).
: console \ redirect output to console
['] txu \ lookup the address of the word txu
'emit ! \ store it to the vector for emit
['] rxu \ lookup the address of the word rxu
'key ! \ store it to the vector for key
['] rxu? \ lookup the address of the word rxu?
'key? ! \ store it to the vector for key?
;
|
Traps for young players: make sure that the ' mark in the code above is not a smart quote.
' works, but ’ does not, as they are represented by different character codes. |
|
Finally, each command to the LCD must be terminated with the transmission of three bytes of $ff. (See LCD documentation.) The following word does that.
: eoc \ terminate command to LCD
$ff emit $ff emit $ff emit
;
The LCD seems to get spurious chars on powerup, and these can mess with the first command you send. It's useful to flush the LCD's command buffer after powerup, to remove any of this junk.
: flush
lcd eoc console
;
The LCD will respond to the junk by sending error codes back to the Scamp. Therefore it's useful to empty the Scamp's UART1 input buffer after flushing the LCD.
: emptybuf
rx1? for
rx1 drop
next
;
So at startup, the following is good practice with the LCD:
setbaud flush emptybuf
You should be ready to go.
Note, the error code from the LCD for a misunderstood command is 26 255 255 255. If you get an unexpected 26 response from the LCD, then the LCD had an error processing your command. Use emptybuf to clear your input buffer.
Note, the error code from the LCD for a misunderstood command is 26 255 255 255. If you get an unexpected 26 response from the LCD, then the LCD had an error processing your command. Use emptybuf to clear your input buffer.
Faster Baud Rate
Now that we have lcd, eoc and console defined, we can send commands to our LCD. The first useful thing we can do is increase the baud rate to allow for faster comms. Note that you need to run setbaud first to establish comms with the LCD.
The following word definition will increase the baud rate for the LCD and the Scamp to 31250 bps. Note that we send the command to increase the LCD's baud rate, and then change the Scamp baud rate to suit. The delay before changing the Scamp's baud rate is important, as it allows the transmission to the LCD to complete before the baud rate is switched.
The following word definition will increase the baud rate for the LCD and the Scamp to 31250 bps. Note that we send the command to increase the LCD's baud rate, and then change the Scamp baud rate to suit. The delay before changing the Scamp's baud rate is important, as it allows the transmission to the LCD to complete before the baud rate is switched.
: fastbaud \ set the baud rate to 31250 bps for LCD
lcd
." baud=31250" \ and let's crank it up
eoc console
500 ms \ let previous transmission complete
31250. baud u1baud !
;
Note that at a faster baud rate, the LCD is more prone to comms errors. So your at your own discretion.
Clearing the LCD Screen
This word takes a color value from the stack, clears the LCD screen, and sets the background color. You have a 16-bit color palette to play with.
: lcdcls ( color -- )
lcd
." cls "
<# s>d #s #> type
eoc console
;
To clear the screen with a black background, 0 lcdcls. To clear the screen with a white background, $ffff lcdcls.
Backlight
This word takes a decimal value (0 .. 100) from the stack and sets the LCD's backlight brightness:
: backlight ( percent -- )
lcd
." dim="
<# s>d #s #> type
eoc console
;
For example, to set the backlight to 75%, type #75 backlight.
Drawing Circles
: circle ( color radius x y -- )
lcd
." cir "
swap
<# s>d #s #> \ x
type
<# s>d #s #44 hold #> \ y
type
<# s>d #s #44 hold #> \ radius
type
<# s>d #s #44 hold #> \ color
type
eoc console
;
Example: 5665 20 100 100 circle draws a green circle of radius 20 at screen coordinates 100,100.
: filledcircle ( color radius x y -- )
lcd
." cirs "
swap
<# s>d #s #> \ x
type
<# s>d #s #44 hold #> \ y
type
<# s>d #s #44 hold #> \ radius
type
<# s>d #s #44 hold #> \ color
type
eoc console
;
Example: 600 50 200 200 filledcircle, draws a blue circle (color 600) of radius 50 at 200,200.
Drawing Rectangles
: area ( color width height x y -- )
lcd
." fill "
swap
<# s>d #s #> \ x
type
<# s>d #s #44 hold #> \ y
type
swap
<# s>d #s #44 hold #> \ width
type
<# s>d #s #44 hold #> \ height
type
<# s>d #s #44 hold #> \ color
type
eoc console
;
Example: random 40 70 10 30 area draws an area of size 40x70 at screen coordinates 10,30, with a random color. (Note that the internal LCD command is fill, but as this is a reserved word in Forth, the command has been renamed.)
: rectangle ( color x2 y2 x1 y1 -- )
\ x2 and y2 must be larger than x1 and y1
lcd
." draw "
swap
<# s>d #s #> \ x2
type
<# s>d #s #44 hold #> \ y2
type
swap
<# s>d #s #44 hold #> \ x1
type
<# s>d #s #44 hold #> \ y1
type
<# s>d #s #44 hold #> \ color
type
eoc console
;
Example: 5432 200 200 100 100 rectangle, draws an unfilled rectangle with a blue (5432) color, from 100,100 to 200,200.
Drawing Lines and Pixels
: line ( color x2 y2 x1 y1 -- )
\ x2 and y2 must be larger than x1 and y1
lcd
." line "
swap
<# s>d #s #> \ x2
type
<# s>d #s #44 hold #> \ y2
type
swap
<# s>d #s #44 hold #> \ x1
type
<# s>d #s #44 hold #> \ y1
type
<# s>d #s #44 hold #> \ color
type
eoc console
;
The LCD doesn't have a command to draw a single pixel, but it can be fudged by drawing a line of no length:
: pixel ( color x y -- )
over over
line
;
Example: 0 10 20 pixel, draws a black pixel at 10,20.
Brush
The LCD has a touch drawing capability, allowing you to draw on the LCD with a stylus. The following word will turn the brush on (with specified color).
Note that the LCD brush won't register a flat finger, it requires a fine stylus for the brush to work. Also note that the response time of the NX3224K024 isn't great - this is independent of your Scamp.
: brush ( color -- )
lcd
." thc="
<# s>d #s #> type \ set the brush color
eoc
." thdra=1"
eoc console
;
The following word disables the brush.
: brushoff
lcd
." thdra=0"
eoc console
;
Printing a String
The LCD has a command (xstr) to place string at a specified location. The general format of the LCD command xstr is :
xstr x,y,width,height,fontID,foreground_color,background_color,xcentered,ycentered,fill_type,"your string here".
You can adapt this to output strings as you wish.
xstr x,y,width,height,fontID,foreground_color,background_color,xcentered,ycentered,fill_type,"your string here".
You can adapt this to output strings as you wish.
The following word prints a string in red text with a black background, at screen coordinates 10,10. Note that the LCD understands colors such as RED, BLACK, GREEN, etc.
: hello
lcd
." xstr 10,10,100,30,0,RED,BLACK,0,1,1,"
34 emit
." Hello world"
34 emit
eoc console
;
Demo
To test our drawing capability, try the following:
: raindrops |
|