Learning from Arduino. Four LCD Libraries for the M2 & X2 chips

Flenser

Senior Member
I have uploaded these four ports of the Arduino liquidcrystal LCD library to the PICAXE chips:
For driving character LCDs in 8-bit mode https://picaxeforum.co.uk/threads/lcd-library-lcd_lib-8bit.33077/
For driving character LCDs in 4-bit mode https://picaxeforum.co.uk/threads/lcd-library-lcd_lib-4bit.33078/
For driving character LCDs using the PCF8574-based I2C backpack https://picaxeforum.co.uk/threads/lcd-library-pcf8574-i2c.33079/
For driving the AXE133 serial LCD module using the Arduino liquidcrystal LCD library commands: https://picaxeforum.co.uk/threads/lcd-library-lcd_lib-axe133-serial.33156/

Why did I write these?

The following times where the forum was unable to help people to drive LCD displays using a PICAXE chip had stuck in my mind:
- In March 2021 we were not able to help Peter Howarth (New Member) and ended up recommending a book by Ron Hackett or a pair of articles from Nuts & Volts for him to try their tutorials.
- In Dec 2021 dennis shubert (New Member) ended up deciding "Think I will get an arduino and lib may work then Thanks for your time."
- In Feb 2022 woschx (New Member) ended up deciding to use an Arduino to drive the LCD instead of a PICAXE and made the comment "With an Arduino and the appropriate library, I have now been able to control the display. It's a pity that there doesn't seem to be anything like that for the Picaxe." (worschx later tried out PhilHornby's SainsmartLCD2004.bas code and from his comment ended up being able to use it instead of an Arduino.)

For Arduino users using the LiquidCrystal LCD library is pretty easy.
Here is all the code needed to configure the LiquidCrystal library and initialize the LCD taken from that library's "Hello World" example program.:
Code:
// include the library code:
#include <LiquidCrystal.h>

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// set up the LCD's number of columns and rows:
lcd.begin(16, 2);


That's it. These four lines complete the configuration of the library and the initialization of the LCD.
The rest of the code in the "Hello World" example simply calls the LCD library's commands to send commands and write characters to the LCD.

On the other hand, when users ask the forum for help using an LCD in their PICAXE program this is what happens:
- One or more forum members provide a link to a working example program that drives an LCD display that:
- use different pins and ports to connect to the LCD and​
- give different instructions on how to connect the LCD to the PICAXE chip, either an ASCII schematic or as a text list of connections.​
- The user that we are helping needs to read these programs and understand them well enough to either modify the example for their own use or else to copy the LCD code out of the example into their own program.
- The program examples we provide mostly send hex values as commands to the LCD so the user we are helping has to read (from somewhere) and understand how these hex values are formatted.
- I did find a couple of exceptions to this. PhilHornby's SainsmartLCD2004.bas code from 2013 and Rolfi's SubsMacros_Serial_LCD.basinc code from 2015.​
- The user we are helping then has to understand what they have written and how to control LCDs well enough to be able to debug their new program.

It appears to me that the current situation is that it's easier for people who are relatively inexperienced with microcontrollers and/or programming to use compiled C on the Arduino to drive an LCD than it is for them to use interpreted BASIC on a PICAXE chip. To quote the character Jubal Early from the TV Series Firefly "Does that seem right to you?"

So woschx's question about why there are no libraries for the PICAXE struck me as a fair one now that PE has the #INCLUDE directive and PICAXE code can use include-only libraries .

This prompted me to:
1. Try writing a simple LCD library to find out if it could be done (it can) and to discover what some of the issues are in writing and using include-only libraries with PICAXE interpreted BASIC (this is a subject for another post)
2. The Arduino LiquidCrystal LCD library's API seemed to me to be a good one to standardize on so next I wanted see if I could port the entire library to the PICAXE (and with a couple of relatively minor syntax changes I could).
3. Having got this far I went ahead and generated three more versions of my library. One using 4-bit mode, one using the PCF8574-based I2C backpack. and one to drive the AXE133 module using the Arduino liquidcrystal LCD library commands

My four libraries implement the same set of commands with just the following exceptions:
- The LCD_LIB() command is specific to each library.
- The PCF8574 backpack library supports turning LCD backlight off and on.
- The AXE133 serial library supports printing the predefined messages that have been stored within the AXE133 firmware program and
controlling the outputs C.0, C.1, & C.2 on the AXE133 module.

Finally, here is the code needed to configure my 8-bit LCD_LIB library and initialize the LCD taken from my PICAXE version of the "Hello World" example program:
Code:
; Include the LCD_LIB configuration macro
#INCLUDE "LCD_LIB-8bit-Config-Macro.basinc"

; Configure all the LCD_LIB settings
;LCD_LIB(columns, rows, lcdEnablePin, lcdEnablePinDir, lcdRsPin, lcdRspinDir, lcdPort, lcdPortDir, wTempVar, bTempVar1, bTempVar2, bLcdSettings)
LCD_LIB(16, 2, outpinC.1, dirC.1, outpinC.2, dirC.2, outpinsB, dirsB, w4, b3, b4, b5)

; Include the LCD_LIB library code
#INCLUDE "LCD_LIB-8bit.basinc"

LCD_begin             ; initialise LCD

My intention was to try and make it as easy as possible to use character-based LCDs with the PICAXE chips and using LCDs with the 4-bit and 8-bit libraries will still require getting all the connections right, including the contrast pot.
However I hope that having a library could make it almost trivially easy to use LCDs with the PCF8574-based I2C backpack as there are only 4 wires to get right when connecting the LCD backpack to the PICAXE chip and with the AXE133 module as there are only 3 wires to connect.

At the moment my project posts make this claim about how easy they are to use:
To use it:
1. Download the files
2. Extract the library files and example programs from the zip file into a directory.
3. Connect your PICAXE chip to the LCD. The manual has pictures showing how to connect each PICAXE chip to the LCD to work with the example programs.
4. Download one of the example programs into the PICAXE using Program Editor.
That's it!

but this is only tested by me. If anyone tests them and finds that this is not true then I would like to hear about it.

All bug reports for these libraries are welcome.

27/07/2024: Post updated to add the AXE133 serial library.
 
Last edited:
Hi,
Using linux, linaxepad and a 20X2, I can't get past the first #INCLUDE with the syntaxe check.

26036
 
Using linux, linaxepad and a 20X2, I can't get past the first #INCLUDE with the syntaxe check.

kfil, as far as I'm aware the Rev-Ed PICAXE precompiler is only available on Windows. There is no Rev-Ed precompiler available for Linux so you won't be able to use any of the precompiler "#" directives.

The user pliser is maintaining a Python script that can process the PICAXE "#" directives on Linux & Mac OS and in this post https://picaxeforum.co.uk/threads/is-picaxe-support-for-mac-officially-dead.32196/post-336485 he describes the latest updates to his script and gives the link where you can download it.
I know that his Python precompiler script can be used with MS Visual Studio on Linux but I've never used linaxepad and I don't know whether it can be configured to use the precompiler script.
 
OK.
I got the same error using Winaxepad and I no longer have PE6 installed, so I'll leave it there.
 
Flenser, you sir are a credit to the forum! Thanks for your dedication to rectifying this issue. It's true that cheap, abundant LCDs are a PITA with Picaxe. Surprising that Rev-Ed hasn't jumped on this problem. I don't have time to dive into this right now but hopefully folks will benefit from your excellent work. Full marks!
 
This looked to be just the thing for a novice like me, but I had some trouble, I couldn’t get it to display letters or numbers on the 16 x 2 LCD.

I loaded the LCD_LIB-4bit.zip and followed all the instructions to load “Hello World” and commented or uncommented the parts depending on either the X2 or M2. I tried both using a 28X2 and a 20M2 with the same result. The backlight was on and adjusting the pot made variations to the LCD but no words or numbers displayed. I tried another LCD with the same result. I had each of the 20M2 outputs flash a LED a few times which to me suggested the 20M2 was working.

I then downloaded the LCD-PCF8574-I2C-V2.zip and loaded example “Hello World” and either commented or uncommented depending on either X2 or M2. I tried both X2 and M2 but got nothing on the display. I loaded the backlight example but that didn’t turn off the backlight. Unfortunately I only have one LCD with the PCF8574 based I2C backpack installed, but judging by the others I wouldn’t expect any difference. Although this one would be my preference, I can’t get it to display either.

It would seem obvious that I am doing something wrong or haven’t done something I should have. Would somebody let me know what I have done wrong and how to fix it?
 
Dalenrose,

The PCF8574-I2C version has the fewest wires so let's investigate that first.

Pls post
  • a picture of your whole circuit. i.e a picture that shows the PICAXE chip, the power supply wires going to it and the wires connecting to the PCF8574-I2C backpack.
  • A copy of the Hello World” program that you download to the chip after you have made all the changes to suit the chip you are using.
 
Hi Flenser,
Thanks for replying. This is the example I downloaded to the chip. The photo shows the Picaxe development board, I used a different board on a previous try.


Code:
#REM
PICAXE LCD PCF8574 I2C backpack Library - Hello World example
Demonstrates the use a 16x2 LCD display. The PICAXE LCD PCF8574-I2C library works with LCD displays that have the PCF8574 based I2C backpack installed.

This program prints "Hello World!" to the LCD and shows the time since startup.

The circuit (08M2, 14M2, 18M2, 20M2, 20X2, 28X2 & 40X2):
* PCF8574 I2C LCD backpack GND pin to ground
* PCF8574 I2C LCD backpack VCC pin to +5V
* PCF8574 I2C LCD backpack SDA pin to PICAXE pin i2c sda
* PCF8574 I2C LCD backpack SCL pin to PICAXE pin i2c scl

Library by Flenser
For information about this library visit: https://picaxeforum.co.uk/threads/lcd-library-pcf8574-i2c.33079/
This example code is in the public domain.
#ENDREM
''Picaxe 20M2

SETFREQ M4

; Include the LCD_LIB configuration macro
#INCLUDE "LCD_LIB-PCF8574-I2C-Config-Macro.basinc"

; Configure all the LCD_LIB settings
; LCD_LIB(columns, rows, i2cSlaveAddress, i2cMode, wTempVar, bTempVar1, bTempVar2, bLcdSettings)
LCD_LIB(16, 2, $4E, I2CSLOW_4, w4, b3, b4, b5)

; Include the LCD_LIB library code
#INCLUDE "LCD_LIB-PCF8574-I2C.basinc"

setup:
LCD_begin             ; initialise LCD

;SETTIMER t1s_4        ; Uncomment this line for X2 chips

;Print a message to the LCD.
LCD_print("Hello World!")

main:
    ; set the cursor to column 0, line 1
    ; (note: line 1 is the second row, since the line numbers start at 0):
    LCD_setCursor(0, 1)

    ; print the number of seconds since reset:
    LCD_writeDecimal(time)        ; Uncomment this line for M2 chips
    ;LCD_writeDecimal(timer)        ; Uncomment this line for X2 chips
goto main
 

Attachments

  • IMG_0864.jpg
    IMG_0864.jpg
    94 KB · Views: 27
@Delenrose Can you confirm that you have the mandatory Pull-Up resistors connected to the SCL and SDA lines in your circuit. They are not obvious to me in the photograph.
 
@Delenrose, I can see no issue with the wiring and pgm. This is not surprising as they are both pretty simple.

However, I should have started with more basic LCD debugging.

Pls disconnect the SCL & SDA wires from the backpack and then turn the power off and back on so that the LCD does it's power on initialization and check what the LCD displays. You should see two lines of black rectangles on the LCD display.

If you do not get this then adjust the pot on the PCF8574-I2C backpack until you do see these lines of rectangles.
 
@inglewoodpete - no I have not got any resistors on the SCL or SDA lines because the PCF8574-I2C manual that I was following didn't have any.

@Flenser - I disconnected the SCL & SDA lines from the backpack turned the power off then on - display showed blank screen - adjusted the pot and got only one line of white rectangles on screen closest to the 16 pin connections - adjusted pot back to get dirty-white/grey. Turned power off and with everything connected up again, turned power back on and still only one row of 16 rectangles showing. I guess that means the LCD is not working properly, unless you have some other tricks up your sleeve. I'll have to order some more and give them a try. Thanks for the trouble you have taken.

When downloading the Hello World example to the chip, does PE or the example automatically open and save the relevant information from the library to the chip at the same time? Because I didn't do anything other than have PE download the example file to the chip.
 
@inglewoodpete - no I have not got any resistors on the SCL or SDA lines because the PCF8574-I2C manual that I was following didn't have any.

@Flenser - I guess that means the LCD is not working properly, unless you have some other tricks up your sleeve. I'll have to order some more and give them a try. Thanks for the trouble you have taken.
I can't imagine how it will communicate without the pullup resistors.

One row of dark blocks indicates that the LCD is operating (ie booted up) correctly but has not yet initialised. This suggests either 1) the initialsation instructions being sent from the PICAXE are wrong or 2) the pullup resistors are required. Insert two 4.7k ohm resistors between +5v and the SDA and SCL pins (anything between 3.9k and 10k will probably work but 4.7k is preferred).
 
