first commit

This commit is contained in:
Jérôme Delacotte
2025-03-06 11:15:32 +01:00
commit 7b30d6e298
5276 changed files with 2108927 additions and 0 deletions

View File

@@ -0,0 +1,94 @@
// vi:ts=4
// ----------------------------------------------------------------------------
// HelloWorld - simple demonstration of lcd
// Created by Bill Perry 2016-07-02
// bperrybap@opensource.billsworld.billandterrie.com
//
// This example code is unlicensed and is released into the public domain
// ----------------------------------------------------------------------------
//
// This sketch is for LCDs with PCF8574 or MCP23008 chip based backpacks
// WARNING:
// Use caution when using 3v only processors like arm and ESP8266 processors
// when interfacing with 5v modules as not doing proper level shifting or
// incorrectly hooking things up can damage the processor.
//
// Sketch prints "Hello, World!" on the lcd
//
// If initialization of the LCD fails and the arduino supports a built in LED,
// the sketch will simply blink the built in LED.
//
// NOTE:
// If the sketch fails to produce the expected results, or blinks the LED,
// run the included I2CexpDiag sketch to test the i2c signals and the LCD.
//
// ----------------------------------------------------------------------------
// LiquidCrystal compability:
// Since hd44780 is LiquidCrystal API compatible, most existing LiquidCrystal
// sketches should work with hd44780 hd44780_I2Cexp i/o class once the
// includes are changed to use hd44780 and the lcd object constructor is
// changed to use the hd44780_I2Cexp i/o class.
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
hd44780_I2Cexp lcd; // declare lcd object: auto locate & auto config expander chip
// If you wish to use an i/o expander at a specific address, you can specify the
// i2c address and let the library auto configure it. If you don't specify
// the address, or use an address of zero, the library will search for the
// i2c address of the device.
// hd44780_I2Cexp lcd(i2c_address); // specify a specific i2c address
//
// It is also possible to create multiple/seperate lcd objects
// and the library can still automatically locate them.
// Example:
// hd4480_I2Cexp lcd1;
// hd4480_I2Cexp lcd2;
// The individual lcds would be referenced as lcd1 and lcd2
// i.e. lcd1.home() or lcd2.clear()
//
// It is also possible to specify the i2c address
// when declaring the lcd object.
// Example:
// hd44780_I2Cexp lcd1(0x20);
// hd44780_I2Cexp lcd2(0x27);
// This ensures that each each lcd object is assigned to a specific
// lcd device rather than letting the library automatically asign it.
// LCD geometry
const int LCD_COLS = 16;
const int LCD_ROWS = 2;
void setup()
{
int status;
// initialize LCD with number of columns and rows:
// hd44780 returns a status from begin() that can be used
// to determine if initalization failed.
// the actual status codes are defined in <hd44780.h>
// See the values RV_XXXX
//
// looking at the return status from begin() is optional
// it is being done here to provide feedback should there be an issue
//
// note:
// begin() will automatically turn on the backlight
//
status = lcd.begin(LCD_COLS, LCD_ROWS);
if(status) // non zero status means it was unsuccesful
{
// hd44780 has a fatalError() routine that blinks an led if possible
// begin() failed so blink error code using the onboard LED if possible
hd44780::fatalError(status); // does not return
}
// initalization was successful, the backlight should be on now
// Print a message to the LCD
lcd.print("Hello, World!");
}
void loop() {}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,315 @@
static const int dummyvar = 0; // dummy declaration for older broken IDEs!!!!
// vi:ts=4
// ----------------------------------------------------------------------------
// LCDCustomChars - simple demonstration of lcd custom characters
// Created by Bill Perry 2016-10-06
// bperrybap@opensource.billsworld.billandterrie.com
//
// This example code is unlicensed and is released into the public domain
// ----------------------------------------------------------------------------
//
// This sketch is for LCDs with PCF8574 or MCP23008 chip based backpacks
// WARNING:
// Use caution when using 3v only processors like arm and ESP8266 processors
// when interfacing with 5v modules as not doing proper level shifting or
// incorrectly hooking things up can damage the processor.
//
// Sketch demonstrates how to assign custom characters to the eight hd44780
// custom character codepoints and how to display on the LCD using
// write() and print()
//
// You can create your own custom characters.
// Here are a couple of web pages that have a tool that will generate the data
// values needed for custom character.
// https://kakedev.github.io/GlyphGenerator/
// http://www.quinapalus.com/hd44780udg.html
// https://omerk.github.io/lcdchargen
//
#include <Wire.h>
#include <hd44780.h> // include hd44780 library header file
#include <hd44780ioClass/hd44780_I2Cexp.h> // i/o expander/backpack class
hd44780_I2Cexp lcd; // auto detect backpack and pin mappings
// LCD geometry
const int LCD_COLS = 16;
const int LCD_ROWS = 2;
const int LongDelay = 5000;
const int ShortDelay = 800;
int customcharRow = 1; // default to printing custom chars on row 1
// Below are some custom characters for demonstration
// You can ensure that the data for these custom characters is only
// in flash and not in RAM by using the const qualifier.
// However....
// If using the AVR part, the AVR proprietary PROGMEM directive must be used.
// PROGMEM is only required on AVR parts since the AVR parts cannot directly
// access const data stored in flash like all the other processors.
// PROGMEM is an AVR specific proprietary kludge that tells the linker and
// startup code to handle the data differently.
// PROGMEM is only used by the AVR and not required by any other processor.
//
// Most non AVR cores provide AVR compatibilty by providing support (emulation)
// for the AVR proprietary PROGMEM directive and corresponding access functions,
// but some do not.
//
// Because of this AVR const data and PROGMEM issue, there is no way to
// guarantee code portability across all cores when using const data.
//
//
// the hd44780 library assumes that if a const qualifier is used on the AVR
// processor that the data has been stored in flash using the PROGMEM directive.
// There is no way for the hd44780 library to know or detect if PROGMEM has
// been used.
// So if the const qualifer is used but the PROGMEM directive is not used on
// an AVR processor, the custom char will be garbage.
//
// Examples:
// For all processors other than AVR:
// const char bell[8] = {0x04,0x0e,0x0e,0x0e,0x1f,0x00,0x04,0x00};
// const uint8_ bell[8] = {0x04,0x0e,0x0e,0x0e,0x1f,0x00,0x04,0x00};
//
// For AVR: (and non AVR cores that have AVR PROGMEM emulation)
// const char bell[8] PROGMEM = {0x04,0x0e,0x0e,0x0e,0x1f,0x00,0x04,0x00};
// const uint8_t bell[8] PROGMEM = {0x04,0x0e,0x0e,0x0e,0x1f,0x00,0x04,0x00};
// OR
// const PROGMEM char bell[8] = {0x04,0x0e,0x0e,0x0e,0x1f,0x00,0x04,0x00};
// const PROGMEM uint8_t bell[8] = {0x04,0x0e,0x0e,0x0e,0x1f,0x00,0x04,0x00};
// NOTE:
// if PROGMEM is used on older AVR compilers it generates a warning.
//
uint8_t bell[8] = {0x04,0x0e,0x0e,0x0e,0x1f,0x00,0x04,0x00};
uint8_t note[8] = {0x02,0x03,0x02,0x0e,0x1e,0x0c,0x00,0x00};
uint8_t clockface[8] = {0x00,0x0e,0x15,0x17,0x11,0x0e,0x00,0x00};
uint8_t heart[8] = {0x00,0x0a,0x1f,0x1f,0x0e,0x04,0x00,0x00};
uint8_t duck[8] = {0x00,0x0c,0x1d,0x0f,0x0f,0x06,0x00,0x00};
uint8_t check[8] = {0x00,0x01,0x03,0x16,0x1c,0x08,0x00,0x00};
uint8_t cross[8] = {0x00,0x1b,0x0e,0x04,0x0e,0x1b,0x00,0x00};
uint8_t smile[8] = {0x00,0x0a,0x0a,0x00,0x00,0x11,0x0e,0x00};
uint8_t degreeSymbol[8]= {0x06,0x09,0x09,0x06,0x00,0x00,0x00,0x00};
uint8_t degreeC[8] = {0x18,0x18,0x03,0x04,0x04,0x04,0x03,0x00};
uint8_t degreeF[8] = {0x18,0x18,0x07,0x04,0x07,0x04,0x04,0x00};
const PROGMEM uint8_t vsigbar[][8] = {
{0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // 0 bars, same as <space>
{0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x1F}, // 1 bars
{0x00, 0x00,0x00,0x00,0x00,0x00,0x1F,0x1F}, // 2 bars
{0x00, 0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F}, // 3 bars
{0x00, 0x00,0x00,0x00,0x1F,0x1F,0x1F,0x1F}, // 4 bars
{0x00, 0x00,0x00,0x1F,0x1F,0x1F,0x1F,0x1F}, // 5 bars
{0x00, 0x00,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F}, // 6 bars
{0x00, 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F}, // 7 bars
{0x1F, 0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F}, // 8 bars
};
void setup()
{
int status;
// initialize LCD with number of columns and rows:
// hd44780 returns a status from begin() that can be used
// to determine if initalization failed.
// the actual status codes are defined in <hd44780.h>
// See the values RV_XXXX
//
// looking at the return status from begin() is optional
// it is being done here to provide feedback should there be an issue
//
// note:
// begin() will automatically turn on the backlight
//
status = lcd.begin(LCD_COLS, LCD_ROWS);
if(status) // non zero status means it was unsuccesful
{
// begin() failed so blink error code using the onboard LED if possible
hd44780::fatalError(status); // does not return
}
// initalization was successful, the backlight should be on now
}
void loop(void)
{
lcd.clear();
lcd.print("Custom Chars");
// create custom characters
// int rval = createChar(charval, charmap[]);
//
// createChar() creates a custom character
// for the character at the charval codepoint.
// It returns zero if successful.
//
// to display the custom character, simply call write()
// with the charval use in createChar()
//
// The display must be initialized *before* you attempt
// to create custom characters.
//
// Note: On hd44780 displays there are 8 custom characters.
// They are assigned to character codepoint values 0x00 to 0x07
// The codepoints 0x08 to 0x0f are duplicates for 0x00 to 0x07
// i.e. 0x08 is the same as 0x00, 0x09 same as 0x01, etc...
// create 8 custom characters
lcd.createChar(0, bell);
lcd.createChar(1, note);
lcd.createChar(2, clockface);
lcd.createChar(3, heart);
lcd.createChar(4, duck);
lcd.createChar(5, check);
lcd.createChar(6, cross);
lcd.createChar(7, smile);
// prepare to display the custom characters
// on multi line displays the custom characters will be
// displayed on the 2nd line
// on single line displays, delay a bit to see the initial display,
// then clear the display to display the custom characters on the top line
if(LCD_ROWS < 2)
{
customcharRow = 0;
delay(LongDelay);
lcd.clear();
}
lcd.setCursor(0, customcharRow);
// write() or print() can be used to display custom characters.
//
// To use write() pass the charval of the desired custom character.
// lcd.write(charval);
// NOTE:
// The Print class has an issue that does not allow 0 (zero) to be used
// on write() without casting it. The Arduino team refuses to fix this.
// hd44780 has a work around in it to remove this issue so you can call
// write() with a constant value of 0 without having to cast it.
//
// write() can also be used with literal characters that contain
// an octal (base 8) escape seuence.
// lcd.write('\###');
//
// To use print() pass in the charval of the desired custom character
// as a character *not* an integer.
// This requires using a literal character with an octal escape sequence.
// lcd.print('\###');
//
// Since both write() & print() both accept octal escaped literal characters
// it is the most compatible & portable way of sending custom characters
// display all 8 custom characters.
// write() with character codepoint values
lcd.write(0); // casting to an uint8_t or byte not needed with hd44780
lcd.write(1);
// write() & print() with octal escaped literal characters
lcd.write('\002'); // this is an octal escaped literal character
lcd.write('\003'); // this is an octal escaped literal character
lcd.print('\004'); // this is an octal escaped literal character
lcd.print('\005'); // this is an octal escaped literal character
// can also drop the leading zeros on small litereal values like these
lcd.print('\06'); // this is an octal escaped literal character
lcd.print('\7'); // this is an octal escaped literal character
delay(LongDelay);
// You can also insert custom character codepoints into C strings.
// To do so, insert the character codepoint value as an octal constant.
// However,
// because zero indicates the end of string in C you cannot use zero.
// Example:
// lcd.print("charval #1: \001"); // prints custom character at codepoint 1
lcd.setCursor(0,customcharRow);
lcd.print("code1: \001");
delay(ShortDelay);
lcd.setCursor(0,customcharRow);
lcd.print("code2: \002");
delay(ShortDelay);
lcd.setCursor(0,customcharRow);
lcd.print("code3: \003");
delay(ShortDelay);
lcd.setCursor(0,customcharRow);
lcd.print("code4: \004");
delay(ShortDelay);
lcd.setCursor(0,customcharRow);
lcd.print("code5: \005");
delay(ShortDelay);
lcd.setCursor(0,customcharRow);
lcd.print("code6: \006");
delay(ShortDelay);
lcd.setCursor(0,customcharRow);
lcd.print("code7: \007");
delay(ShortDelay);
// Another nifty trick is that you can modify custom characters on the
// display without having to re-write the characters on the display.
// To do this, simply create a new character for a codepoint.
// All characters on the display which have that codepoint will "magically"
// change to the new custom character.
// So for example, if the entire display was written with custom character
// zero and character zero was a bell, if you called createChar() to
// redefine character codepoint zero to be a duck,
// the entire display would turn to ducks without having to send any
// characters to the display.
// create the initial custom character
lcd.createChar(0, bell);
// fill the custom character line with the custom character.
lcd.setCursor(0,customcharRow);
for(uint8_t col=0; col<LCD_COLS; col++)
lcd.write(0);
delay(ShortDelay);
// change the single custom character previously written on the row
// and all the characters on the row will change
// without having to re-write the characters.
lcd.createChar(0, note);
delay(ShortDelay);
lcd.createChar(0, clockface);
delay(ShortDelay);
lcd.createChar(0, heart);
delay(ShortDelay);
lcd.createChar(0, duck);
delay(ShortDelay);
lcd.createChar(0, check);
delay(ShortDelay);
lcd.createChar(0, cross);
delay(ShortDelay);
lcd.createChar(0, smile);
delay(ShortDelay);
lcd.createChar(0, degreeSymbol);
delay(ShortDelay);
lcd.createChar(0, degreeC);
delay(ShortDelay);
lcd.createChar(0, degreeF);
delay(ShortDelay);
// show multiple vertical bars rising
// by changing the single custom character that is already written
// to the entire row on the display
for(int i = 0; i < 9; i++)
{
lcd.createChar(0, vsigbar[i]);
delay(ShortDelay);
}
delay(LongDelay);
}

View File

@@ -0,0 +1,143 @@
// vi:ts=4
// ----------------------------------------------------------------------------
// LineWrap - simple demonstration of automatic linewrap functionality
// Created by Bill Perry 2017-05-10
// bperrybap@opensource.billsworld.billandterrie.com
//
// This example code is unlicensed and is released into the public domain
// ----------------------------------------------------------------------------
//
// This sketch is for LCDs with PCF8574 or MCP23008 chip based backpacks
//
// WARNING:
// Use caution when using 3v only processors like arm and ESP8266 processors
// when interfacing with 5v modules as not doing proper level shifting or
// incorrectly hooking things up can damage the processor.
//
// Sketch demonstrates hd44780 library automatic line wrapping functionality.
//
// Background:
// hd44780 LCDs do not use linear continuous memory for the characters
// on the lines on the display.
// This means that simply sending continuous characters to the
// display will not fill lines and wrap appropriately as might be expected.
// The hd44780 library solves this issue by adding a line wrapping capability
// in s/w that can be enabled & disabled.
// This allows the host to send characters to the display continuously and they
// will wrap to the next lower line when the end of the visible line has been
// reached. When on the bottom line it will wrap back to the top line.
//
// (Configure LCD_COLS & LCD_ROWS if desired/needed)
// Expected behavior of the sketch:
// - display a banner announcing the test.
// - print the configured LCD geometry
// - print a long text string to demostrate automatic line wrapping
// - print lots of characters (slowly) to show how the full wrapping works.
// (loop)
//
// If initialization of the LCD fails and the arduino supports a built in LED,
// the sketch will simply blink the built in LED with the initalization error
// code.
//
// NOTE:
// If the sketch fails to produce the expected results, or blinks the LED,
// run the included I2CexpDiag sketch to test the i2c signals and the LCD.
//
// Special note for certain 16x1 displays:
// Some 16x1 displays are actually a 8x2 display that have both lines on
// a single line on the display.
// If you have one of these displays, simply set the geometry to 8x2 instead
// of 16x1.
// In normal sketches, lineWrap() mode will allow this type of display to
// properly function as a 16x1 display in that it will allow printing up to
// 16 characters on the display without having to manually set the cursor
// position to print the right characters on the half of the display.
// However, when using this 8x2 display as a 16x1 display,
// scrollDisplayLeft() and scrollDisplayRight() will not work as intended.
// They will shift the two halves of the display rather than the entire display.
// This is because the hd44780 chip is doing the shift and chip is hard coded
// internally for two lines.
// include the needed headers.
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip
// LCD geometry
// while 16x2 will work on most displays even if the geometry is different,
// for actual wrap testing of a particular LCD it is best to use the correct
// geometry.
const int LCD_COLS = 16;
const int LCD_ROWS = 2;
void setup()
{
int status;
// initialize LCD with number of columns and rows:
// hd44780 returns a status from begin() that can be used
// to determine if initalization failed.
// the actual status codes are defined in <hd44780.h>
status = lcd.begin(LCD_COLS, LCD_ROWS);
if(status) // non zero status means it was unsuccesful
{
// begin() failed so blink error code using the onboard LED if possible
hd44780::fatalError(status); // does not return
}
// turn on automatic line wrapping
// which automatically wraps lines to the next lower line and wraps back
// to the top when at the bottom line
// NOTE:
// noLineWrap() can be used to disable automatic line wrapping.
// _write() can be called instead of write() to send data bytes
// to the display bypassing any special character or line wrap processing.
lcd.lineWrap();
}
void loop()
{
lcd.clear();
lcd.print("WrapTest");
delay(2000);
lcd.clear();
//print the configured LCD geometry
lcd.print(LCD_COLS);
lcd.print("x");
lcd.print(LCD_ROWS);
delay(3000);
lcd.clear();
// print a long text string
// without line wrapping enabled, the text would not wrap properly
// to the next line.
if(LCD_COLS == 8)
lcd.print("A long text line");
else
lcd.print("This is a very long line of text");
delay(3000);
lcd.clear();
// now print 2 full displays worth of characters to show
// the full wrapping.
lcd.cursor(); // turn on cursor so you can see where it is
char c = '0'; // start at the character for the number zero
for(int i = 2*LCD_COLS*LCD_ROWS; i; i--)
{
lcd.print(c++);
delay(200); // slow things down to watch the printing & wrapping
if(c > 0x7e) // wrap back to beginning of printable ASCII chars
c = '!';
}
delay(3000);
lcd.noCursor(); // turn off cursor
}

View File

@@ -0,0 +1,154 @@
// vi:ts=4
// ----------------------------------------------------------------------------
// MultiDisplay - simple demonstration of accessing multiple lcds
// Created by Bill Perry 2016-07-02
// bperrybap@opensource.billsworld.billandterrie.com
//
// This example code is unlicensed and is released into the public domain
// ----------------------------------------------------------------------------
//
// This sketch is for LCDs with PCF8574 or MCP23008 chip based backpacks
// WARNING:
// Use caution when using 3v only processors like arm and ESP8266 processors
// when interfacing with 5v modules as not doing proper level shifting or
// incorrectly hooking things up can damage the processor.
//
// Sketch will print lcd instance number on top line with i2c address
// and will print the amount of time since the Arduino has been reset
// on the second row.
//
// If initialization of the LCD fails and the arduino supports a built in LED,
// the sketch will simply blink the built in LED.
//
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
// All displays will be assumed to be 16x2
// Even if display is larger the sketch should still work correctly
const int LCD_ROWS = 2;
const int LCD_COLS = 16;
// this lcd[] array declares an array of lcd objects.
// an array makes using multiple lcd easy as you can acces the object
// by using the lcds instance number as in index into the array.
// This really only works if all the lcds are the same.
//
hd44780_I2Cexp lcd[16]; // auto locate & configure up to 16 displays
int NumLcd; // number of LCD displays found.
// It is also possible to create multiple/seperate lcd objects
// and the library can still automatically locate them.
// Example:
// hd4480_I2Cexp lcd1;
// hd4480_I2Cexp lcd2;
// The individual lcds would be referenced as lcd1 and lcd2
// i.e. lcd1.home() or lcd2.clear()
//
// It is also possible to specify the i2c address
// when defining the lcd object.
// Example:
// hd44780_I2Cexp lcd1(0x20);
// hd44780_I2Cexp lcd2(0x27);
// This ensures that each each lcd object is assigned to a specific
// lcd device rather than letting the library automatically asign it.
void setup()
{
/*
* Locate all the displays by attempting to intialize each one
*/
for(NumLcd = 0; NumLcd < 16; NumLcd++)
{
/*
* If begin fails, then assume we have no more displays
*/
if(lcd[NumLcd].begin(LCD_ROWS, LCD_COLS) != 0)
break;
}
if(NumLcd == 0)
{
// no LCD devices found, blink the onboard LED if possible
fatalError(1); // this never returns
}
for(int n = 0; n < NumLcd; n++)
{
/*
* Label the display with its instance number
* and i2c address
*/
lcd[n].setCursor(0, 0);
lcd[n].print("LCD:");
lcd[n].print(n);
lcd[n].print(" (0x");
lcd[n].print(lcd[n].getProp(hd44780_I2Cexp::Prop_addr), HEX);
lcd[n].print(")");
}
}
void loop()
{
static unsigned long lastsecs = -1; // pre-initialize with non zero value
unsigned long secs;
secs = millis() / 1000;
// see if 1 second has passed
// so the display is only updated once per second
if(secs != lastsecs)
{
lastsecs = secs; // keep track of last seconds
// write the 'uptime' to each display found
for(int n = 0; n < NumLcd; n++)
{
// set the cursor to column 0, line 1
// (note: line 1 is the second row, counting begins with 0):
lcd[n].setCursor(0, 1);
// print uptime on lcd device: (time since last reset)
PrintUpTime(lcd[n], secs);
}
}
}
// PrintUpTime(outdev, secs) - print uptime in HH:MM:SS format
// outdev - the device to send output
// secs - the total number of seconds uptime
void PrintUpTime(Print &outdev, unsigned long secs)
{
unsigned int hr, mins, sec;
// convert total seconds to hours, mins, seconds
mins = secs / 60; // how many total minutes
hr = mins / 60; // how many total hours
mins = mins % 60; // how many minutes within the hour
sec = secs % 60; // how many seconds within the minute
// print uptime in HH:MM:SS format
// Print class does not support fixed width formatting
// so insert a zero if number smaller than 10
if(hr < 10)
outdev.write('0');
outdev.print((int)hr);
outdev.write(':');
if(mins < 10)
outdev.write('0');
outdev.print((int)mins);
outdev.write(':');
if(sec < 10)
outdev.write('0');
outdev.print((int)sec);
}
// fatalError() - loop & blink an error code
void fatalError(int ecode)
{
hd44780::fatalError(ecode); // does not return
}

View File

@@ -0,0 +1,44 @@
hd44780_I2Cexp examples
=======================
The examples included in this directory are for the hd44780_I2Cexp i/o class.<br>
The hd44780_I2Cexp i/o class controls an LCD using an i2c i/o exapander backpack (PCF8574 or MCP23008)
#### The following examples are included:
- `HelloWorld`<br>
Prints "Hello, World!" on the lcd
- `I2CexpDiag`<br>
Verifies configuation & operation of hd44780 LCDs based
on the Hitachi HD44780 and compatible chipsets using I2C extension
backpacks that use a simple I2C i/o expander chip. (PCF8574 or MCP23008)
Sketch supports testing of multiple displays at once.
- `LCDCustomChars`<br>
Demonstrates using custom characters
- `LineWrap`<br>
Demonstrates automatic linewrap functionality
- `MultiDisplay`<br>
Displays information on multiple displays at once.
- `ReadWrite`<br>
Demonstrates the ability to read data from the LCD.
- `Serial2LCD`<br>
Displays a message read from the serial port on the lcd.
- `SoftwareWire`<br>
Demonstrates how to use the SoftwareWire library to allow using different pins
for SDA and SCL signals.
- `UpTime`<br>
Prints the amount of time since the Arduino has been reset.
- `hd44780examples`<br>
The hd44780examples subdirectory contains
hd44780_I2Cexp class specific wrapper sketches for sketches under
examples/hd44780examples.

View File

@@ -0,0 +1,142 @@
// vi:ts=4
// ----------------------------------------------------------------------------
// ReadWrite - simple demonstration reading data from LCD
// Created by Bill Perry 2016-08-19
// bperrybap@opensource.billsworld.billandterrie.com
//
// This example code is unlicensed and is released into the public domain
// ----------------------------------------------------------------------------
//
// This sketch is for LCDs with PCF8574 or MCP23008 chip based backpacks
// WARNING:
// Use caution when using 3v only processors like arm and ESP8266 processors
// when interfacing with 5v modules as not doing proper level shifting or
// incorrectly hooking things up can damage the processor.
//
// The purpose of the sketch is to demonstrate the ability to read data from
// the LCD.
//
// Sketch will print the amount of time since the Arduino has been reset
// on the top row and then read the data from the LCD to print it on the
// second row
//
// If there are errors and the arduino supports a built in LED,
// an error status code will blink on the built in LED.
// Error codes:
// (1) lcd device initalization failed
// (2) lcd device does not support reads
// (3) error reading data from lcd device
// (4) error writing data to lcd device
// (5) read data mismatch
//
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>
hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip
// LCD geometry
const int LCD_ROWS = 2;
const int LCD_COLS = 16;
void setup()
{
// initialize LCD with number of columns and rows:
if( lcd.begin(LCD_COLS, LCD_ROWS))
{
// begin() failed so blink the onboard LED if possible
fatalError(1);
}
// check to see if device can read by attempting to read
// the lcd status register. If it fails then assume it was
// because the lcd device does not support reads.
if(lcd.status() < 0)
{
lcd.print("No Read Support");
fatalError(2);
}
}
void loop()
{
static unsigned long lastsecs = -1; // pre-initialize with non zero value
unsigned long secs;
secs = millis() / 1000;
// see if 1 second has passed
// so the display is only updated once per second
if(secs != lastsecs)
{
lastsecs = secs; // keep track of last seconds
// set the cursor position to top line: column 0, row 0
lcd.setCursor(0, 0);
// print uptime on lcd device: (time since last reset)
PrintUpTime(lcd, secs);
// Now copy the characters from the top line to the 2nd line
// This is done character by character by:
// - setting the character position to read
// - reading a character
// - setting the character position to write
// - writing the charcter read
for(int col = 0; col < LCD_COLS; col++)
{
int c;
lcd.setCursor(col, 0);
if((c = lcd.read()) < 0) // if a read error, bomb out
fatalError(3);
// check for ':' characters in col 2 and 5
// if not there, consider it a fatal read error
if((col == 2 || col == 5) && c != ':')
fatalError(5);
lcd.setCursor(col, 1);
if(lcd.write((uint8_t) c) != 1)
fatalError(4);
}
}
}
// PrintUpTime(outdev, secs) - print uptime in HH:MM:SS format
// outdev - the device to send output
// secs - the total number of seconds uptime
void PrintUpTime(Print &outdev, unsigned long secs)
{
unsigned int hr, mins, sec;
// convert total seconds to hours, mins, seconds
mins = secs / 60; // how many total minutes
hr = mins / 60; // how many total hours
mins = mins % 60; // how many minutes within the hour
sec = secs % 60; // how many seconds within the minute
// print uptime in HH:MM:SS format
// Print class does not support fixed width formatting
// so insert a zero if number smaller than 10
if(hr < 10)
outdev.write('0');
outdev.print((int)hr);
outdev.write(':');
if(mins < 10)
outdev.write('0');
outdev.print((int)mins);
outdev.write(':');
if(sec < 10)
outdev.write('0');
outdev.print((int)sec);
}
// fatalError() - loop & blink and error code
void fatalError(int ecode)
{
hd44780::fatalError(ecode); // does not return
}

View File

@@ -0,0 +1,120 @@
// vi:ts=4
// ----------------------------------------------------------------------------
// Serial2LCD - simple demonstration printing characters from serial port
// Created by Bill Perry 2020-06-28
// bperrybap@opensource.billsworld.billandterrie.com
//
// This example code is unlicensed and is released into the public domain
// ----------------------------------------------------------------------------
//
// This sketch is for LCDs with PCF8574 or MCP23008 chip based backpacks
//
// Sketch demonstrates hd44780 how to read a message of characters from
// serial port and display it on the LCD.
// It takes advantage of the hd44780 library automatic line
// wrapping capability.
// See the LineWrap sketch for details about line wrapping.
//
// WARNING:
// Use caution when using 3v only processors like arm and ESP8266 processors
// when interfacing with 5v modules as not doing proper level shifting or
// incorrectly hooking things up can damage the processor.
//
// Configure LCD_COLS, LCD_ROWS and BAUDRATE if desired/needed
// Expected behavior of the sketch:
// - characters received from serial port are displayed on LCD
// - CR and LF are ignored/dropped
//
// If initialization of the LCD fails and the arduino supports a built in LED,
// the sketch will simply blink the built in LED with the initalization error
// code.
//
// NOTE:
// If the sketch fails to produce the expected results, or blinks the LED,
// run the included I2CexpDiag sketch to test the i2c signals and the LCD.
//
// Some 16x1 displays are actually a 8x2 display that have both lines on
// a single line on the display.
// If you have one of these displays, simply set the geometry to 8x2 instead
// of 16x1.
// include the needed headers.
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip
// LCD geometry
// while 16x2 will work on most displays even if the geometry is different,
// for actual wrap testing of a particular LCD it is best to use the correct
// geometry.
const int LCD_COLS = 16;
const int LCD_ROWS = 2;
const int BAUDRATE = 9600;
void setup()
{
int status;
// initalize Serial port
Serial.begin(BAUDRATE);
// initialize LCD with number of columns and rows:
// hd44780 returns a status from begin() that can be used
// to determine if initalization failed.
// the actual status codes are defined in <hd44780.h>
status = lcd.begin(LCD_COLS, LCD_ROWS);
if(status) // non zero status means it was unsuccesful
{
// begin() failed
Serial.print("LCD initalization failed: ");
Serial.println(status);
// blink error code using the onboard LED if possible
hd44780::fatalError(status); // does not return
}
// turn on automatic line wrapping
// which automatically wraps lines to the next lower line and wraps back
// to the top when at the bottom line
// NOTE:
// noLineWrap() can be used to disable automatic line wrapping.
// _write() can be called instead of write() to send data bytes
// to the display bypassing any special character or line wrap processing.
lcd.lineWrap();
lcd.print("Serial2LCD");
if(LCD_ROWS > 1)
{
lcd.setCursor(0,1);
lcd.print("Baud:");
lcd.print(BAUDRATE);
}
}
void loop()
{
// check to see if characters available
// indicating a message is coming in
if (Serial.available())
{
// wait some time for rest of message to arrive
delay(100);
// Clear the display before showing the new message
lcd.clear();
// print the message on the LCD
while (Serial.available() > 0)
{
char c;
c = Serial.read();
if(c != '\r' && c != '\n') // drop CR and LF characters
lcd.write(c);
}
}
}

View File

@@ -0,0 +1,72 @@
// vi:ts=4
// ----------------------------------------------------------------------------
// SoftwareWire - how to use SoftwareWire library with hd44780_I2Cexp
// Created by Bill Perry 2020-01-01
// bperrybap@opensource.billsworld.billandterrie.com
//
// This example code is unlicensed and is released into the public domain
// ----------------------------------------------------------------------------
//
// Demonstrates how to use the SoftwareWire library to allow using different
// Arduino pins for SDA and SCL signals.
//
// Sketch prints "Hello, World!" on the lcd
//
// If initialization of the LCD fails and the arduino supports a built in LED,
// the sketch will simply blink the built in LED.
//
// WARNING:
// The SoftWareWire developers made a major change to the library June 2018
// which is in the subsequent 1.5.1 release that causes it be unusable by
// the hd44780 library.
// Until this change is backed out, you will not be able to use
// SoftWareWire beyond version 1.5.0 with the hd44780 library.
// This sketh will do a check to try to detect the incompatibilty issue
// and will error off with a compiler error when detected.
// See this github issue for details:
// https://github.com/Testato/SoftwareWire/issues/28
//
// NOTE:
// Using the SoftwareWire library is not necessary on the espXXXX platform as
// that platform already has the ability to configure the pins used in the
// Wire library.
// On the esp platforms, include <Wire.h> and set the pins by passing them to
// Wire.begin(sda, scl) *before* calling lcd.begin()
//
//
// ----------------------------------------------------------------------------
// define the Arduino pins you want to use for sda and scl signals
// use any Arduino pins you want,
// this uses same pins as the i2c h/w pins (SDA, SCL)
const int sda=SDA, scl=SCL;
#include <SoftwareWire.h> // make sure to not use beyond version 1.5.0
// Check for "new" SoftwareWire that breaks things
#if defined(TwoWire_h)
#error incompatible version of SoftwareWire library (use version 1.5.0)
#endif
SoftwareWire Wire(sda,scl); // Create Wire object using desired Arduino pins
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h>
hd44780_I2Cexp lcd; // declare lcd object and let it auto-configure everything.
void setup()
{
int istatus;
istatus = lcd.begin(16,2);
if(istatus)
{
// LCD initalization failed.
// handle it anyway you want
lcd.fatalError(istatus); // blinks error code on built in LED
}
lcd.print("Hello, World!");
lcd.setCursor(0,1);
lcd.print("SoftwareWire");
}
void loop() { }

View File

@@ -0,0 +1,141 @@
// vi:ts=4
// ----------------------------------------------------------------------------
// UpTime - simple demonstration of lcd
// Created by Bill Perry 2017-05-11
// bperrybap@opensource.billsworld.billandterrie.com
//
// This example code is unlicensed and is released into the public domain
// ----------------------------------------------------------------------------
//
// This sketch is for LCDs with PCF8574 or MCP23008 chip based backpacks
//
// WARNING:
// Use caution when using 3v only processors like arm and ESP8266 processors
// when interfacing with 5v modules as not doing proper level shifting or
// incorrectly hooking things up can damage the processor.
//
// Sketch will print "UpTime" on top row of lcd
// and will print the amount of time since the Arduino has been reset
// on the second row.
//
// If initialization of the LCD fails and the arduino supports a built in LED,
// the sketch will simply blink the built in LED.
//
// NOTE:
// If the sketch fails to produce the expected results, or blinks the LED,
// run the included I2CexpDiag sketch to test the i2c signals and the LCD.
#include <Wire.h>
#include <hd44780.h> // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip
// LCD geometry
const int LCD_COLS = 16;
const int LCD_ROWS = 2;
void setup()
{
int status;
// initialize LCD with number of columns and rows:
// hd44780 returns a status from begin() that can be used
// to determine if initalization failed.
// the actual status codes are defined in <hd44780.h>
// See the values RV_XXXX
//
// looking at the return status from begin() is optional
// it is being done here to provide feedback should there be an issue
//
// note:
// begin() will automatically turn on the backlight
//
status = lcd.begin(LCD_COLS, LCD_ROWS);
if(status) // non zero status means it was unsuccesful
{
// hd44780 has a fatalError() routine that blinks an led if possible
// begin() failed so call fatalError() with the error code.
hd44780::fatalError(status); // does not return
}
// initalization was successful, the backlight should be on now
// Print a message to the LCD
lcd.print(" UpTime");
if(LCD_ROWS < 2)
delay(3000);
}
void loop()
{
static unsigned long lastsecs = -1; // pre-initialize with non zero value
unsigned long secs;
int status;
secs = millis() / 1000;
// see if 1 second has passed
// so the display is only updated once per second
if(secs != lastsecs)
{
lastsecs = secs; // keep track of last seconds
// set the cursor position to column 0, row 1
// note: row 1 is the second row from top,
// since row counting begins with 0
// if display has only 1 line, it will appear on that line
status = lcd.setCursor(0, 1);
if(status) // non zero status means it was unsuccesful
{
// setCursor() failed so call fatalError() with the error code.
hd44780::fatalError(status); // does not return
}
// print uptime on lcd device: (time since last reset)
PrintUpTime(lcd, secs);
}
}
// PrintUpTime(outdev, secs) - print uptime in HH:MM:SS format
// outdev - the device to send output
// secs - the total number of seconds uptime
//
// This is a fancy output routine.
// outdev is a Print class object which indicates
// where the output should be sent.
// PrintUpTime can be used with any object that uses the Print class.
// This code works with Serial objects, as well as the the hd44780 lcd objects.
// i.e. you can call with Serial: PrintUpTime(Serial, seconds);
void PrintUpTime(Print &outdev, unsigned long secs)
{
unsigned int hr, mins, sec;
// convert total seconds to hours, mins, seconds
mins = secs / 60; // how many total minutes
hr = mins / 60; // how many total hours
mins = mins % 60; // how many minutes within the hour
sec = secs % 60; // how many seconds within the minute
// print uptime in HH:MM:SS format
if(hr > 99)
hr %= 100; // limit hr to 0-99
// Print class does not support fixed width formatting
// so insert a zero if number smaller than 10
if(hr < 10)
outdev.write('0');
outdev.print((int)hr);
outdev.write(':');
if(mins < 10)
outdev.write('0');
outdev.print((int)mins);
outdev.write(':');
if(sec < 10)
outdev.write('0');
outdev.print((int)sec);
}

View File

@@ -0,0 +1,33 @@
// ----------------------------------------------------------------------------
// LCDcharset - Display LCD character set
// ----------------------------------------------------------------------------
// This sketch is a wrapper sketch for the hd44780 library example LCDcharset.
// Note:
// This is not a normal sketch and should not be used as model or example
// of hd44780 library sketches.
// This sketch is simple wrapper that declares the needed lcd object for the
// hd44780 library sketch.
// It is provided as a convenient way to run a pre-configured sketch for
// the i/o class.
// The source code for this sketch lives in hd44780 examples:
// hd44780/examples/hd44780examples/LCDcharset/LCDcharset.ino
// From IDE:
// [File]->Examples-> hd44780/hd44780examples/LCDcharset
//
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h> // include i/o class header
// define the LCD geometry
#define LCD_COLS 16
#define LCD_ROWS 2
// declare the lcd object
hd44780_I2Cexp lcd; // auto locate and autoconfig interface pins
// tell the hd44780 sketch the lcd object has been declared
#define HD44780_LCDOBJECT
// include the hd44780 library LCDcharset sketch source code
#include <examples/hd44780examples/LCDcharset/LCDcharset.ino>

View File

@@ -0,0 +1,29 @@
// ----------------------------------------------------------------------------
// LCDiSpeed - LCD Interface Speed test for hd44780 hd44780_I2Cexp i/o class
// ----------------------------------------------------------------------------
// This sketch is a wrapper sketch for the hd44780 library example LCDiSpeed.
// Note:
// This is not a normal sketch and should not be used as model or example
// of hd44780 library sketches.
// This sketch is simple wrapper that declares the needed lcd object for the
// hd44780 library sketch.
// It is provided as a convenient way to run a pre-configured sketch for
// the i/o class.
// The source code for this sketch lives in hd44780 examples:
// hd44780/examples/hd44780examples/LCDiSpeed/LCDiSpeed.ino
// From IDE:
// [File]->Examples-> hd44780/hd44780examples/LCDiSpeed
//
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h> // include i/o class header
// declare the lcd object
hd44780_I2Cexp lcd; // auto locate and autoconfig interface pins
// tell the hd44780 sketch the lcd object has been declared
#define HD44780_LCDOBJECT
// include the hd44780 library LCDiSpeed sketch source code
#include <examples/hd44780examples/LCDiSpeed/LCDiSpeed.ino>

View File

@@ -0,0 +1,36 @@
// ----------------------------------------------------------------------------
// LCDiSpeed - LCD Interface Speed test for hd44780 hd44780_I2Cexp i/o class
// ----------------------------------------------------------------------------
// This sketch is a wrapper sketch for the hd44780 library example LCDiSpeed.
// Note:
// This is not a normal sketch and should not be used as model or example
// of hd44780 library sketches.
// This sketch is simple wrapper that declares the needed lcd object for the
// hd44780 library sketch.
// It is provided as a convenient way to run a pre-configured sketch for
// the i/o class.
// The source code for this sketch lives in hd44780 examples:
// hd44780/examples/hd44780examples/LCDiSpeed/LCDiSpeed.ino
// From IDE:
// [File]->Examples-> hd44780/hd44780examples/LCDiSpeed
//
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h> // include i/o class header
#if ARDUINO < 157
#error "This sketch Requires Arduino 1.5.7 or higher"
#endif
// NOTE: uses API that only works on IDE 1.5.7 and up
#define WIRECLOCK 400000L // tell hd44780 example to use this i2c clock rate
// declare the lcd object
hd44780_I2Cexp lcd; // auto locate and autoconfig interface pins
// tell the hd44780 sketch the lcd object has been declared
#define HD44780_LCDOBJECT
// include the hd44780 library LCDiSpeed sketch source code
#include <examples/hd44780examples/LCDiSpeed/LCDiSpeed.ino>

View File

@@ -0,0 +1,29 @@
// ----------------------------------------------------------------------------
// LCDLibTest - LCD library test sketch for hd44780 hd44780_I2Cexp i/o class
// ----------------------------------------------------------------------------
// This sketch is a wrapper sketch for the hd44780 library example.
// Note:
// This is not a normal sketch and should not be used as model or exmaple
// of hd44780 library sketches.
// This sketch is simple wrapper that declares the needed lcd object for the
// hd44780 library sketch.
// It is provided as a convenient way to run a pre-configured sketch for
// the i/o class.
// The source code for this sketch lives in the hd44780 examples.
// hd44780/examples/hd44780examples/LCDlibTest/LCDlibTest.ino
// From IDE:
// [File]->Examples-> hd44780/hd44780examples/LCDlibTest
//
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h> // include i/o class header
// declare the lcd object
hd44780_I2Cexp lcd; // auto locate and autoconfig interface pins
// tell the hd44780 sketch the lcd object has been declared
#define HD44780_LCDOBJECT
// include the hd44780 library sketch source code
#include <examples/hd44780examples/LCDlibTest/LCDlibTest.ino>

View File

@@ -0,0 +1,36 @@
// ----------------------------------------------------------------------------
// LCDLibTest - LCD library test sketch for hd44780 hd44780_I2Cexp i/o class
// ----------------------------------------------------------------------------
// This sketch is a wrapper sketch for the hd44780 library example.
// Note:
// This is not a normal sketch and should not be used as model or exmaple
// of hd44780 library sketches.
// This sketch is simple wrapper that declares the needed lcd object for the
// hd44780 library sketch.
// It is provided as a convenient way to run a pre-configured sketch for
// the i/o class.
// The source code for this sketch lives in the hd44780 examples.
// hd44780/examples/hd44780examples/LCDlibTest/LCDlibTest.ino
// From IDE:
// [File]->Examples-> hd44780/hd44780examples/LCDlibTest
//
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h> // include i/o class header
#if ARDUINO < 157
#error "This sketch Requires Arduino 1.5.7 or higher"
#endif
// NOTE: uses API that only works on IDE 1.5.7 and up
#define WIRECLOCK 400000L // tell hd44780 example to use this i2c clock rate
// declare the lcd object
hd44780_I2Cexp lcd; // auto locate and autoconfig interface pins
// tell the hd44780 sketch the lcd object has been declared
#define HD44780_LCDOBJECT
// include the hd44780 library sketch source code
#include <examples/hd44780examples/LCDlibTest/LCDlibTest.ino>

View File

@@ -0,0 +1,29 @@
// ----------------------------------------------------------------------------
// lcdproc - LCD library lcdproc wrapper sketch for hd44780_I2Cexp i/o class
// ----------------------------------------------------------------------------
// This sketch is a wrapper sketch for the hd44780 library example.
// Note:
// This is not a normal sketch and should not be used as model or exmaple
// of hd44780 library sketches.
// This sketch is simple wrapper that declares the needed lcd object for the
// hd44780 library sketch.
// It is provided as a convenient way to run a pre-configured sketch for
// the i/o class.
// The source code for this sketch lives in the hd44780 examples.
// hd44780/examples/hd44780examples/lcdproc/lcdproc.ino
// From IDE:
// [File]->Examples-> hd44780/hd44780examples/lcdproc
//
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h> // include i/o class header
// declare the lcd object
hd44780_I2Cexp lcd; // auto locate and autoconfig interface pins
// tell the hd44780 sketch the lcd object has been declared
#define HD44780_LCDOBJECT
// include the hd44780 library sketch source code
#include <examples/hd44780examples/lcdproc/lcdproc.ino>

View File

@@ -0,0 +1,36 @@
// ----------------------------------------------------------------------------
// lcdproc - LCD library lcdproc wrapper sketch for hd44780_I2Cexp i/o class
// ----------------------------------------------------------------------------
// This sketch is a wrapper sketch for the hd44780 library example.
// Note:
// This is not a normal sketch and should not be used as model or exmaple
// of hd44780 library sketches.
// This sketch is simple wrapper that declares the needed lcd object for the
// hd44780 library sketch.
// It is provided as a convenient way to run a pre-configured sketch for
// the i/o class.
// The source code for this sketch lives in the hd44780 examples.
// hd44780/examples/hd44780examples/lcdproc/lcdproc.ino
// From IDE:
// [File]->Examples-> hd44780/hd44780examples/lcdproc
//
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h> // include i/o class header
#if ARDUINO < 157
#error "This sketch Requires Arduino 1.5.7 or higher"
#endif
// NOTE: uses API that only works on IDE 1.5.7 and up
#define WIRECLOCK 400000L // tell hd44780 example to use this i2c clock rate
// declare the lcd object
hd44780_I2Cexp lcd; // auto locate and autoconfig interface pins
// tell the hd44780 sketch the lcd object has been declared
#define HD44780_LCDOBJECT
// include the hd44780 library sketch source code
#include <examples/hd44780examples/lcdproc/lcdproc.ino>