From 8f789fe8f28b678b3be3e83dc80942bd454a0268 Mon Sep 17 00:00:00 2001 From: Gavin lyons Date: Sun, 30 Apr 2023 20:53:19 +0100 Subject: [PATCH] version 1.3.0 --- README.md | 42 +- examples/HelloWorld/HelloWorld.ino | 30 +- examples/HelloWorldSTM32/HelloWorldSTM32.ino | 40 ++ examples/TestRun/TestRun.ino | 264 ------------ examples/TestRun16X02/TestRun16X02.ino | 252 ++++++++++++ examples/TestRun20X04/TestRun20X04.ino | 201 +++++---- extras/doc/CHANGELOG.md | 8 + extras/doc/GPIO_MCU_used.md | 28 -- extras/doc/GPIO_MCU_used.txt | 25 ++ keywords.txt | 1 + library.properties | 2 +- src/HD44780_LCD_PCF8574.cpp | 406 +++++++++++-------- src/HD44780_LCD_PCF8574.h | 192 ++++----- 13 files changed, 789 insertions(+), 702 deletions(-) create mode 100644 examples/HelloWorldSTM32/HelloWorldSTM32.ino delete mode 100644 examples/TestRun/TestRun.ino create mode 100644 examples/TestRun16X02/TestRun16X02.ino delete mode 100644 extras/doc/GPIO_MCU_used.md create mode 100644 extras/doc/GPIO_MCU_used.txt diff --git a/README.md b/README.md index 1d351e1..57c36ef 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,20 @@ -[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/paypalme/whitelight976) +[![Website](https://img.shields.io/badge/Website-Link-blue.svg)](https://gavinlyonsrepo.github.io/) [![Rss](https://img.shields.io/badge/Subscribe-RSS-yellow.svg)](https://gavinlyonsrepo.github.io//feed.xml) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/paypalme/whitelight976) -![ lcd ](https://github.com/gavinlyonsrepo/pic_16F1619_projects/blob/master/images/LCDPCF.jpg) +![ lcd image ](https://github.com/gavinlyonsrepo/pic_16F1619_projects/blob/master/images/LCDPCF.jpg) + +# Hd44780_LCD_PCF8574 Table of contents --------------------------- * [Overview](#overview) * [Installation](#installation) + * [Software](#software) * [Output](#output) - * [Tested](#tested) - * [Ports](#ports) - + * [Tested on](#tested-on) + * [Notes](#notes) + Overview -------------------- * Name : HD44780_LCD_PCF8574 @@ -31,11 +34,16 @@ Overview Installation ------------------------------ -The library is included in the official Arduino library manger and the optimum way to install it is using the library manager which can be opened by the manage libraries option in Arduino IDE. +The library is included in the official Arduino library manger and the optimum way to install it is using the library manager in the Arduino IDE. + +Software +-------------------------- -See link below for instruction for this and for the other methods too. +**API** -[Installing Additional Arduino Libraries guide](https://www.arduino.cc/en/Guide/Libraries) +The API (application programming interface) html documentation is at link. Hosted on github pages and generated by Doxygen software. Here the user will find lots of information on files, functions & data types. + +[Software API Url Link](https://gavinlyonsrepo.github.io/misc/software_docs/HD44780_LCD_PCF8574/index.html) Output --------------------- @@ -48,22 +56,22 @@ Output of custom character test in testrun example file on 16x02 display. ![ pic2 ](https://github.com/gavinlyonsrepo/HD44780_LCD_PCF8574/blob/main/extras/image/2004.jpg) -Tested +Tested on ------------------------ Tested on following MCUs. -The example files are setup for an UNO/NANO for the pin connections used -by for other MCU testing see extras/doc folder GPIO_MCU_used.MD file. +The example files are setup for an UNO/NANO rev 3.0 for the pin connections used +by for other MCU testing see extras/doc folder GPIO_MCU_used.txt file. 1. Arduino UNO & NANO v3 2. ESP8266 3. ESP32 -4. STM32 "blue pill", Can support both I2C ports , In example files comment in #define STM32_BLUE_PILL_SETUP -and pick which port you want. Added in Version 1.2.0. +4. STM32 "blue pill", Can support both I2C ports , Use STM32 example file. -Ports +Notes ------------------------ -Raspberry Pi C++ : [URL link](https://github.com/gavinlyonsrepo/HD44780_LCD_RPI) - -PIC XC32 : [URL link](https://github.com/gavinlyonsrepo/pic_32_projects) +1. "stm32duino" board manager core used in testing STM32 "blue pill" +2. For description of entry modes , cursor types, custom characters etc [See]( http://dinceraydin.com/lcd/commands.htm) +3. 16X04 board not tested but should work. +4. I2C Debugging can be turned on by commenting in a define in header file. diff --git a/examples/HelloWorld/HelloWorld.ino b/examples/HelloWorld/HelloWorld.ino index 3fb0a30..933f403 100644 --- a/examples/HelloWorld/HelloWorld.ino +++ b/examples/HelloWorld/HelloWorld.ino @@ -1,38 +1,26 @@ -/* - * File: HelloWorld.ino - * Author: Gavin Lyons. - * Description: See URL for full details. - * URL: https://github.com/gavinlyonsrepo/HD44780_LCD_PCF8574 - */ + /*! + @file HelloWorld.ino + @author Gavin Lyons + @brief + Hello World for HD44780_LCD_PCF8574 arduino library +*/ // Section: Included library #include "HD44780_LCD_PCF8574.h" // Section: Defines #define DISPLAY_DELAY_INIT 50 // mS -// **** NOTE :: Comment in If using STM32 bluepill **** -//#define STM32_BLUE_PILL_SETUP - -// Section: Globals -#ifdef STM32_BLUE_PILL_SETUP // *** STM32 Blue Pill *** -// Set-up Choice I2C interface 1 or 2 :: pick one and one only -TwoWire Wire2(1,I2C_FAST_MODE); // Use STM32 I2C1 -//TwoWire Wire2(2,I2C_FAST_MODE); // Use STM32 I2C2 -HD44780LCD myLCD(2, 16, 0x27, &Wire2); // LCD object.rows ,cols ,PCF8574 I2C addr, Interface) -#else -// myLCD(rows , cols , PCF8574 I2C address) -HD44780LCD myLCD( 2, 16, 0x27); // instantiate an object -#endif +HD44780LCD myLCD(2, 16, 0x27, &Wire); // instantiate an object // Section: Setup void setup() { delay(DISPLAY_DELAY_INIT); - myLCD.PCF8574_LCDInit(LCDCursorTypeOn); + myLCD.PCF8574_LCDInit(myLCD.LCDCursorTypeOn); myLCD.PCF8574_LCDClearScreen(); myLCD.PCF8574_LCDBackLightSet(true); - myLCD.PCF8574_LCDGOTO(LCDLineNumberOne, 0); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberOne, 0); } // Section: Main Loop diff --git a/examples/HelloWorldSTM32/HelloWorldSTM32.ino b/examples/HelloWorldSTM32/HelloWorldSTM32.ino new file mode 100644 index 0000000..03683bf --- /dev/null +++ b/examples/HelloWorldSTM32/HelloWorldSTM32.ino @@ -0,0 +1,40 @@ + /*! + @file HelloWorldSTM32.ino + @author Gavin Lyons + @brief + Hello World for HD44780_LCD_PCF8574 arduino library for STM32 "blue pill" + @note Allows testing of both I2C ports 1 and 2 on the STM32 "blue pill" board +*/ + +// Section: Included library +#include "HD44780_LCD_PCF8574.h" + +// Section: Defines +#define DISPLAY_DELAY_INIT 50 // mS +#define STM_I2C1_PORT 1 // STM32 I2C port 1 = I2C1 +#define STM_I2C2_PORT 2 // STM32 I2C port 2 = I2C2 + +// Section: Globals +TwoWire Wire2(STM_I2C1_PORT); // use I2C1 Port 1 +HD44780LCD myLCD(2, 16, 0x27, &Wire2); + +// Section: Setup + +void setup() { + delay(DISPLAY_DELAY_INIT); + myLCD.PCF8574_LCDInit(myLCD.LCDCursorTypeOn); + myLCD.PCF8574_LCDClearScreen(); + myLCD.PCF8574_LCDBackLightSet(true); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberOne, 0); +} + +// Section: Main Loop + +void loop() { + char testString[] = "Hello World"; + myLCD.PCF8574_LCDSendString(testString); + myLCD.PCF8574_LCDSendChar('!'); // Display a single character + while (true) {}; +} + +// EOF diff --git a/examples/TestRun/TestRun.ino b/examples/TestRun/TestRun.ino deleted file mode 100644 index 3f7a1ae..0000000 --- a/examples/TestRun/TestRun.ino +++ /dev/null @@ -1,264 +0,0 @@ -/* - * File: TestRun.cpp - * Description: - * This file contains the "main" function for project, a set of test sequence - * to test the HD44780 LCD library - * Author: Gavin Lyons. - * Description: See URL for full details. - * URL: https://github.com/gavinlyonsrepo/HD44780_LCD_PCF8574 - * - * Notes: - * (1) For description of entry modes , cursor types, custom characters - * and more see here http://dinceraydin.com/lcd/commands.htm - * (2) This is for 16 column 2 row LCD - */ - -// Section: Included library -#include "HD44780_LCD_PCF8574.h" - -// Section: Defines -#define DISPLAY_DELAY_1 1000 -#define DISPLAY_DELAY_2 2000 -#define DISPLAY_DELAY 5000 -// **** NOTE :: Comment in If using STM32 bluepill **** -//#define STM32_BLUE_PILL_SETUP - -// Section: Globals -#ifdef STM32_BLUE_PILL_SETUP // *** STM32 Blue Pill *** -// Set-up Choice I2C interface 1 or 2 :: pick one and one only -TwoWire Wire2(1,I2C_FAST_MODE); // Use STM32 I2C1 -//TwoWire Wire2(2,I2C_FAST_MODE); // Use STM32 I2C2 -HD44780LCD myLCD(2, 16, 0x27, &Wire2); // LCD object.rows ,cols ,PCF8574 I2C addr, Interface) -#else -// myLCD(rows , cols , PCF8574 I2C address) -HD44780LCD myLCD( 2, 16, 0x27); // instantiate an object -#endif - -// Section: Function Prototypes - -void helloWorld(void); -void cursorMoveTest(void); -void scrollTest(void); -void gotoTest(void); -void clearLineTest(void); -void cursorTest(void); -void entryModeTest(void); -void writeNumTest(void); -void customChar(void); -void backLightTest(void); -void endTest(void); - -// Section: Setup - -void setup() { - delay(50); - myLCD.PCF8574_LCDInit(LCDCursorTypeOn); - myLCD.PCF8574_LCDClearScreen(); - myLCD.PCF8574_LCDBackLightSet(true); - -} - -// Section: Main Loop - -void loop() { - - helloWorld(); - cursorMoveTest(); - scrollTest(); - gotoTest(); - clearLineTest(); - cursorTest(); // Cursor type and screen reset test(4 off ) check, - // cursor mode is changed by calling reset. - entryModeTest(); // Text entry mode (4 off ) Note: if screen is reset - // non default entry mode setting will also be reset - writeNumTest(); // Print numerical data using print() test - customChar(); // Custom character from CGRAM test - backLightTest(); - -} // End of Main - -// Section : Functions - -void helloWorld(void) { - char teststr1[] = "Hello"; - char teststr2[] = "World"; - myLCD.PCF8574_LCDGOTO(LCDLineNumberOne, 0); - myLCD.PCF8574_LCDSendString(teststr1); - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo , 0); - myLCD.PCF8574_LCDSendString(teststr2); // Display a string - myLCD.PCF8574_LCDSendChar('!'); // Display a single character - delay(DISPLAY_DELAY_1); -} - -void cursorMoveTest(void) { - myLCD.PCF8574_LCDMoveCursor(LCDMoveRight, 2); - delay(DISPLAY_DELAY); - myLCD.PCF8574_LCDMoveCursor(LCDMoveLeft, 2); -} - -void scrollTest(void) { - for (uint8_t i = 0; i < 5; i++) { - myLCD.PCF8574_LCDScroll(LCDMoveRight, 1); - delay(DISPLAY_DELAY_2); - } - myLCD.PCF8574_LCDScroll(LCDMoveLeft, 5); - delay(DISPLAY_DELAY_2); -} - -void gotoTest(void) { - char teststr3[] = "Line 2"; - myLCD.PCF8574_LCDClearScreen(); - myLCD.PCF8574_LCDGOTO(LCDLineNumberOne, 10); - myLCD.PCF8574_LCDSendChar('A'); - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo , 2); - myLCD.PCF8574_LCDSendString(teststr3); - delay(DISPLAY_DELAY); -} - -void clearLineTest(void) -{ - myLCD.PCF8574_LCDClearLine(LCDLineNumberTwo ); - delay(DISPLAY_DELAY_2); - myLCD.PCF8574_LCDClearLine(LCDLineNumberOne); - delay(DISPLAY_DELAY_2); -} - -void cursorTest(void) { - char teststr1[] = "Cursor no 4"; - char teststr2[] = "Cursor no 1"; - char teststr3[] = "Cursor no 2"; - char teststr4[] = "Cursor no 3"; - - myLCD.PCF8574_LCDResetScreen(LCDCursorTypeOnBlink); //type 4 cursor - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo, 0); - myLCD.PCF8574_LCDSendString(teststr1); - delay(DISPLAY_DELAY_2); - myLCD.PCF8574_LCDClearLine(LCDLineNumberTwo); - - myLCD.PCF8574_LCDResetScreen(LCDCursorTypeOff); //type 1 cursor - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo, 0); - myLCD.PCF8574_LCDSendString(teststr2); - delay(DISPLAY_DELAY_2); - myLCD.PCF8574_LCDClearLine(LCDLineNumberTwo); - - myLCD.PCF8574_LCDResetScreen(LCDCursorTypeBlink); //type 2 cursor - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo, 0); - myLCD.PCF8574_LCDSendString(teststr3); - delay(DISPLAY_DELAY_2); - myLCD.PCF8574_LCDClearLine(LCDLineNumberTwo); - - myLCD.PCF8574_LCDResetScreen(LCDCursorTypeOn); // Back to initial state , type 3 - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo, 0); - myLCD.PCF8574_LCDSendString(teststr4); - delay(DISPLAY_DELAY_2); - myLCD.PCF8574_LCDClearLine(LCDLineNumberTwo); -} - -void writeNumTest() -{ - int numPos = 193; - int numNeg = -8582; - double myPI = 3.1456; - - myLCD.PCF8574_LCDGOTO(LCDLineNumberOne, 0); - myLCD.print(numPos); - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo , 0); - myLCD.print(numNeg); - myLCD.PCF8574_LCDMoveCursor(LCDMoveRight, 2); - myLCD.print(myPI,3); - - delay(DISPLAY_DELAY); - myLCD.PCF8574_LCDClearScreen(); - - myLCD.PCF8574_LCDGOTO(LCDLineNumberOne, 0); // 11 - myLCD.print(11); - myLCD.PCF8574_LCDMoveCursor(LCDMoveRight, 2); // 13 - myLCD.print(11,OCT); - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo , 0); // B - myLCD.print(11, HEX); - myLCD.PCF8574_LCDMoveCursor(LCDMoveRight, 2); // 1011 - myLCD.print(11,BIN); - - delay(DISPLAY_DELAY); -} - -void customChar(void) { - - // Data to test custom function - uint8_t bellChar[8] = {0x4, 0xe, 0xe, 0xe, 0x1f, 0x0, 0x4}; - uint8_t noteChar[8] = {0x2, 0x3, 0x2, 0xe, 0x1e, 0xc, 0x0}; - uint8_t clockChar[8] = {0x0, 0xe, 0x15, 0x17, 0x11, 0xe, 0x0}; - uint8_t heartChar[8] = {0x0, 0xa, 0x1f, 0x1f, 0xe, 0x4, 0x0}; - uint8_t duckChar[8] = {0x0, 0xc, 0x1d, 0xf, 0xf, 0x6, 0x0}; - uint8_t checkChar[8] = {0x0, 0x1, 0x3, 0x16, 0x1c, 0x8, 0x0}; - uint8_t crossChar[8] = {0x0, 0x1b, 0xe, 0x4, 0xe, 0x1b, 0x0}; - uint8_t enterChar[8] = {0x1, 0x1, 0x5, 0x9, 0x1f, 0x8, 0x4}; - - myLCD.PCF8574_LCDClearScreen(); - - // Load the CGRAM with the data , custom characters - // location argument must be 0 to 7 - myLCD.PCF8574_LCDCreateCustomChar(0, bellChar); // Location 0 - myLCD.PCF8574_LCDCreateCustomChar(1, noteChar); - myLCD.PCF8574_LCDCreateCustomChar(2, clockChar); - myLCD.PCF8574_LCDCreateCustomChar(3, heartChar); - myLCD.PCF8574_LCDCreateCustomChar(4, duckChar); - myLCD.PCF8574_LCDCreateCustomChar(5, checkChar); - myLCD.PCF8574_LCDCreateCustomChar(6, crossChar); - myLCD.PCF8574_LCDCreateCustomChar(7, enterChar); // Location 7 - - myLCD.PCF8574_LCDGOTO(LCDLineNumberOne, 0); - - // Print out custom characters from - // CGRAM locations 0-7 - // location argument must be 0 to 7 - for (uint8_t i = 0; i < 8; i++) { - myLCD.PCF8574_LCDPrintCustomChar(i); - myLCD.PCF8574_LCDMoveCursor(LCDMoveRight, 1); - } - - delay(DISPLAY_DELAY); - myLCD.PCF8574_LCDClearScreen(); -} - -void backLightTest(void) -{ - char teststr4[] = "Back Light"; - // Needs another command/data before it changes Light - myLCD.PCF8574_LCDBackLightSet(false); - - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo , 1); - myLCD.PCF8574_LCDSendString(teststr4); - delay(DISPLAY_DELAY); - myLCD.PCF8574_LCDBackLightSet(true); - myLCD.PCF8574_LCDClearScreen(); -} - -void entryModeTest(void) { - - char teststr8[] = "1234"; - - myLCD.PCF8574_LCDChangeEntryMode(LCDEntryModeOne); - myLCD.PCF8574_LCDGOTO(LCDLineNumberOne, 8); - myLCD.PCF8574_LCDSendString(teststr8); // <-C4321 - delay(DISPLAY_DELAY_2); - myLCD.PCF8574_LCDClearScreenCmd(); - - myLCD.PCF8574_LCDChangeEntryMode(LCDEntryModeTwo); - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo, 8); - myLCD.PCF8574_LCDSendString(teststr8); // C4321-> - delay(DISPLAY_DELAY_2); - myLCD.PCF8574_LCDClearScreenCmd(); - - myLCD.PCF8574_LCDChangeEntryMode(LCDEntryModeFour); - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo, 8); - myLCD.PCF8574_LCDSendString(teststr8); // <-1234C - delay(DISPLAY_DELAY_2); - myLCD.PCF8574_LCDClearScreenCmd(); - - myLCD.PCF8574_LCDChangeEntryMode(LCDEntryModeThree); // Set back to default entry mode - myLCD.PCF8574_LCDClearScreenCmd(); - delay(DISPLAY_DELAY_1); -} - -// *** EOF *** diff --git a/examples/TestRun16X02/TestRun16X02.ino b/examples/TestRun16X02/TestRun16X02.ino new file mode 100644 index 0000000..54c3f42 --- /dev/null +++ b/examples/TestRun16X02/TestRun16X02.ino @@ -0,0 +1,252 @@ +/*! + @file TestRun16X02.ino + @author Gavin Lyons + @brief + This file contains the "main" function for project, a set of test sequence + to test the HD44780_LCD_PCF8574 arduino library. 16X02 display. + @note + -# Test 1 :: Hello world + -# Test 2 :: Move the cursor test + -# Test 3 :: Scroll the display test + -# Test 4 :: Test GOTO method + -# Test 5 :: Test clear a line method + -# Test 6 :: Cursor type (4 off) and screen reset test, Cursor mode is changed with a reset. + -# Test 7 :: Text entry mode (4 off) if screen is reset the entry mode will be reset to default + -# Test 8 :: Print numerical data using print() method + -# Test 9 :: Custom character's from the CGRAM test + -# Test 10 :: Backlight test. +*/ + +// Section: Included library +#include "HD44780_LCD_PCF8574.h" + +// Section: Defines +#define DISPLAY_DELAY_1 1000 +#define DISPLAY_DELAY_2 2000 +#define DISPLAY_DELAY 5000 + +// Section: Globals +HD44780LCD myLCD( 2, 16, 0x27, &Wire); // instantiate an object + +// Section: Function Prototypes + +void helloWorld(void); +void cursorMoveTest(void); +void scrollTest(void); +void gotoTest(void); +void clearLineTest(void); +void cursorTest(void); +void entryModeTest(void); +void writeNumTest(void); +void customChar(void); +void backLightTest(void); +void endTest(void); + +// Section: Setup + +void setup() { + delay(50); + myLCD.PCF8574_LCDInit(myLCD.LCDCursorTypeOn); + myLCD.PCF8574_LCDClearScreen(); + myLCD.PCF8574_LCDBackLightSet(true); + +} + +// Section: Main Loop + +void loop() { + + helloWorld(); + cursorMoveTest(); + scrollTest(); + gotoTest(); + clearLineTest(); + cursorTest(); + entryModeTest(); + writeNumTest(); + customChar(); + backLightTest(); + +} // End of Main + +// Section : Functions + +void helloWorld(void) { + char teststr1[] = "Hello"; + char teststr2[] = "World"; + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberOne, 0); + myLCD.PCF8574_LCDSendString(teststr1); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo , 0); + myLCD.PCF8574_LCDSendString(teststr2); // Display a string + myLCD.PCF8574_LCDSendChar('!'); // Display a single character + delay(DISPLAY_DELAY_1); +} + +void cursorMoveTest(void) { + myLCD.PCF8574_LCDMoveCursor(myLCD.LCDMoveRight, 2); + delay(DISPLAY_DELAY); + myLCD.PCF8574_LCDMoveCursor(myLCD.LCDMoveLeft, 2); +} + +void scrollTest(void) { + for (uint8_t i = 0; i < 5; i++) { + myLCD.PCF8574_LCDScroll(myLCD.LCDMoveRight, 1); + delay(DISPLAY_DELAY_2); + } + myLCD.PCF8574_LCDScroll(myLCD.LCDMoveLeft, 5); + delay(DISPLAY_DELAY_2); +} + +void gotoTest(void) { + char teststr3[] = "Line 2"; + myLCD.PCF8574_LCDClearScreen(); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberOne, 10); + myLCD.PCF8574_LCDSendChar('A'); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo , 2); + myLCD.PCF8574_LCDSendString(teststr3); + delay(DISPLAY_DELAY); +} + +void clearLineTest(void) +{ + myLCD.PCF8574_LCDClearLine(myLCD.LCDLineNumberTwo ); + delay(DISPLAY_DELAY_2); + myLCD.PCF8574_LCDClearLine(myLCD.LCDLineNumberOne); + delay(DISPLAY_DELAY_2); +} + +void cursorTest(void) { + char teststr1[] = "Cursor no 4"; + char teststr2[] = "Cursor no 1"; + char teststr3[] = "Cursor no 2"; + char teststr4[] = "Cursor no 3"; + + myLCD.PCF8574_LCDResetScreen(myLCD.LCDCursorTypeOnBlink); //type 4 cursor + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo, 0); + myLCD.PCF8574_LCDSendString(teststr1); + delay(DISPLAY_DELAY_2); + myLCD.PCF8574_LCDClearLine(myLCD.LCDLineNumberTwo); + + myLCD.PCF8574_LCDResetScreen(myLCD.LCDCursorTypeOff); //type 1 cursor + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo, 0); + myLCD.PCF8574_LCDSendString(teststr2); + delay(DISPLAY_DELAY_2); + myLCD.PCF8574_LCDClearLine(myLCD.LCDLineNumberTwo); + + myLCD.PCF8574_LCDResetScreen(myLCD.LCDCursorTypeBlink); //type 2 cursor + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo, 0); + myLCD.PCF8574_LCDSendString(teststr3); + delay(DISPLAY_DELAY_2); + myLCD.PCF8574_LCDClearLine(myLCD.LCDLineNumberTwo); + + myLCD.PCF8574_LCDResetScreen(myLCD.LCDCursorTypeOn); // Back to initial state , type 3 + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo, 0); + myLCD.PCF8574_LCDSendString(teststr4); + delay(DISPLAY_DELAY_2); + myLCD.PCF8574_LCDClearLine(myLCD.LCDLineNumberTwo); +} + +void writeNumTest() +{ + int numPos = 193; + int numNeg = -8582; + double myPI = 3.1456; + + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberOne, 0); + myLCD.print(numPos); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo , 0); + myLCD.print(numNeg); + myLCD.PCF8574_LCDMoveCursor(myLCD.LCDMoveRight, 2); + myLCD.print(myPI,3); + + delay(DISPLAY_DELAY); + myLCD.PCF8574_LCDClearScreen(); + + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberOne, 0); // 11 + myLCD.print(11); + myLCD.PCF8574_LCDMoveCursor(myLCD.LCDMoveRight, 2); // 13 + myLCD.print(11,OCT); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo , 0); // B + myLCD.print(11, HEX); + myLCD.PCF8574_LCDMoveCursor(myLCD.LCDMoveRight, 2); // 1011 + myLCD.print(11,BIN); + + delay(DISPLAY_DELAY); +} + +void customChar(void) { + uint8_t index = 0; // Character generator RAM location ,0-7 ,64 bytes + // custom characters data to test custom character function + uint8_t symbolData[8][8] = { + {0x04, 0x0E, 0x0E, 0x0E, 0x1F, 0x00, 0x04, 0x00}, // bell + {0x02, 0x03, 0x02, 0x0E, 0x1E, 0x0C, 0x00, 0x00}, // Note + {0x00, 0x0E, 0x15, 0x17, 0x11, 0x0E, 0x00, 0x00}, // clock + {0x00, 0x0C, 0x1D, 0x0F, 0x0F, 0x06, 0x00, 0x00}, // duck + {0x00, 0x01, 0x03, 0x16, 0x1C, 0x08, 0x00, 0x00}, // check + {0x00, 0x1B, 0x0E, 0x04, 0x0E, 0x1B, 0x00, 0x00}, // cross + {0x00, 0x0A, 0x1F, 0x1F, 0x0E, 0x04, 0x00, 0x00}, // heart + {0x01, 0x01, 0x05, 0x09, 0x1F, 0x08, 0x04, 0x00} // return arrow + }; + + myLCD.PCF8574_LCDClearScreen(); + + // Load the CGRAM with the data , custom characters + // location argument must be 0 to 7 , load the data into LCD memory + for (uint8_t index = 0; index < 8; index++) { + myLCD.PCF8574_LCDCreateCustomChar(index , symbolData[index]); + } + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberOne, 0); + + // Print out custom characters from + // CGRAM locations 0-7 , location argument must be 0 to 7 + for (index = 0; index < 8; index ++) { + myLCD.PCF8574_LCDPrintCustomChar(index); + myLCD.PCF8574_LCDMoveCursor(myLCD.LCDMoveRight, 1); + } + + delay(DISPLAY_DELAY); + myLCD.PCF8574_LCDClearScreen(); +} + +void backLightTest(void) +{ + char teststr4[] = "Back Light :: "; + + myLCD.PCF8574_LCDBackLightSet(false); // Needs another command/data before it changes Light + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo , 1); + myLCD.PCF8574_LCDSendString(teststr4); + myLCD.print(myLCD.PCF8574_LCDBackLightGet()); // read the backlight variable status + delay(DISPLAY_DELAY); + + myLCD.PCF8574_LCDBackLightSet(true); // Needs another command/data before it changes Light + myLCD.PCF8574_LCDClearScreen(); +} + +void entryModeTest(void) { + + char teststr8[] = "1234"; + + myLCD.PCF8574_LCDChangeEntryMode(myLCD.LCDEntryModeOne); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberOne, 8); + myLCD.PCF8574_LCDSendString(teststr8); // <-C4321 + delay(DISPLAY_DELAY_2); + myLCD.PCF8574_LCDClearScreenCmd(); + + myLCD.PCF8574_LCDChangeEntryMode(myLCD.LCDEntryModeTwo); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo, 8); + myLCD.PCF8574_LCDSendString(teststr8); // C4321-> + delay(DISPLAY_DELAY_2); + myLCD.PCF8574_LCDClearScreenCmd(); + + myLCD.PCF8574_LCDChangeEntryMode(myLCD.LCDEntryModeFour); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo, 8); + myLCD.PCF8574_LCDSendString(teststr8); // <-1234C + delay(DISPLAY_DELAY_2); + myLCD.PCF8574_LCDClearScreenCmd(); + + myLCD.PCF8574_LCDChangeEntryMode(myLCD.LCDEntryModeThree); // Set back to default entry mode + myLCD.PCF8574_LCDClearScreenCmd(); + delay(DISPLAY_DELAY_1); +} + +// *** EOF *** diff --git a/examples/TestRun20X04/TestRun20X04.ino b/examples/TestRun20X04/TestRun20X04.ino index 2e8ec92..627adb5 100644 --- a/examples/TestRun20X04/TestRun20X04.ino +++ b/examples/TestRun20X04/TestRun20X04.ino @@ -1,17 +1,21 @@ -/* - * File: TestRu20X04n.cpp - * Description: - * This file contains the "main" function for project, a set of test sequence - * to test the HD44780 LCD library 20x04 - * Author: Gavin Lyons. - * Description: See URL for full details. - * URL: https://github.com/gavinlyonsrepo/HD44780_LCD_PCF8574 - * - * Notes: - * (1) For description of entry modes , cursor types, custom characters - * and more see here http://dinceraydin.com/lcd/commands.htm - * (2) This file is for 20 cols 4 row LCD - */ + /*! + @file TestRun20X04.ino + @author Gavin Lyons + @brief + This file contains the "main" function for project, a set of test sequence + to test the HD44780_LCD_PCF8574 arduino library. 20X04 display. + @note + -# Test 1 :: Hello world + -# Test 2 :: Move the cursor test + -# Test 3 :: Scroll the display test + -# Test 4 :: Test GOTO method + -# Test 5 :: Test clear a line method + -# Test 6 :: Cursor type (4 off) and screen reset test, Cursor mode is changed with a reset. + -# Test 7 :: Text entry mode (4 off) if screen is reset the entry mode will be reset to default + -# Test 8 :: Print numerical data using print() method + -# Test 9 :: Custom character's from the CGRAM test + -# Test 10 :: Backlight test. +*/ // Section: Included library #include "HD44780_LCD_PCF8574.h" @@ -20,19 +24,9 @@ #define DISPLAY_DELAY_1 1000 #define DISPLAY_DELAY_2 2000 #define DISPLAY_DELAY 5000 -// **** NOTE :: Comment in If using STM32 bluepill **** -//#define STM32_BLUE_PILL_SETUP // Section: Globals -#ifdef STM32_BLUE_PILL_SETUP // *** STM32 Blue Pill *** -// Set-up Choice I2C interface 1 or 2 :: pick one and one only -TwoWire Wire2(1,I2C_FAST_MODE); // Use STM32 I2C1 -//TwoWire Wire2(2,I2C_FAST_MODE); // Use STM32 I2C2 -HD44780LCD myLCD(4, 20, 0x27, &Wire2); // LCD object.rows ,cols ,PCF8574 I2C addr, Interface) -#else -// myLCD(rows , cols , PCF8574 I2C address) -HD44780LCD myLCD( 4, 20, 0x27); // instantiate an object -#endif +HD44780LCD myLCD( 4, 20, 0x27, &Wire); // instantiate an object // Section: Function Prototypes @@ -52,7 +46,7 @@ void endTest(void); void setup() { delay(50); - myLCD.PCF8574_LCDInit(LCDCursorTypeOn); + myLCD.PCF8574_LCDInit(myLCD.LCDCursorTypeOn); myLCD.PCF8574_LCDClearScreen(); myLCD.PCF8574_LCDBackLightSet(true); @@ -67,12 +61,10 @@ void loop() { scrollTest(); gotoTest(); clearLineTest(); - cursorTest(); // Cursor type and screen reset test(4 off ) check, - // cursor mode is changed by calling reset. - entryModeTest(); // Text entry mode (4 off ) Note: if screen is reset - // non default entry mode setting will also be reset - writeNumTest(); // Print numerical data using print() test - customChar(); // Custom character from CGRAM test + cursorTest(); + entryModeTest(); + writeNumTest(); + customChar(); backLightTest(); } // End of Main @@ -81,26 +73,26 @@ void loop() { void helloWorld(void) { char teststr1[] = "Hello"; char teststr2[] = "World"; - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo, 0); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo, 0); myLCD.PCF8574_LCDSendString(teststr1); - myLCD.PCF8574_LCDGOTO(LCDLineNumberThree , 0); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberThree , 0); myLCD.PCF8574_LCDSendString(teststr2); // Display a string myLCD.PCF8574_LCDSendChar('!'); // Display a single character delay(DISPLAY_DELAY_1); } void cursorMoveTest(void) { - myLCD.PCF8574_LCDMoveCursor(LCDMoveRight, 2); + myLCD.PCF8574_LCDMoveCursor(myLCD.LCDMoveRight, 2); delay(DISPLAY_DELAY); - myLCD.PCF8574_LCDMoveCursor(LCDMoveLeft, 2); + myLCD.PCF8574_LCDMoveCursor(myLCD.LCDMoveLeft, 2); } void scrollTest(void) { for (uint8_t i = 0; i < 10; i++) { - myLCD.PCF8574_LCDScroll(LCDMoveRight, 1); + myLCD.PCF8574_LCDScroll(myLCD.LCDMoveRight, 1); delay(DISPLAY_DELAY_2); } - myLCD.PCF8574_LCDScroll(LCDMoveLeft, 10); + myLCD.PCF8574_LCDScroll(myLCD.LCDMoveLeft, 10); delay(DISPLAY_DELAY_2); } @@ -116,13 +108,13 @@ void gotoTest(void) { // Print a string to each line - myLCD.PCF8574_LCDGOTO(LCDLineNumberOne, 0); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberOne, 0); myLCD.PCF8574_LCDSendString(teststr1); - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo , 0); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo , 0); myLCD.PCF8574_LCDSendString(teststr2); - myLCD.PCF8574_LCDGOTO(LCDLineNumberThree , 0); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberThree , 0); myLCD.PCF8574_LCDSendString(teststr3); - myLCD.PCF8574_LCDGOTO(LCDLineNumberFour , 0); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberFour , 0); myLCD.PCF8574_LCDSendString(teststr4); delay(DISPLAY_DELAY); @@ -132,28 +124,28 @@ void gotoTest(void) { // with a unique goto command for (columnPos = 0 ; columnPos <20 ; columnPos++) { - myLCD.PCF8574_LCDGOTO(LCDLineNumberOne, columnPos); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberOne, columnPos); myLCD.PCF8574_LCDSendChar(testchar++); } //Line 1 delay(DISPLAY_DELAY_1); for (columnPos = 0 ; columnPos <20 ; columnPos++) { - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo, columnPos); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo, columnPos); myLCD.PCF8574_LCDSendChar(testchar++); } //Line 2 delay(DISPLAY_DELAY_1); for (columnPos = 0 ; columnPos <20 ; columnPos++) { - myLCD.PCF8574_LCDGOTO(LCDLineNumberThree, columnPos); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberThree, columnPos); myLCD.PCF8574_LCDSendChar(testchar++); } //Line 3 delay(DISPLAY_DELAY_1); for (columnPos = 0 ; columnPos <20 ; columnPos++) { - myLCD.PCF8574_LCDGOTO(LCDLineNumberFour, columnPos); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberFour, columnPos); myLCD.PCF8574_LCDSendChar(testchar++); } // Line 4 delay(DISPLAY_DELAY); @@ -161,13 +153,13 @@ void gotoTest(void) { void clearLineTest(void) { - myLCD.PCF8574_LCDClearLine(LCDLineNumberOne); + myLCD.PCF8574_LCDClearLine(myLCD.LCDLineNumberOne); delay(DISPLAY_DELAY_2); - myLCD.PCF8574_LCDClearLine(LCDLineNumberTwo); + myLCD.PCF8574_LCDClearLine(myLCD.LCDLineNumberTwo); delay(DISPLAY_DELAY_2); - myLCD.PCF8574_LCDClearLine(LCDLineNumberThree); + myLCD.PCF8574_LCDClearLine(myLCD.LCDLineNumberThree); delay(DISPLAY_DELAY_2); - myLCD.PCF8574_LCDClearLine(LCDLineNumberFour); + myLCD.PCF8574_LCDClearLine(myLCD.LCDLineNumberFour); delay(DISPLAY_DELAY_2); } @@ -177,29 +169,29 @@ void cursorTest(void) { char teststr3[] = "Cursor no 2"; char teststr4[] = "Cursor no 3"; - myLCD.PCF8574_LCDResetScreen(LCDCursorTypeOnBlink); //type 4 cursor - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo, 0); + myLCD.PCF8574_LCDResetScreen(myLCD.LCDCursorTypeOnBlink); //type 4 cursor + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo, 0); myLCD.PCF8574_LCDSendString(teststr1); delay(DISPLAY_DELAY_2); - myLCD.PCF8574_LCDClearLine(LCDLineNumberTwo); + myLCD.PCF8574_LCDClearLine(myLCD.LCDLineNumberTwo); - myLCD.PCF8574_LCDResetScreen(LCDCursorTypeOff); //type 1 cursor - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo, 0); + myLCD.PCF8574_LCDResetScreen(myLCD.LCDCursorTypeOff); //type 1 cursor + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo, 0); myLCD.PCF8574_LCDSendString(teststr2); delay(DISPLAY_DELAY_2); - myLCD.PCF8574_LCDClearLine(LCDLineNumberTwo); + myLCD.PCF8574_LCDClearLine(myLCD.LCDLineNumberTwo); - myLCD.PCF8574_LCDResetScreen(LCDCursorTypeBlink); //type 2 cursor - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo, 0); + myLCD.PCF8574_LCDResetScreen(myLCD.LCDCursorTypeBlink); //type 2 cursor + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo, 0); myLCD.PCF8574_LCDSendString(teststr3); delay(DISPLAY_DELAY_2); - myLCD.PCF8574_LCDClearLine(LCDLineNumberTwo); + myLCD.PCF8574_LCDClearLine(myLCD.LCDLineNumberTwo); - myLCD.PCF8574_LCDResetScreen(LCDCursorTypeOn); // Back to initial state , type 3 - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo, 0); + myLCD.PCF8574_LCDResetScreen(myLCD.LCDCursorTypeOn); // Back to initial state , type 3 + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo, 0); myLCD.PCF8574_LCDSendString(teststr4); delay(DISPLAY_DELAY_2); - myLCD.PCF8574_LCDClearLine(LCDLineNumberTwo); + myLCD.PCF8574_LCDClearLine(myLCD.LCDLineNumberTwo); } void writeNumTest() @@ -208,23 +200,23 @@ void writeNumTest() int numNeg = -8582; double myPI = 3.1456; - myLCD.PCF8574_LCDGOTO(LCDLineNumberOne, 0); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberOne, 0); myLCD.print(numPos); - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo , 0); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo , 0); myLCD.print(numNeg); - myLCD.PCF8574_LCDMoveCursor(LCDMoveRight, 2); + myLCD.PCF8574_LCDMoveCursor(myLCD.LCDMoveRight, 2); myLCD.print(myPI,3); delay(DISPLAY_DELAY); myLCD.PCF8574_LCDClearScreen(); - myLCD.PCF8574_LCDGOTO(LCDLineNumberOne, 0); // 11 + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberOne, 0); // 11 myLCD.print(11); - myLCD.PCF8574_LCDMoveCursor(LCDMoveRight, 2); // 13 + myLCD.PCF8574_LCDMoveCursor(myLCD.LCDMoveRight, 2); // 13 myLCD.print(11,OCT); - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo , 0); // B + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo , 0); // B myLCD.print(11, HEX); - myLCD.PCF8574_LCDMoveCursor(LCDMoveRight, 2); // 1011 + myLCD.PCF8574_LCDMoveCursor(myLCD.LCDMoveRight, 2); // 1011 myLCD.print(11,BIN); delay(DISPLAY_DELAY); @@ -232,37 +224,33 @@ void writeNumTest() void customChar(void) { - // Data to test custom function - uint8_t bellChar[8] = {0x4, 0xe, 0xe, 0xe, 0x1f, 0x0, 0x4}; - uint8_t noteChar[8] = {0x2, 0x3, 0x2, 0xe, 0x1e, 0xc, 0x0}; - uint8_t clockChar[8] = {0x0, 0xe, 0x15, 0x17, 0x11, 0xe, 0x0}; - uint8_t heartChar[8] = {0x0, 0xa, 0x1f, 0x1f, 0xe, 0x4, 0x0}; - uint8_t duckChar[8] = {0x0, 0xc, 0x1d, 0xf, 0xf, 0x6, 0x0}; - uint8_t checkChar[8] = {0x0, 0x1, 0x3, 0x16, 0x1c, 0x8, 0x0}; - uint8_t crossChar[8] = {0x0, 0x1b, 0xe, 0x4, 0xe, 0x1b, 0x0}; - uint8_t enterChar[8] = {0x1, 0x1, 0x5, 0x9, 0x1f, 0x8, 0x4}; + uint8_t index = 0; // Character generator RAM location ,0-7 ,64 bytes + // custom characters data to test custom character function + uint8_t symbolData[8][8] = { + {0x04, 0x0E, 0x0E, 0x0E, 0x1F, 0x00, 0x04, 0x00}, // bell + {0x02, 0x03, 0x02, 0x0E, 0x1E, 0x0C, 0x00, 0x00}, // Note + {0x00, 0x0E, 0x15, 0x17, 0x11, 0x0E, 0x00, 0x00}, // clock + {0x00, 0x0C, 0x1D, 0x0F, 0x0F, 0x06, 0x00, 0x00}, // duck + {0x00, 0x01, 0x03, 0x16, 0x1C, 0x08, 0x00, 0x00}, // check + {0x00, 0x1B, 0x0E, 0x04, 0x0E, 0x1B, 0x00, 0x00}, // cross + {0x00, 0x0A, 0x1F, 0x1F, 0x0E, 0x04, 0x00, 0x00}, // heart + {0x01, 0x01, 0x05, 0x09, 0x1F, 0x08, 0x04, 0x00} // return arrow + }; myLCD.PCF8574_LCDClearScreen(); // Load the CGRAM with the data , custom characters - // location argument must be 0 to 7 - myLCD.PCF8574_LCDCreateCustomChar(0, bellChar); // Location 0 - myLCD.PCF8574_LCDCreateCustomChar(1, noteChar); - myLCD.PCF8574_LCDCreateCustomChar(2, clockChar); - myLCD.PCF8574_LCDCreateCustomChar(3, heartChar); - myLCD.PCF8574_LCDCreateCustomChar(4, duckChar); - myLCD.PCF8574_LCDCreateCustomChar(5, checkChar); - myLCD.PCF8574_LCDCreateCustomChar(6, crossChar); - myLCD.PCF8574_LCDCreateCustomChar(7, enterChar); // Location 7 - - myLCD.PCF8574_LCDGOTO(LCDLineNumberThree, 0); + // location argument must be 0 to 7 , load the data into LCD memory + for (uint8_t index = 0; index < 8; index++) { + myLCD.PCF8574_LCDCreateCustomChar(index , symbolData[index]); + } + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberOne, 0); // Print out custom characters from - // CGRAM locations 0-7 - // location argument must be 0 to 7 - for (uint8_t i = 0; i < 8; i++) { - myLCD.PCF8574_LCDPrintCustomChar(i); - myLCD.PCF8574_LCDMoveCursor(LCDMoveRight, 1); + // CGRAM locations 0-7 , location argument must be 0 to 7 + for (index = 0; index < 8; index ++) { + myLCD.PCF8574_LCDPrintCustomChar(index); + myLCD.PCF8574_LCDMoveCursor(myLCD.LCDMoveRight, 1); } delay(DISPLAY_DELAY); @@ -271,14 +259,15 @@ void customChar(void) { void backLightTest(void) { - char teststr4[] = "Back Light"; - // Needs another command/data before it changes Light - myLCD.PCF8574_LCDBackLightSet(false); + char teststr4[] = "Back Light : "; - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo , 1); + myLCD.PCF8574_LCDBackLightSet(false); // Needs another command/data before it changes Light + + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo , 1); myLCD.PCF8574_LCDSendString(teststr4); + myLCD.print(myLCD.PCF8574_LCDBackLightGet()); // read the backlight variable status delay(DISPLAY_DELAY); - myLCD.PCF8574_LCDBackLightSet(true); + myLCD.PCF8574_LCDBackLightSet(true); // Needs another command/data before it changes Light myLCD.PCF8574_LCDClearScreen(); } @@ -286,25 +275,25 @@ void entryModeTest(void) { char teststr8[] = "1234"; - myLCD.PCF8574_LCDChangeEntryMode(LCDEntryModeOne); - myLCD.PCF8574_LCDGOTO(LCDLineNumberOne, 8); + myLCD.PCF8574_LCDChangeEntryMode(myLCD.LCDEntryModeOne); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberOne, 8); myLCD.PCF8574_LCDSendString(teststr8); // <-C4321 delay(DISPLAY_DELAY_2); myLCD.PCF8574_LCDClearScreenCmd(); - myLCD.PCF8574_LCDChangeEntryMode(LCDEntryModeTwo); - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo, 8); + myLCD.PCF8574_LCDChangeEntryMode(myLCD.LCDEntryModeTwo); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo, 8); myLCD.PCF8574_LCDSendString(teststr8); // C4321-> delay(DISPLAY_DELAY_2); myLCD.PCF8574_LCDClearScreenCmd(); - myLCD.PCF8574_LCDChangeEntryMode(LCDEntryModeFour); - myLCD.PCF8574_LCDGOTO(LCDLineNumberTwo, 8); + myLCD.PCF8574_LCDChangeEntryMode(myLCD.LCDEntryModeFour); + myLCD.PCF8574_LCDGOTO(myLCD.LCDLineNumberTwo, 8); myLCD.PCF8574_LCDSendString(teststr8); // <-1234C delay(DISPLAY_DELAY_2); myLCD.PCF8574_LCDClearScreenCmd(); - myLCD.PCF8574_LCDChangeEntryMode(LCDEntryModeThree); // Set back to default entry mode + myLCD.PCF8574_LCDChangeEntryMode(myLCD.LCDEntryModeThree); // Set back to default entry mode myLCD.PCF8574_LCDClearScreenCmd(); delay(DISPLAY_DELAY_1); } diff --git a/extras/doc/CHANGELOG.md b/extras/doc/CHANGELOG.md index a335f77..d92aa0a 100644 --- a/extras/doc/CHANGELOG.md +++ b/extras/doc/CHANGELOG.md @@ -7,3 +7,11 @@ * Example file added for 20x04 * version 1.2.0 September 2022 * Option added for User to pick I2C port for STM32 bluepill, github issue 2. +* version 1.3.0 April 2023 + * Refactor and optimisations , enums are now part of the class + * Added STM32 "hello world" example file + * Added "Doxyen" style comments in order to use "Doxygen" software to automatically + generate a html based software API. + + + diff --git a/extras/doc/GPIO_MCU_used.md b/extras/doc/GPIO_MCU_used.md deleted file mode 100644 index 028a174..0000000 --- a/extras/doc/GPIO_MCU_used.md +++ /dev/null @@ -1,28 +0,0 @@ -GPIO used in testing for I2C --------------------------------------- - -UNO/NANO I2C - -1. A4 SDA -2. A5 SCLK - -ESP8266 HARDWARE I2C - -3. D1 GPIO5 20 SCK -4. D2 GPIO4 19 SDA - -ESP32 HARDWARE I2C - -5. D22 GPIO22 SCK -6. D21 GPIO21 SDA - -STM32 STM32F103C8T6 "blue pill" I2C - -| Pin Name | Pin | Arduino Pin | PCB Label | Func | I2C Channel | -| -- | -- | -- | -- | -- | -- | -| PB6 | 42 | 22 | B6 | SCK | I2C1 | -| PB7 | 43 | 23 | B7 | SDA | I2C1 | -| PB10 | 21 | 26 | B10 | SCK | I2C2 | -| PB11 | 22 | 27 | B11 | SDA | I2C2 | - - diff --git a/extras/doc/GPIO_MCU_used.txt b/extras/doc/GPIO_MCU_used.txt new file mode 100644 index 0000000..8e6a76d --- /dev/null +++ b/extras/doc/GPIO_MCU_used.txt @@ -0,0 +1,25 @@ +# GPIO used in testing for I2C + +UNO/NANO I2C +A4 SDA +A5 SCLK + +ESP8266 HARDWARE I2C +D1 GPIO5 20 SCK +D2 GPIO4 19 SDA + +ESP32 HARDWARE I2C +D22 GPIO22 SCK +D21 GPIO21 SDA + +STM32 STM32F103C8T6 "blue pill" I2C + +I2C port 1 +PB6 22 42 B6 SCK +PB7 23 43 B7 SDA + +I2C port 2 +PB10 21 26 B10 SCL2 +PB11 22 27 B11 SDA2 + + diff --git a/keywords.txt b/keywords.txt index 366830d..a8be9c0 100644 --- a/keywords.txt +++ b/keywords.txt @@ -11,6 +11,7 @@ PCF8574_LCDInit KEYWORD2 PCF8574_LCDDisplayON KEYWORD2 PCF8574_LCDResetScreen KEYWORD2 PCF8574_LCDBackLightSet KEYWORD2 +PCF8574_LCDBackLightGet KEYWORD2 PCF8574_LCD_I2C_ON KEYWORD2 PCF8574_LCDSendString KEYWORD2 PCF8574_LCDSendChar KEYWORD2 diff --git a/library.properties b/library.properties index e66b49a..3c91125 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=HD44780_LCD_PCF8574 -version=1.2.0 +version=1.3.0 author=Gavin Lyons maintainer=Gavin Lyons sentence=Library to Support the HD44780 LCD I2C driven by the PCF8574 controller diff --git a/src/HD44780_LCD_PCF8574.cpp b/src/HD44780_LCD_PCF8574.cpp index 8870e12..b36f6e8 100644 --- a/src/HD44780_LCD_PCF8574.cpp +++ b/src/HD44780_LCD_PCF8574.cpp @@ -1,105 +1,127 @@ +/*! + @file HD44780_LCD_PCF8574.cpp + @author Gavin Lyons + @brief HD44780-based character LCD 16x02 I2C(PCF8574) library Source file for arduino eco system +*/ -// Section : Includes +// Includes #include "HD44780_LCD_PCF8574.h" -// Section : constructor - -HD44780LCD :: HD44780LCD(uint8_t NumRow, uint8_t NumCol, uint8_t I2Caddress,TwoWire *twi) +/*! + @brief Constructor for class TM1638plus + @param NumRow Number of Rows/Lines in the LCD + @param NumCol Number of Columns in the LCD + @param I2Caddress The PCF8574 I2C address, default is 0x27. + @param twi Pointer to the Wire I2C interface. +*/ +HD44780LCD :: HD44780LCD(uint8_t NumRow, uint8_t NumCol, uint8_t I2Caddress, TwoWire *twi) { _NumRowsLCD = NumRow; _NumColsLCD = NumCol; _LCDSlaveAddresI2C = I2Caddress; - wire = twi; + wire = twi; } +// Methods -// Section : Functions - -// Func Desc: Send data byte to LCD via I2C -// Param1: data byte +/*! + @brief Send data byte to LCD via I2C + @param data The data byte to send + @note if LCD_SERIAL_DEBUG is defined , will output data on I2C failures. +*/ void HD44780LCD::PCF8574_LCDSendData(unsigned char data) { - unsigned char dataLower, dataUpper; - uint8_t dataI2C[4]; - uint8_t TransmissionCode = 0; + // I2C MASK Byte = DATA-led-en-rw-rs (en=enable rs = reg select)(rw always write) + const uint8_t LCDDataByteOn= 0x0D; //enable=1 and rs =1 1101 DATA-led-en-rw-rs + const uint8_t LCDDataByteOff = 0x09; // enable=0 and rs =1 1001 DATA-led-en-rw-rs + + unsigned char dataNibbleLower, dataNibbleUpper; + uint8_t dataBufferI2C[4]; + uint8_t I2CReturnCode = 0; - dataLower = (data << 4)&0xf0; //select lower nibble by moving it to the upper nibble position - dataUpper = data & 0xf0; //select upper nibble - dataI2C[0] = dataUpper | (LCD_DATA_BYTE_ON & _LCDBackLight); //enable=1 and rs =1 1101 YYYY-X-en-X-rs - dataI2C[1] = dataUpper | (LCD_DATA_BYTE_OFF & _LCDBackLight); //enable=0 and rs =1 1001 YYYY-X-en-X-rs - dataI2C[2] = dataLower | (LCD_DATA_BYTE_ON & _LCDBackLight); //enable=1 and rs =1 1101 YYYY-X-en-X-rs - dataI2C[3] = dataLower | (LCD_DATA_BYTE_OFF & _LCDBackLight); //enable=0 and rs =1 1001 YYYY-X-en-X-rs + dataNibbleLower = (data << 4)&0xf0; //select lower nibble by moving it to the upper nibble position + dataNibbleUpper = data & 0xf0; //select upper nibble + dataBufferI2C[0] = dataNibbleUpper | (LCDDataByteOn & _LCDBackLight); //enable=1 and rs =1 1101 YYYY-X-en-X-rs + dataBufferI2C[1] = dataNibbleUpper | (LCDDataByteOff & _LCDBackLight); //enable=0 and rs =1 1001 YYYY-X-en-X-rs + dataBufferI2C[2] = dataNibbleLower | (LCDDataByteOn & _LCDBackLight); //enable=1 and rs =1 1101 YYYY-X-en-X-rs + dataBufferI2C[3] = dataNibbleLower | (LCDDataByteOff & _LCDBackLight); //enable=0 and rs =1 1001 YYYY-X-en-X-rs wire->beginTransmission(_LCDSlaveAddresI2C); - wire->write(dataI2C, 4) ; - TransmissionCode = wire->endTransmission(); - if (TransmissionCode!= 0) + wire->write(dataBufferI2C, 4) ; + I2CReturnCode = wire->endTransmission(); + if (I2CReturnCode!= 0) { #ifdef LCD_SERIAL_DEBUG Serial.print("1203 : "); Serial.print("I2C error wire.endTransmission : "); - Serial.print("Tranmission code : "); - Serial.println(TransmissionCode); + Serial.print("I2CReturnCode code : "); + Serial.println(I2CReturnCode); delay(100); #endif } } -// Func Desc: Send command byte to lcd -// Param1: command byte - +/*! + @brief Send command byte to lcd + @param cmd command byte + @note if LCD_SERIAL_DEBUG is defined will output data on I2C failures +*/ void HD44780LCD::PCF8574_LCDSendCmd(unsigned char cmd) { - unsigned char cmdLower, cmdupper; - uint8_t cmdI2C[4]; - uint8_t TransmissionCode = 0; - cmdLower = (cmd << 4)&0xf0; //select lower nibble by moving it to the upper nibble position - cmdupper = cmd & 0xf0; //select upper nibble - cmdI2C[0] = cmdupper | (LCD_CMD_BYTE_ON & _LCDBackLight); // YYYY-1100 YYYY-led-en-rw-rs ,enable=1 and rs =0 - cmdI2C[1] = cmdupper | (LCD_CMD_BYTE_OFF & _LCDBackLight); // YYYY-1000 YYYY-led-en-rw-rs ,enable=0 and rs =0 - cmdI2C[2] = cmdLower | (LCD_CMD_BYTE_ON & _LCDBackLight); // YYYY-1100 YYYY-led-en-rw-rs ,enable=1 and rs =0 - cmdI2C[3] = cmdLower | (LCD_CMD_BYTE_OFF & _LCDBackLight); // YYYY-1000 YYYY-led-en-rw-rs ,enable=0 and rs =0 + // I2C MASK Byte = COMD-led-en-rw-rs (en=enable rs = reg select)(rw always write) + const uint8_t LCDCmdByteOn = 0x0C; // enable=1 and rs =0 1100 COMD-led-en-rw-rs + const uint8_t LCDCmdByteOff = 0x08; // enable=0 and rs =0 1000 COMD-led-en-rw-rs + + unsigned char cmdNibbleLower, cmdNibbleUpper; + uint8_t cmdBufferI2C[4]; + uint8_t I2CReturnCode = 0; + + cmdNibbleLower = (cmd << 4)&0xf0; //select lower nibble by moving it to the upper nibble position + cmdNibbleUpper = cmd & 0xf0; //select upper nibble + cmdBufferI2C[0] = cmdNibbleUpper | (LCDCmdByteOn & _LCDBackLight); // YYYY-1100 YYYY-led-en-rw-rs ,enable=1 and rs =0 + cmdBufferI2C[1] = cmdNibbleUpper | (LCDCmdByteOff & _LCDBackLight); // YYYY-1000 YYYY-led-en-rw-rs ,enable=0 and rs =0 + cmdBufferI2C[2] = cmdNibbleLower | (LCDCmdByteOn & _LCDBackLight); // YYYY-1100 YYYY-led-en-rw-rs ,enable=1 and rs =0 + cmdBufferI2C[3] = cmdNibbleLower | (LCDCmdByteOff & _LCDBackLight); // YYYY-1000 YYYY-led-en-rw-rs ,enable=0 and rs =0 wire->beginTransmission(_LCDSlaveAddresI2C); - wire->write(cmdI2C, 4) ; - TransmissionCode = wire->endTransmission(); - if (TransmissionCode!= 0) + wire->write(cmdBufferI2C, 4) ; + I2CReturnCode = wire->endTransmission(); + if (I2CReturnCode != 0) { #ifdef LCD_SERIAL_DEBUG Serial.print("1202 : "); Serial.print("I2C error wire.endTransmission : "); - Serial.print("Tranmission code : "); - Serial.println(TransmissionCode); + Serial.print("I2CReturnCode: "); + Serial.println(I2CReturnCode); delay(100); #endif } } -// Func Desc: Clear a line by writing spaces to every position -// Param1: enum LCDLineNumber_e lineNo 1-4 - +/*! + @brief Clear a line by writing spaces to every position + @param lineNo LCDLineNumber_e enum lineNo 1-4 +*/ void HD44780LCD::PCF8574_LCDClearLine(LCDLineNumber_e lineNo) { switch (lineNo) { - case LCDLineNumberOne: - PCF8574_LCDSendCmd(LCD_LINE_ADR1); - break; - case LCDLineNumberTwo: - PCF8574_LCDSendCmd(LCD_LINE_ADR2); - break; + case LCDLineNumberOne:PCF8574_LCDSendCmd(LCDLineAddressOne); break; + case LCDLineNumberTwo:PCF8574_LCDSendCmd(LCDLineAddressTwo); break; case LCDLineNumberThree: - if (_NumColsLCD == 20) - PCF8574_LCDSendCmd(LCD_LINE_ADR3_20); - else - PCF8574_LCDSendCmd(LCD_LINE_ADR3_16); - break; + switch (_NumColsLCD) + { + case 16: PCF8574_LCDSendCmd(LCDLineAddress3Col16); break; + case 20: PCF8574_LCDSendCmd(LCDLineAddress3Col20); break; + } + break; case LCDLineNumberFour: - if (_NumColsLCD == 20) - PCF8574_LCDSendCmd(LCD_LINE_ADR4_20); - else - PCF8574_LCDSendCmd(LCD_LINE_ADR4_16); - break; + switch (_NumColsLCD) + { + case 16: PCF8574_LCDSendCmd(LCDLineAddress4Col16); break; + case 20: PCF8574_LCDSendCmd(LCDLineAddress4Col20); break; + } + break; } for (uint8_t i = 0; i < _NumColsLCD; i++) { @@ -107,14 +129,12 @@ void HD44780LCD::PCF8574_LCDClearLine(LCDLineNumber_e lineNo) { } } -// Func Desc: Clear screen by writing spaces to every position -// Note : See also LCDClearScreenCmd for software command clear alternative. - +/*! + @brief Clear screen by writing spaces to every position + @note : See also LCDClearScreenCmd for software command clear alternative. +*/ void HD44780LCD::PCF8574_LCDClearScreen(void) { - if (_NumRowsLCD < 1 || _NumRowsLCD >4) - { - return; - } + if (_NumRowsLCD < 1 || _NumRowsLCD >4){return;} PCF8574_LCDClearLine(LCDLineNumberOne); @@ -126,33 +146,34 @@ void HD44780LCD::PCF8574_LCDClearScreen(void) { PCF8574_LCDClearLine(LCDLineNumberFour); } - -// Func Desc: Reset screen -// Param1: enum LCDCursorType_e cursor type, 4 choices - +/*! + @brief Reset screen + @param CursorType LCDCursorType_e enum cursor type, 4 choices +*/ void HD44780LCD::PCF8574_LCDResetScreen(LCDCursorType_e CursorType) { - PCF8574_LCDSendCmd(LCD_MODE_4BIT); - PCF8574_LCDSendCmd(LCD_DISPLAY_ON); + PCF8574_LCDSendCmd(LCDModeFourBit); + PCF8574_LCDSendCmd(LCDDisplayOn); PCF8574_LCDSendCmd(CursorType); - PCF8574_LCDSendCmd(LCD_CLRSCR); + PCF8574_LCDSendCmd(LCDClearScreen); PCF8574_LCDSendCmd(LCDEntryModeThree); delay(5); } - -// Func Desc: Turn Screen on and off -// Param1: passed bool, True = display on , false = display off - +/*! + @brief Turn Screen on and off + @param OnOff True = display on , false = display off +*/ void HD44780LCD::PCF8574_LCDDisplayON(bool OnOff) { - OnOff ? PCF8574_LCDSendCmd(LCD_DISPLAY_ON) : PCF8574_LCDSendCmd(LCD_DISPLAY_OFF); + OnOff ? PCF8574_LCDSendCmd(LCDDisplayOn) : PCF8574_LCDSendCmd(LCDDisplayOff); delay(5); } -// Func Desc: Initialise LCD -// Param1: enum LCDCursorType_e cursor type, 4 choices. - -void HD44780LCD::PCF8574_LCDInit(LCDCursorType_e CursorType) { +/*! + @brief Initialise LCD + @param cursorType 4 choices. +*/ +void HD44780LCD::PCF8574_LCDInit(LCDCursorType_e cursorType) { if (PCF8574_LCD_I2C_ON() != true) { @@ -161,142 +182,178 @@ void HD44780LCD::PCF8574_LCDInit(LCDCursorType_e CursorType) { } delay(15); - PCF8574_LCDSendCmd(LCD_HOME); + PCF8574_LCDSendCmd(LCDHomePosition); delay(5); - PCF8574_LCDSendCmd(LCD_HOME); + PCF8574_LCDSendCmd(LCDHomePosition); delay(5); - PCF8574_LCDSendCmd(LCD_HOME); + PCF8574_LCDSendCmd(LCDHomePosition); delay(5); - PCF8574_LCDSendCmd(LCD_MODE_4BIT); - PCF8574_LCDSendCmd(LCD_DISPLAY_ON); - PCF8574_LCDSendCmd(CursorType); + PCF8574_LCDSendCmd(LCDModeFourBit); + PCF8574_LCDSendCmd(LCDDisplayOn); + PCF8574_LCDSendCmd(cursorType); PCF8574_LCDSendCmd(LCDEntryModeThree); - PCF8574_LCDSendCmd(LCD_CLRSCR); + PCF8574_LCDSendCmd(LCDClearScreen); delay(5); } -// Func Desc: Send string to LCD -// Param1: Pointer to the char array - +/*! + @brief Send a string to LCD + @param str Pointer to the char array +*/ void HD44780LCD::PCF8574_LCDSendString(char *str) { while (*str) PCF8574_LCDSendData(*str++); } - -// Func Desc: Sends a character to screen , simply wraps SendData command. -// Param1: Character to display +/*! + @brief Sends a character to screen , simply wraps SendData command. + @param data Character to display +*/ void HD44780LCD::PCF8574_LCDSendChar(char data) { PCF8574_LCDSendData(data); } -// Func Desc: Moves cursor -// Param1. enum LCDDirectionType_e left or right -// Param2. uint8_t number of spaces to move - +/*! + @brief Moves cursor + @param direction enum LCDDirectionType_e left or right + @param moveSize number of spaces to move +*/ void HD44780LCD::PCF8574_LCDMoveCursor(LCDDirectionType_e direction, uint8_t moveSize) { uint8_t i = 0; - if (direction == LCDMoveRight) { + const uint8_t LCDMoveCursorLeft = 0x10; //Command Byte Code: Move cursor one character left + const uint8_t LCDMoveCursorRight = 0x14; // Command Byte Code : Move cursor one character right + switch(direction) + { + case LCDMoveRight: for (i = 0; i < moveSize; i++) { - PCF8574_LCDSendCmd(LCD_MOV_CURSOR_RIGHT); + PCF8574_LCDSendCmd(LCDMoveCursorRight); } - } else { + break; + case LCDMoveLeft: for (i = 0; i < moveSize; i++) { - PCF8574_LCDSendCmd(LCD_MOV_CURSOR_LEFT); + PCF8574_LCDSendCmd(LCDMoveCursorLeft); } + break; } } -// Func Desc: Scrolls screen -// Param1. enum LCDDirectionType_e , left or right -// Param2. uint8_t number of spaces to scroll - +/*! + @brief Scrolls screen + @param direction left or right + @param ScrollSize number of spaces to scroll +*/ void HD44780LCD::PCF8574_LCDScroll(LCDDirectionType_e direction, uint8_t ScrollSize) { uint8_t i = 0; - if (direction == LCDMoveRight) { + + const uint8_t LCDScrollRight = 0x1E; // Command Byte Code: Scroll display one character right (all lines) + const uint8_t LCDScrollLeft = 0x18; //Command Byte Code: Scroll display one character left (all lines) + + switch(direction) + { + case LCDMoveRight: for (i = 0; i < ScrollSize; i++) { - PCF8574_LCDSendCmd(LCD_SCROLL_RIGHT); + PCF8574_LCDSendCmd(LCDScrollRight); } - } else { + break; + case LCDMoveLeft: for (i = 0; i < ScrollSize; i++) { - PCF8574_LCDSendCmd(LCD_SCROLL_LEFT); + PCF8574_LCDSendCmd(LCDScrollLeft); } + break; } - } -// Func Desc: moves cursor to an x , y position on display. -// Param1: enum LCDLineNumber_e row 1-4 -// Param2: uint8_t col 0-15 + +/*! + @brief moves cursor to an x , y position on display. + @param line x row 1-4 + @param col y column 0-15 or 0-19 +*/ void HD44780LCD::PCF8574_LCDGOTO(LCDLineNumber_e line, uint8_t col) { switch (line) { - case LCDLineNumberOne: - PCF8574_LCDSendCmd(LCD_LINE_ADR1 | col); - break; - case LCDLineNumberTwo: - PCF8574_LCDSendCmd(LCD_LINE_ADR2 | col); - break; + case LCDLineNumberOne: PCF8574_LCDSendCmd(LCDLineAddressOne| col); break; + case LCDLineNumberTwo: PCF8574_LCDSendCmd(LCDLineAddressTwo | col); break; case LCDLineNumberThree: - if (_NumColsLCD == 20) - PCF8574_LCDSendCmd(LCD_LINE_ADR3_20 + col); - else - PCF8574_LCDSendCmd(LCD_LINE_ADR3_16 | col); - break; + switch (_NumColsLCD) + { + case 16: PCF8574_LCDSendCmd(LCDLineAddress3Col16 | col); break; + case 20: PCF8574_LCDSendCmd(LCDLineAddress3Col20 + col); break; + } + break; case LCDLineNumberFour: - if (_NumColsLCD == 20) - PCF8574_LCDSendCmd(LCD_LINE_ADR4_20 + col); - else - PCF8574_LCDSendCmd(LCD_LINE_ADR4_16 | col); - ; - break; + switch (_NumColsLCD) + { + case 16: PCF8574_LCDSendCmd(LCDLineAddress4Col16 | col); break; + case 20: PCF8574_LCDSendCmd(LCDLineAddress4Col20+ col); break; + } + break; } } -// Func Desc: Saves a custom character to a location in CG_RAM -// Param1: CG_RAM location 0-7 we only have 8 locations 0-7 -// Param2: An array of 8 bytes representing a custom character data +/*! + @brief Saves a custom character to a location in character generator RAM 64 bytes. + @param location CG_RAM location 0-7, we only have 8 locations 64 bytes + @param charmap An array of 8 bytes representing a custom character data +*/ void HD44780LCD::PCF8574_LCDCreateCustomChar(uint8_t location, uint8_t * charmap) { + + const uint8_t LCD_CG_RAM = 0x40; // character-generator RAM (CG RAM address) if (location >= 8) {return;} + PCF8574_LCDSendCmd(LCD_CG_RAM | (location<<3)); for (uint8_t i=0; i<8; i++) { PCF8574_LCDSendData(charmap[i]); } } -// Func Desc: Turn LED backlight on and off -// Param1: passed bool True = LED on , false = display LED off -// Note: another data or command must be issued before it takes effect. +/*! + @brief Turn LED backlight on and off + @param OnOff passed bool True = LED on , false = display LED off + @note another data or command must be issued before it takes effect. +*/ void HD44780LCD::PCF8574_LCDBackLightSet(bool OnOff) { - OnOff ? (_LCDBackLight= LCD_BACKLIGHTON_MASK) : (_LCDBackLight= LCD_BACKLIGHTOFF_MASK); + OnOff ? (_LCDBackLight= LCDBackLightOnMask) : (_LCDBackLight= LCDBackLightOffMask); } +/*! + @brief get the backlight flag status + @return the status of backlight on or off , true or false. +*/ +bool HD44780LCD::PCF8574_LCDBackLightGet(void) +{ + switch(_LCDBackLight){ + case LCDBackLightOnMask : return true; break; + case LCDBackLightOffMask: return false; break; + default : return true ; break ; + } +} -// Func Desc: Setup I2C settings -// Returns false if PCF8574 fails to appear on I2C bus -// Returns true if ok -// Note if LCD_SERIAL_DEBUG enabled will print I2C error code to screen -// wire.endTransmission() return: -// 0 : Success -// 1 : Data length error -// 2 : NACK on transmit of the address. -// 3 : NACK on transmit of the data. -// 4 : Some other error +/*! + @brief Switch on the I2C + @returns false if PCF8574 fails to appear on I2C bus , true if ok + @note if LCD_SERIAL_DEBUG enabled will print I2C error code to screen + wire.endTransmission() return: + 0 : Success + 1 : Data length error + 2 : NACK on transmit of the address. + 3 : NACK on transmit of the data. + 4 : Some other error +*/ bool HD44780LCD::PCF8574_LCD_I2C_ON() { - uint8_t TransmissionCode = 0; + uint8_t I2CReturnCode= 0; wire->begin(); - //Wire.setClock(100000UL); // V 1.2.0 wire->beginTransmission(_LCDSlaveAddresI2C); - TransmissionCode = wire->endTransmission(); - if (TransmissionCode!= 0) + I2CReturnCode = wire->endTransmission(); + if (I2CReturnCode!= 0) { #ifdef LCD_SERIAL_DEBUG Serial.print("1201 : "); Serial.print("I2C error wire.endTransmission : "); - Serial.print("Tranmission code : "); - Serial.println(TransmissionCode); + Serial.print("I2CReturnCode: "); + Serial.println(I2CReturnCode); #endif return false; //Check if the PCF8574 is connected }else{ @@ -307,40 +364,49 @@ bool HD44780LCD::PCF8574_LCD_I2C_ON() } } - -// Print out a customer character from CGRAM -// Param1 CGRAM location 0-7 +/*! + @brief Print out a customer character from character generator CGRAM 64 bytes 8 characters + @param location CGRAM 0-7 +*/ void HD44780LCD::PCF8574_LCDPrintCustomChar(uint8_t location) { if (location >= 8) {return;} PCF8574_LCDSendData(location); } -// Called by print class, used to print out numerical data types etc -size_t HD44780LCD::write(uint8_t c) +/*! + @brief Called by print class, used to print out numerical data types etc + @param character write a character + @note used internally. Called by the print method using virtual +*/ +size_t HD44780LCD::write(uint8_t character) { - PCF8574_LCDSendChar(c) ; + PCF8574_LCDSendChar(character) ; return 1; } -// Clear display using software command , set cursor position to zero -// See also LCDClearScreen for manual clear - +/*! + @brief Clear display using software command , set cursor position to zero + @note See also LCDClearScreen for manual clear + */ void HD44780LCD::PCF8574_LCDClearScreenCmd(void) { - PCF8574_LCDSendCmd(LCD_CLRSCR); + PCF8574_LCDSendCmd(LCDClearScreen); delay(3); // Requires a delay } -// Set Cursor position to zero +/*! + @brief Set cursor position to home position . + */ void HD44780LCD::PCF8574_LCDHome(void) { - PCF8574_LCDSendCmd(LCD_HOME); + PCF8574_LCDSendCmd(LCDHomePosition); delay(3); // Requires a delay } -// Change entry mode -// Param1 enum LCDEntryMode_e 1-4 , 4 choices. - +/*! + @brief Change entry mode + @param newEntryMode 1-4 , 4 choices. + */ void HD44780LCD::PCF8574_LCDChangeEntryMode(LCDEntryMode_e newEntryMode) { PCF8574_LCDSendCmd(newEntryMode); diff --git a/src/HD44780_LCD_PCF8574.h b/src/HD44780_LCD_PCF8574.h index ce1087e..fcb6cff 100644 --- a/src/HD44780_LCD_PCF8574.h +++ b/src/HD44780_LCD_PCF8574.h @@ -1,12 +1,10 @@ -/* - * File: HD44780_LCD_PCF8574.h - * Description: - * HD44780-based character LCD 16x02 I2C(PCF8574) library header file for arduino eco system - * Author: Gavin Lyons. - * Created : March 2022 - * Description: See URL for full details. - * URL: https://github.com/gavinlyonsrepo/HD44780_LCD_PCF8574 - */ +/*! + @file HD44780_LCD_PCF8574.h + @author Gavin Lyons + @brief HD44780-based character LCD 16x02 I2C(PCF8574) library header file for arduino eco system + URL: https://github.com/gavinlyonsrepo/HD44780_LCD_PCF8574 +*/ + #if ARDUINO >= 100 #include "Arduino.h" @@ -17,95 +15,73 @@ #include "Wire.h" - #ifndef LCD_HD44780_H #define LCD_HD44780_H -// Section: Defines - -//#define LCD_SERIAL_DEBUG // comment in for serial debug I2C errors - -// Command Byte Codes See URL : dinceraydin.com/lcd/commands.htm for HD44780 CMDs - -#define LCD_MODE_8BIT 0x38 // Function set (8-bit interface, 2 lines, 5*7 Pixels) -#define LCD_MODE_4BIT 0x28 // Function set (4-bit interface, 2 lines, 5*7 Pixels) - -#define LCD_SCROLL_RIGHT 0x1E // Scroll display one character right (all lines) -#define LCD_SCROLL_LEFT 0x18 // Scroll display one character left (all lines) -#define LCD_HOME 0x02 // Home (move cursor to top/left character position) - -#define LCD_MOV_CURSOR_LEFT 0x10 // Move cursor one character left -#define LCD_MOV_CURSOR_RIGHT 0x14 //Move cursor one character right - -#define LCD_DISPLAY_ON 0x0C // Restore the display (with cursor hidden) -#define LCD_DISPLAY_OFF 0x08 // Blank the display (without clearing) -#define LCD_CLRSCR 0x01 // clear screen - -#define LCD_LINE_ADR1 0x80 // Set cursor position (DDRAM address) 80+ addr -#define LCD_LINE_ADR2 0xC0 // Set cursor position line 2 (DDRAM address) C0+ addr -#define LCD_LINE_ADR3_20 0x94 // line 3 untested, no part, for 20x04 -#define LCD_LINE_ADR4_20 0xD4 // line 4 untested, no part, for 20x04 -#define LCD_LINE_ADR3_16 0x90 // line 3 untested, no part, for 16x04 -#define LCD_LINE_ADR4_16 0xD0 // line 4 untested, no part, for 16x04 -#define LCD_CG_RAM 0x40 //Set pointer in character-generator RAM (CG RAM address) - -// Codes for I2C byte, -// Byte = DATA-led-en-rw-rs (en=enable rs = reg select)(led always on rw always write) -#define LCD_DATA_BYTE_ON 0x0D //enable=1 and rs =1 1101 DATA-led-en-rw-rs -#define LCD_DATA_BYTE_OFF 0x09 // enable=0 and rs =1 1001 DATA-led-en-rw-rs -#define LCD_CMD_BYTE_ON 0x0C // enable=1 and rs =0 1100 COMD-led-en-rw-rs -#define LCD_CMD_BYTE_OFF 0x08 // enable=0 and rs =0 1000 COMD-led-en-rw-rs -#define LCD_BACKLIGHTON_MASK 0x0F // XXXX-1111 , XXXX = don't care -#define LCD_BACKLIGHTOFF_MASK 0x07 // XXXX-0111 - -// Section :: enums - -typedef enum { - LCDEntryModeOne = 0x04, // Display Shift :OFF Decrement Address Counter - LCDEntryModeTwo = 0x05, // Display Shift :ON Decrement Address Counter - LCDEntryModeThree = 0x06, // Display Shift :OFF Increment Address Counter, default - LCDEntryModeFour = 0x07, // Display Shift :ON Increment Address Counter -} LCDEntryMode_e; // Entry mode set command - -typedef enum -{ - LCDCursorTypeOff= 0x0C, // Make cursor invisible - LCDCursorTypeBlink = 0x0D, // Turn on blinking-block cursor - LCDCursorTypeOn = 0x0E, // Turn on visible underline cursor - LCDCursorTypeOnBlink = 0x0F, // Turn on blinking-block cursor + visible underline cursor -}LCDCursorType_e; // Cursor mode - -typedef enum -{ - LCDMoveRight= 1, // move right - LCDMoveLeft = 2, // move left -}LCDDirectionType_e; // Direction mode for scroll and move - -typedef enum { - LCDLineNumberOne = 1, // row 1 - LCDLineNumberTwo = 2, // row 2 - LCDLineNumberThree = 3, // row 3 - LCDLineNumberFour = 4, // row 4 -} LCDLineNumber_e; // line number - - -// Section: Class's - -class HD44780LCD : public Print{ - public: - HD44780LCD(uint8_t NumRow, uint8_t NumCol, uint8_t I2Caddress, TwoWire *twi = &Wire); +//#define LCD_SERIAL_DEBUG // Comment in for serial debug I2C errors, set baud rate externally. + +/*! + @brief Class for HD44780 LCD +*/ +class HD44780LCD : public Print{ +public: + + // public enums + + /*! Backlight Control , Command Byte Code */ + enum LCDBackLight_e : uint8_t{ + LCDBackLightOnMask = 0x0F, /**< XXXX-1111 , Turn on Back light */ + LCDBackLightOffMask = 0x07 /**< XXXX-0111, Turn off Back light */ + }; + + /*! Entry mode control set command, Command Byte Code */ + enum LCDEntryMode_e : uint8_t{ + LCDEntryModeOne = 0x04, /**< Display Shift :OFF Decrement Address Counter */ + LCDEntryModeTwo = 0x05, /**< Display Shift :ON Decrement Address Counter */ + LCDEntryModeThree = 0x06, /**< Display Shift :OFF Increment Address Counter, default */ + LCDEntryModeFour = 0x07 /**< Display Shift :ON Increment Address Counter */ + }; + + /*! Cursor mode, Command Byte Code */ + enum LCDCursorType_e : uint8_t { + LCDCursorTypeOff= 0x0C, /**< Make cursor invisible */ + LCDCursorTypeBlink = 0x0D, /**< Turn on blinking-block cursor */ + LCDCursorTypeOn = 0x0E, /**< Turn on visible underline cursor */ + LCDCursorTypeOnBlink = 0x0F /**