Dalenrose,
Where I said "You should see two lines of black rectangles on the LCD display" I was wrong. Inglewoodpete is correct, with the SDL & SCL lines disconnected you should see one line of black rectangles when you turn power on to the LCD.
- This indicates that there is nothing wrong with your LCD. It has done its internal power on setup to display the line of black rectangles.

When you "disconnected the SCL & SDA lines from the backpack turned the power off then on - display showed blank screen" this means that the contrast setting was wrong. That is why I've fallen back to doing basic debugging. If the contrast setting is wrong then you won't seen any text on the LCD, even when everything is working.

Now that you have one line of black rectangles we know that the contrast setting is right and we go to the next LCD debugging step.
Connect the SDA and SCL wires to the LCD again, turn the power on to the M2 & LCD and download the "Hello World" program from your post #8 to the 20M chip again.

The "LCD_begin" command initializes the LCD to the 4-bit mode that the PCF8574-I2C backpack uses and the line of black rectangles should disappear.

Does the line of black rectangles disappear?
What do you see on the LCD?

We want to test one change at a time so pls do not add any extra pullup resistors for this test.

I didn't need to add these pullup resistors when I was testing this library code.
If you'd like to test adding the extra pullup resistors then please do this after you've finished my test. If the pullup resistors are needed then doing this test separately will make it clear what effect each of the two changes had.

