bperrypap,
I have been very busy and haven't had as much time to do this research as I would like to have, so it has taken me awhile. I have found that virtually no straightforward "Hello World" program worked. However, The I2CexpDiag sketch DID work. The problem was that this sketch is extremely complicated and does a lot of things I do not want to do in my programs, and was difficult to determine what the "bare bones" code would be to simply make the LCD work. I have stripped out many pieces piece by piece and the following code does work
// vi:ts=4
// ----------------------------------------------------------------------------
// I2Cexpdiag - i2c LCD i/o Hello WOrld
// Created by Bill Perry 2016-06-17
// Copyright 2016 - Under GPL v3
// Modified by G Clay 7/20/2019
// ----------------------------------------------------------------------------
// The serial port is configured to 9600 baud.
//
#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c expander i/o class header
#ifndef INPUT_PULLUP
#error Sketch requires INPUT_PULLUP which is not supported by this IDE/core version
#endif
// ============================================================================
// user configurable options below this point
// ============================================================================
// Uncomment and use this line instead of the one below if you have a SYDZ backpack
//hd44780_I2Cexp lcd[1]={{I2Cexp_ADDR_UNKNOWN, I2Cexp_BOARD_SYDZ}}; // to run on a single SYDZ based backpack
hd44780_I2Cexp lcd[16]; // auto locate & configure up to 16 displays
// 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;
// turn on ESP8266 specific pin decoding
// Turn this off if it creates issues.
#define I2CEXPDIAG_CFG_DECODE_ESP8266PINS
// ============================================================================
// End of user configurable options
// ============================================================================
#ifndef BIT
#define BIT(_bitnum) (1 << _bitnum)
#endif
//#define MAX_ERRORS 16
//#define DEFPROMPT ((const char *) 0)
int NumLcd; // number of LCD displays found.
uint16_t WorkingLCD = 0; // bitmap of LCDs that are "working"
// macros to process working lcd info
#define isWorkingLCD(_n) (WorkingLCD & BIT(_n))
#define setWorkingLCD(_n) WorkingLCD |= BIT(_n)
#define clrWorkingLCD(_n) WorkingLCD &= ~BIT(_n)
#define anyWorkingLCD (WorkingLCD) // non zero if there are any working LCDs
// convert a define to a string
#define define2str(s) _str(s)
#define _str(...) #VA_ARGS
//********************************************************************************************************************************************************
void setup()
{
int nopullups;
delay(5); // allow the hardware time settle
Serial.begin(9600);
/*
- Locate all the displays by attempting to intialize each one
*/
//if(lcd[0].begin(LCD_ROWS, LCD_COLS) != 0)
// Serial.print(F(" LCD begin failed "));
// setWorkingLCD(0); // mark LCD as "working"
for(NumLcd = 0; NumLcd < (int) (sizeof(lcd)/sizeof(hd44780_I2Cexp)); NumLcd++)
{
char buf[16];
// If begin fails, then assume we have no more displays
if(lcd[NumLcd].begin(LCD_ROWS, LCD_COLS) != 0)
break;
Serial.println(NumLcd);
setWorkingLCD(NumLcd); // mark LCD as "working"
Serial.print(F(" LCD at address: "));
Serial.print(F("0x"));
Serial.print(lcd[NumLcd].getProp(hd44780_I2Cexp::Prop_addr), HEX);
Serial.print(F(" | config: "));
}
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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 working display
for(int n = 0; n < NumLcd; n++)
{
if(!isWorkingLCD(n))
continue; // skip over non working displays
//-------------------------------------------------------------------------------------
// set the cursor to column 0, line 1
// (note: line 1 is the second row, counting begins with 0):
if(lcd[n].setCursor(0, 0))
{
clrWorkingLCD(n); // mark display as no longer working
// output uptime and error message to serial port
PrintUpTime(Serial, secs);
Serial.print(F(" - Error on Display: "));
Serial.println(n);
}
else
{
lcd[n].write("Hello World!");
}
// set the cursor to column 0, line 1
// (note: line 1 is the second row, counting begins with 0):
if(lcd[n].setCursor(0, 1))
{
clrWorkingLCD(n); // mark display as no longer working
// output uptime and error message to serial port
PrintUpTime(Serial, secs);
Serial.print(F(" - Error on Display: "));
Serial.println(n);
}
else
{
// 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);
}
Maybe someone can use it to help them to write code to use this kind of display. Also I have not yet been able to simplify the array approach of such code as
for(NumLcd = 0; NumLcd < (int) (sizeof(lcd)/sizeof(hd44780_I2Cexp)); NumLcd++)
{
char buf[16];
// If begin fails, then assume we have no more displays
if(lcd[NumLcd].begin(LCD_ROWS, LCD_COLS) != 0)
break;
Serial.println(NumLcd);
setWorkingLCD(NumLcd); // mark LCD as "working"
Serial.print(F(" LCD at address: "));
Serial.print(F("0x"));
Serial.print(lcd[NumLcd].getProp(hd44780_I2Cexp::Prop_addr), HEX);
Serial.print(F(" | config: "));
}
into something like
//if(lcd[0].begin(LCD_ROWS, LCD_COLS) != 0)
// Serial.print(F(" LCD begin failed "));
// setWorkingLCD(0); // mark LCD as "working"
and get it to work. Any help in such continued simplification would be appreciated
George