Skip to content

Commit

Permalink
v 1.3.2
Browse files Browse the repository at this point in the history
  • Loading branch information
gavinlyonsrepo committed Dec 27, 2023
1 parent a513d20 commit 9490694
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 31 deletions.
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,28 +34,27 @@
* Author: Gavin Lyons
* Development Tool chain.
1. Raspberry PI 3 model b
2. C++, g++ (Raspbian 8.3.0-6+rpi1) 8.3.0
3. Raspbian 10 Buster OS, armv7l Linux 5.10.63-v7+ , 32 bit.
4. bcm2835 Library 1.73 (dependency)
2. C++, g++ (Debian 12.2.0)
3. Raspbian , Debian 12 bookworm OS, , 64 bit.
3. kernel : aarch64 Linux 6.1.0-rpi7-rpi-v8
4. bcm2835 Library 1.73 dependency. Provides low level I2C bus, delays and GPIO control.


## Installation

1. Make sure I2C bus is enabled on your raspberry PI

2. Install the dependency bcm2835 Library if not installed (at time of writing latest version is 1.73.)
* The bcm2835 library is a dependency and provides low level I2C bus, delays and GPIO control.
1. Install the dependency bcm2835 Library if not installed (at time of writing latest version is 1.73.)
* Install the C libraries of bcm2835, [Installation instructions here](http://www.airspayce.com/mikem/bcm2835/)

3. Download the HD44780_LCD_RPI library
2. Download the HD44780_LCD_RPI library
* Open a Terminal in a folder where you want to download,build & test library
* Run following command to download from github.

```sh
curl -sL https://github.com/gavinlyonsrepo/HD44780_LCD_RPI/archive/1.3.2.tar.gz | tar xz
```

4. Run "make" to run the makefile in repo base folder to install library, it will be
3. Run "make" to run the makefile in repo base folder to install library, it will be
installed to usr/lib and usr/include

```sh
Expand All @@ -77,7 +76,7 @@ make
make run
```

2. There are 4 examples files.
2. There are 5 examples files.
To decide which one the makefile builds simply edit "SRC" variable at top of the makefile in examples folder.
in the "User SRC directory Option Section". Pick an example "SRC" directory path and ONE ONLY.
Comment out the rest and repeat: make & make run.
Expand All @@ -88,6 +87,7 @@ Comment out the rest and repeat: make & make run.
| src/TEST_16x02 | Carries out test sequence testing features | 16x02 |
| src/TEST_20x04 | Carries out test sequence testing features | 20x04 |
| src/CLOCK_16x02 | A basic clock Demo | 16x02 |
| src/TEST_I2C_16x02 | Check I2C connection | 16x02 |

## Hardware

Expand Down Expand Up @@ -130,8 +130,8 @@ User can turn on debug messages with LCDDebugSet method see example file.

### API

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. This API is for the Arduino source port. It is very similar
expect constructor, init and de-init I2C method's will be different.
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. *NOTE :: This API is for the Arduino source port*. It is very similar
expect constructor, I2C method's will be different.

[Software API Url Link](https://gavinlyonsrepo.github.io/misc/software_docs/HD44780_LCD_PCF8574/index.html)

Expand Down
1 change: 1 addition & 0 deletions examples/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ SRC=src/HELLO_16x02
#SRC=src/TEST_16x02
#SRC=src/TEST_20x04
#SRC=src/CLOCK_16x02
#SRC=src/TEST_I2C_16x02

# ************************************************

Expand Down
6 changes: 3 additions & 3 deletions examples/src/HELLO_16x02/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
@file main.cpp
@author Gavin Lyons
@brief
This file contains the "main" function for project, a set of test sequence
This file contains the "main" function for project, Hello world
to test the HD44780_LCD_RPI library
@note
Expand All @@ -17,7 +17,7 @@

// Section: Globals
// myLCD(rows , cols , PCF8574 I2C address, I2C speed)
HD44780PCF8574LCD myLCD(2, 16, 0x27, 148); // instantiate an object
HD44780PCF8574LCD myLCD(2, 16, 0x27, 0); // instantiate an object

// Section: Function Prototypes
bool setup(void);
Expand Down Expand Up @@ -52,7 +52,7 @@ bool setup(void) {
std::cout << "Error 1202: bcm2835_i2c_begin :Cannot start I2C, Running as root?" << std::endl;
return false;
}

myLCD.LCDDebugSet(false);
myLCD.LCD_I2C_SetSpeed();
myLCD.LCDInit(myLCD.LCDCursorTypeOn);
myLCD.LCDClearScreen();
Expand Down
95 changes: 95 additions & 0 deletions examples/src/TEST_I2C_16x02/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*!
@file main.cpp
@author Gavin Lyons
@brief
This file contains the "main" function for project, I2C test
to test the HD44780_LCD_RPI library
@note
-# Test 901 :: I2c Test
*/

// Section: Included library
#include <iostream>
#include <bcm2835.h>
#include "HD44780_LCD.hpp"


// Section: Globals
// myLCD(rows , cols , PCF8574 I2C address, I2C speed)
HD44780PCF8574LCD myLCD(2, 16, 0x27, 0); // instantiate an object

// Section: Function Prototypes
bool setup(void);
void helloWorld(void);
void endTest(void);

// Section: Main Loop
int main(int argc, char **argv)
{
if (!setup()) return -1;
helloWorld();
endTest();
return 0;
}

// Section : Functions

bool setup(void) {
std::cout << "LCD Test Begin" << std::endl;

// Check if Bcm28235 lib installed and print version.
if(!bcm2835_init())
{
std::cout << "Error 1201: init bcm2835 library , Is it installed ?" << std::endl;
return false;
}

// Turn on I2C bus (optionally it may already be on)
if (!myLCD.LCD_I2C_ON())
{
std::cout << "Error 1202: bcm2835_i2c_begin :Cannot start I2C, Running as root?" << std::endl;
return false;
}

bcm2835_delay(1000);
myLCD.LCDDebugSet(true); // Turn debug messages on
myLCD.LCD_I2C_SetSpeed();
if (myLCD.LCDCheckConnection() != 0)
{
std::cout << "Error 1203: bcm2835_i2c_begin :LCD not on bus?" << std::endl;
return false;
}

// print out library versions & flag status( Note optional)
std::cout << "bcm2835 library Version Number :" << bcm2835_version() << std::endl;
std::cout << "HD44780_LCD_RPI lib Version Num :" << myLCD.LCDVerNumGet() << std::endl;
std::cout << "Debug status is : " << (myLCD.LCDDebugGet() ? "On" : "Off") << std::endl ;
std::cout << "Backlight status is : " << (myLCD.LCDBackLightGet() ? "On" : "Off") << std::endl ;
std::cout << "I2C Debug Error : " << myLCD.LCDI2CErrorGet() << std::endl; // Print I2C error flag
std::cout << "I2C Error Timeout mS : " << myLCD.LCDI2CErrorTimeoutGet() << std::endl; // Print I2C Timeout

myLCD.LCDInit(myLCD.LCDCursorTypeOn);
myLCD.LCDClearScreen();
return true;
}

void helloWorld(void)
{
char testString[] = "I2C Test";
myLCD.LCDGOTO(myLCD.LCDLineNumberOne, 0);
myLCD.LCDSendString(testString);
bcm2835_delay(5000);
}


void endTest()
{
myLCD.LCDDisplayON(false); //Switch off display
myLCD.LCD_I2C_OFF(); // Switch off I2C , optional.
bcm2835_close(); // Close the library
std::cout << "LCD Test End" << std::endl ;
}

// *** EOF ***

7 changes: 7 additions & 0 deletions include/HD44780_LCD.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ class HD44780PCF8574LCD : public Print{
bool LCD_I2C_ON(void);
void LCD_I2C_SetSpeed(void);
void LCD_I2C_OFF(void);
int16_t LCDCheckConnection(void);
bool LCDI2CErrorGet(void);
uint16_t LCDI2CErrorTimeoutGet(void);
void LCDI2CErrorTimeoutSet(uint16_t);

void LCDSendString (char *str);
void LCDSendChar (char data);
Expand Down Expand Up @@ -125,6 +129,9 @@ class HD44780PCF8574LCD : public Print{
const uint8_t LCD_I2C_ADDRESS = 0x27; /**< Default I2C address for I2C module PCF8574 backpack on LCD */
uint8_t _LCDSlaveAddresI2C = LCD_I2C_ADDRESS ; /**< I2C address for I2C module PCF8574 backpack on LCD*/
uint16_t _LCDSpeedI2C = 0x00; /**< I2C speed default 0(100K) or BCM2835_I2C_CLOCK_DIVIDER enum values */
uint16_t _I2C_ErrorDelay = 100; /**<I2C delay in event of error in mS*/
uint16_t _I2C_Error = 0; /**< In event of I2C error holds bcm2835 I2C reason code */

uint8_t _NumRowsLCD = 2; /**< number of rows on LCD*/
uint8_t _NumColsLCD = 16; /**< number of columns on LCD*/

Expand Down
77 changes: 60 additions & 17 deletions src/HD44780_LCD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ void HD44780PCF8574LCD::LCDSendData(unsigned char data) {
const uint8_t LCDDataByteOff = 0x09; // enable=0 and rs =1 1001 DATA-led-en-rw-rs

unsigned char dataNibbleLower, dataNibbleUpper;
char dataBufferI2C[4];;
uint8_t attemptI2Cwrite = 0;
char dataBufferI2C[4];
uint8_t attemptI2Cwrite = 3;

dataNibbleLower = (data << 4)&0xf0; //select lower nibble by moving it to the upper nibble position
dataNibbleUpper = data & 0xf0; //select upper nibble
Expand All @@ -57,22 +57,23 @@ void HD44780PCF8574LCD::LCDSendData(unsigned char data) {
dataBufferI2C[3] = dataNibbleLower | (LCDDataByteOff & _LCDBackLight); //enable=0 and rs =1 1001 YYYY-X-en-X-rs

// bcm2835I2CReasonCodes , BCM2835_I2C_REASON_OK 0x00 = Success
uint8_t ReasonCodes = bcm2835_i2c_write(dataBufferI2C, 4);
uint8_t ReasonCodes = bcm2835_i2c_write(dataBufferI2C, 4);

// Error handling retransmit
while(ReasonCodes != 0)
{
if (_DebugON == true)
{
std::cout << "Error 601 I2C Data bcm2835I2CReasonCodes : " << +ReasonCodes << std::endl;
std::cout << "Attempt : " << +attemptI2Cwrite << std::endl;
attemptI2Cwrite++;
bcm2835_delay(100);
std::cout << "Attempt Count: " << +attemptI2Cwrite << std::endl;
}
bcm2835_delay(_I2C_ErrorDelay );
ReasonCodes = bcm2835_i2c_write(dataBufferI2C, 4); // retransmit
bcm2835_delay(25);
if (attemptI2Cwrite >= 3) break;
_I2C_Error = ReasonCodes;
attemptI2Cwrite--;
if (attemptI2Cwrite == 0) break;
}
_I2C_Error = ReasonCodes;
}

/*!
Expand All @@ -88,9 +89,10 @@ void HD44780PCF8574LCD::LCDSendCmd(unsigned char cmd) {
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;
char cmdBufferI2C[4];
uint8_t attemptI2Cwrite = 0;
uint8_t attemptI2Cwrite = 3;

cmdNibbleLower = (cmd << 4)&0xf0; //select lower nibble by moving it to the upper nibble position
cmdNibbleUpper = cmd & 0xf0; //select upper nibble
Expand All @@ -101,20 +103,20 @@ void HD44780PCF8574LCD::LCDSendCmd(unsigned char cmd) {

// bcm2835I2CReasonCodes, BCM2835_I2C_REASON_OK 0x00 = Success
uint8_t ReasonCodes = bcm2835_i2c_write(cmdBufferI2C, 4);

while(ReasonCodes != 0)
{
if (_DebugON == true)
{
std::cout << "Error 602: I2C Command bcm2835I2CReasonCodes : " << +ReasonCodes << std::endl;
std::cout << "Attempt : " << +attemptI2Cwrite << std::endl;
bcm2835_delay(100);
attemptI2Cwrite++;
std::cout << "Attempt Count : " << +attemptI2Cwrite << std::endl;
}
ReasonCodes = bcm2835_i2c_write(cmdBufferI2C, 4); // retransmit
bcm2835_delay(25);
if (attemptI2Cwrite >= 3) break;
bcm2835_delay(_I2C_ErrorDelay);
ReasonCodes = bcm2835_i2c_write(cmdBufferI2C,4); // retransmit
_I2C_Error = ReasonCodes;
attemptI2Cwrite--;
if (attemptI2Cwrite == 0) break;
}
_I2C_Error = ReasonCodes;
}

/*!
Expand Down Expand Up @@ -462,7 +464,7 @@ void HD44780PCF8574LCD::LCDChangeEntryMode(LCDEntryMode_e newEntryMode)

/*!
@brief Turn DEBUG mode on or off setter
@param passed bool True = debug on , false = debug off
@param OnOff passed bool True = debug on , false = debug off
@note prints out statements, if ON and if errors occur
*/
void HD44780PCF8574LCD::LCDDebugSet(bool OnOff)
Expand All @@ -483,4 +485,45 @@ bool HD44780PCF8574LCD::LCDDebugGet(void) { return _DebugON;}
int16_t HD44780PCF8574LCD::LCDVerNumGet(void){return _LibVersionNum;}


/*!
@brief get I2C error Flag
@return I2C error flag = 0x00 no error , > 0 bcm2835I2Creasoncode.
*/
bool HD44780PCF8574LCD::LCDI2CErrorGet(void) { return _I2C_Error;}

/*!
@brief Sets the I2C timeout in the event of an I2C write error
@param newTimeOut I2C timeout delay in mS
*/
void HD44780PCF8574LCD::LCDI2CErrorTimeoutSet(uint16_t newTimeout)
{
_I2C_ErrorDelay = newTimeout;
}

/*!
@brief Sets the I2C timeout in the event of an I2C write error
@return I2C timeout delay in mS, _I2C_ErrorDelay
*/
uint16_t HD44780PCF8574LCD::LCDI2CErrorTimeoutGet(void)
{
return _I2C_ErrorDelay;
}

/*!
@brief checks if LCD on I2C bus
@return bcm2835I2CReasonCodes , BCM2835_I2C_REASON_OK 0x00 = Success
*/
int16_t HD44780PCF8574LCD::LCDCheckConnection(void)
{
int16_t returnValue;
char rxdata[1]; //buffer to hold return byte

bcm2835_i2c_setSlaveAddress(_LCDSlaveAddresI2C); // set i2c address
returnValue = bcm2835_i2c_read(rxdata, 1); // returns reason code , 0 success

_I2C_Error = returnValue;
return returnValue;
}


// **** EOF ****

0 comments on commit 9490694

Please sign in to comment.