When downloading the Hello World example to the chip, does PE or the example automatically open and save the relevant information from the library to the chip at the same time?
Yes, PE copies everyting to the chip.

When you program the chip, PE copies the contents of the two library #INCLUDE files into the "Hello World" program, to make one single combined program, and then does a syntax check of that whole combined program. If the syntax check does not find any errors PE downloads the whole combined program to the PICAXE chip.
 
Last edited:
... The photo shows the Picaxe development board, I used a different board on a previous try.
Hi,

That Red "Backpack" looks a little "unusual". Normally they are a simple, assembled SMD module with maybe a few "Pads" to configure the I2C Address, etc.. The one in the photo appears to have many "Through Holes" that are unpopulated, including the SCL and SDA Pullup resistors? Another potential problem with the Backpacks is that the PCF8574-I2C is a generic chip, so the connections are not "Standardised" for the LCD application. Many of the Backpacks are probably "compatible", because the manufacturer just copied somebody else's. But they might be different because of incompetence, or the developer wanted a "unique" product (i.e. difficult to be substituted by another (cheaper) product). :(

Therefore, you might need to do some Detective Work (Reverse Engineering) on that Backpack, but the first thing to do is to get the I2C working. You don't even need to add any Pullup Resistors, you can use the PICaxe's internal Pullups with a PULLUP $A0 at the top of the (20M2) Program. Strictly, those resistors are "Too High" (~30k) for a large system, but should be adequate for a simple solderless breadboard. However, the I2C Slave Address might be in doubt, so I suggest using a Bus Search Program such as THIS. That particular one is rather large, but it should detect "missing" Pullup resistors and even switch the PICaxe's internal ones on if necessary. ;)

BTW, I don't see an (e.g. 100 nF) supply decoupling capacitor near to the PICaxe. There's probably one somewhere, but its omission has been known to cause problems.

Cheers, Alan.
 
@Flenser,

To continue your test. I copied the code from post 8 to PE and downloaded it to the M2, without errors, and with everything all connected and power on:
The line of rectangles does not disappear.
The LCD displays one row of 16 rectangles only.
 
We want to test one change at a time so pls do not add any extra pullup resistors for this test.

I didn't need to add these pullup resistors when I was testing this library code.
If you'd like to test adding the extra pullup resistors then please do this after you've finished my test. If the pullup resistors are needed then doing this test separately will make it clear what effect each of the two changes had.
When I did an internet search for the "LCM1602 IIC" module, a range of different modules fitting that description were found. And when I look at the photo posted by Dalenrose in Post #8 above, there appears to be provision for the two (through-hole) pullup resistors. To me, it is pretty conclusive that the manufacturer has not included the pullups. For that reason I have been questioning whether Dalenrose has included them. One way to check if there are pullup resistors would be to check the voltage on the SCL and SDA pin after bootup (with respect to 0v/Gnd): they should show a consistent Vcc level (around 5 volts).
 
Dalenrose,

The fact that "The line of rectangles does not disappear" for the 2nd test in your post #6 indicates that the I2C communication between the 20M2 chip and the PCF8574-I2C backpack is not working.

Inglewoodpete has definitely spotted an important difference between the PCF8574-I2C backpack you are using and the backpack I used for my testing.

My PCF8574-I2C backpack does not have any resistors marked as I2C but it DOES have two 4.7k ohm resistors installed.

For you next test install the two I2C pullup resistors as described by Inglewoodpete in his post #12:
"Insert two 4.7k ohm resistors between +5v and the SDA and SCL pins (anything between 3.9k and 10k will probably work but 4.7k is preferred)"

You can do this test by just installing the one resistor between the 20M2 pin11 (SCL) and VCC on your bread board and a second resistor between the 20M2 pin 13 (SDA) and VCC on your breadboard.

You have already downloaded the "Hello World" program to the 20M2 but you will will need to turn the power off and back on so that the program runs from the beginning to execute the "LCD_Begin" command that is needed to initialize the LCD to the 4-bit mode that the PCF8574-I2C backpack uses.

If this works then you can remove those two tempory pullup resistors from your breadboard and solder them between the holes marked SDA & SCL on you PCF8574-I2C backpack so that they are in place permanently for when you use this LCD for other projects.
 
Last edited:
I inserted a 4K7 resistor on each of the SDA & SCL pins on the breadboard and hey presto!! It works fine and even will turn the backlight off when I run that example.
It seems I must have got a cheap type of LCD. I have made a note in my PCF8574-I2C manual that if the Hello World example doesn't display letters & numbers on the LCD screen and only 16 rectangles appear then insert 4K7 resistor between each of the SCL & SDA pins and 5v. That way if I get some of these cheap LCDs in the future I should be right.
This probably means that the LCDs without a backpack should have 4K7 resistors inserted as well but I don't know where. Although I am not real concerned about that at the moment, I have got the 4 pin version working now which is, to me, better all around.

Thankyou very much to all that responded for your help and assistance. To a novice like me it's great to see people willing to help. Have a great day!
 
This probably means that the LCDs without a backpack should have 4K7 resistors inserted as well
These 4K7 resistors are only required when using the PICAXE I2C pins SDA & SCL, so the are only neeeded when using the PCF8574-I2C backpack to drive the LCD.
When driving the LCD directly from the PICAXE chip in 4-bit or 8-bit mode there are no 4K7 resistors needed.

My guess is that the LCD_LIB-4bit library did not work for you was that the contrast was wrong. If you try the LCD_LIB-4bit library again with the contrast set to show the 16 black rectangles when VCC and GND are connected you should find that it works as well.
 
This probably means that the LCDs without a backpack should have 4K7 resistors inserted as well but I don't know where. Although I am not real concerned about that at the moment, I have got the 4 pin version working now which is, to me, better all around.
Due to the way i2c works, all bus drivers are "open drain" or "open collector", which pull the lines down to 0v when signalling a zero bit state. This requires both bus lines to have (external) pull-up resistors to maintain the Vcc (+3.3 or 5 volts) to indicate a '1' state when the lines are not pulled down by either the i2c master or i2c slave. i2c signalling is bidirectional: both the master and the slave can send or receive data.

Open drain/collector circuits are not normally required for one-way data transmission like to an LCD, so pull-up resistors would not be required if the LCD was directly connected to a PICAXE without the backpack.
 
Thanks again for the info. I'll give that a try. At the moment it seems the backpack setup will suit me just fine and it's more economical with Picaxe pins.
 
kfil, as far as I'm aware the Rev-Ed PICAXE precompiler is only available on Windows. There is no Rev-Ed precompiler available for Linux so you won't be able to use any of the precompiler "#" directives.

The user pliser is maintaining a Python script that can process the PICAXE "#" directives on Linux & Mac OS and in this post https://picaxeforum.co.uk/threads/is-picaxe-support-for-mac-officially-dead.32196/post-336485 he describes the latest updates to his script and gives the link where you can download it.
I know that his Python precompiler script can be used with MS Visual Studio on Linux but I've never used linaxepad and I don't know whether it can be configured to use the precompiler script.
Thanks for sharing and recommending my preprocessor script, I'm glad it's still being used and is useful for people!

A rather late response, but in case it's helpful for anyone else, you definitely can use it with axepad, but the process for doing so is a little awkward. You'd want to write your code in axepad as usual, then instead of running syntax check or upload from axepad, instead save the file, then run my preprocessor script on it. You can choose with the options to the preprocessor whether to compile and upload the code directly to the PICAXE chips, or, if you prefer using axepad's interface, open the file it creates in axepad, and from there upload that to the PICAXE.
 
Back
Top