1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-22 23:56:13 +01:00

Lcd experimental (#46)

* LCD/OLED Implementation
* OLED basic working 32
*132 display
* LCD/OLED startup ok
* Simplified setup
* Missing freememory include
* Format Width
Allow right padding number width in String format
* Intermediate scroll
* Compile issues with no LCD
* Clean buffers at startup
* Support for format left padded numbers
* Smarter Scrolling
And forced start messages
Free Ram in slot 2
* LCD tidying
Neater setup block in .ino.
Dropped unnecessary code
No-scroll if display not full
* Missing %E format support
This is used in WifiInterface checkForOK
* Wifi correction and memory guard
This commit is contained in:
Asbelos 2020-10-12 19:32:47 +01:00 committed by GitHub
parent 3f06fb08df
commit 0e3046e24f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 462 additions and 91 deletions

View File

@ -1,3 +1,21 @@
/*
* © 2020,Gregor Baues, Chris Harlow. All rights reserved.
*
* This file is part of CommandStation-EX
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* It is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/
#include <Arduino.h>
#include "CommandDistributor.h"
#include "WiThrottle.h"

View File

@ -1,3 +1,21 @@
/*
* © 2020,Gregor Baues, Chris Harlow. All rights reserved.
*
* This file is part of CommandStation-EX
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* It is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef CommandDistributor_h
#define CommandDistributor_h
#include "DCCEXParser.h"

View File

@ -12,18 +12,6 @@
#include "config.h"
#include "DCCEX.h"
////////////////////////////////////////////////////////////////
//
// Enables an I2C 2x24 or 4x24 LCD Screen
#if ENABLE_LCD
bool lcdEnabled = false;
#if defined(LIB_TYPE_PCF8574)
LiquidCrystal_PCF8574 lcdDisplay(LCD_ADDRESS);
#elif defined(LIB_TYPE_I2C)
LiquidCrystal_I2C lcdDisplay = LiquidCrystal_I2C(LCD_ADDRESS, LCD_COLUMNS, LCD_LINES);
#endif
#endif
// Create a serial command parser for the USB connection,
// This supports JMRI or manual diagnostics and commands
// to be issued from the USB serial console.
@ -31,45 +19,22 @@ DCCEXParser serialParser;
void setup()
{
////////////////////////////////////////////
//
// More display stuff. Need to put this in a .h file and make
// it a class
#if ENABLE_LCD
Wire.begin();
// Check that we can find the LCD by its address before attempting to use it.
Wire.beginTransmission(LCD_ADDRESS);
if (Wire.endTransmission() == 0)
{
lcdEnabled = true;
lcdDisplay.begin(LCD_COLUMNS, LCD_LINES);
lcdDisplay.setBacklight(255);
lcdDisplay.clear();
lcdDisplay.setCursor(0, 0);
lcdDisplay.print("DCC++ EX v");
lcdDisplay.print(VERSION);
lcdDisplay.setCursor(0, 1);
#if COMM_INTERFACE >= 1
lcdDisplay.print("IP: PENDING");
#else
lcdDisplay.print("SERIAL: READY");
#endif
#if LCD_LINES > 2
lcdDisplay.setCursor(0, 3);
lcdDisplay.print("TRACK POWER: OFF");
#endif
}
#endif
// The main sketch has responsibilities during setup()
// Responsibility 1: Start the usb connection for diagnostics
// This is normally Serial but uses SerialUSB on a SAMD processor
Serial.begin(115200);
DIAG(F("DCC++ EX v%S"),F(VERSION));
CONDITIONAL_LCD_START {
// This block is ignored if LCD not in use
LCD(0,F("DCC++ EX v%S"),F(VERSION));
LCD(1,F("Starting"));
}
// Start the WiFi interface on a MEGA, Uno cannot currently handle WiFi
#ifdef WIFI_ON
#if WIFI_ON
WifiInterface::setup(WIFI_SERIAL_LINK_SPEED, F(WIFI_SSID), F(WIFI_PASSWORD), F(WIFI_HOSTNAME), IP_PORT);
#endif // WIFI_ON
@ -83,7 +48,8 @@ void setup()
// Optionally a Timer number (1..4) may be passed to DCC::begin to override the default Timer1 used for the
// waveform generation. e.g. DCC::begin(STANDARD_MOTOR_SHIELD,2); to use timer 2
DCC::begin(MOTOR_SHIELD_TYPE);
DCC::begin(MOTOR_SHIELD_TYPE);
LCD(1,F("Ready"));
}
void loop()
@ -101,7 +67,9 @@ void loop()
#if WIFI_ON
WifiInterface::loop();
#endif
LCDDisplay::loop(); // ignored if LCD not in use
// Optionally report any decrease in memory (will automatically trigger on first call)
#if ENABLE_FREE_MEM_WARNING
static int ramLowWatermark = 32767; // replaced on first loop
@ -110,7 +78,7 @@ void loop()
if (freeNow < ramLowWatermark)
{
ramLowWatermark = freeNow;
DIAG(F("\nFree RAM=%d\n"), ramLowWatermark);
LCD(2,F("Free RAM=%5db"), ramLowWatermark);
}
#endif
}

11
DCC.h
View File

@ -162,16 +162,5 @@ private:
#error CANNOT COMPILE - DCC++ EX ONLY WORKS WITH AN ARDUINO UNO, NANO 328, OR ARDUINO MEGA 1280/2560
#endif
#if ENABLE_LCD
#include <Wire.h>
#if defined(LIB_TYPE_PCF8574)
#include <LiquidCrystal_PCF8574.h>
extern LiquidCrystal_PCF8574 lcdDisplay;
#elif defined(LIB_TYPE_I2C)
#include <LiquidCrystal_I2C.h>
extern LiquidCrystal_I2C lcdDisplay;
#endif
extern bool lcdEnabled;
#endif
#endif

View File

@ -11,7 +11,8 @@
#include "version.h"
#include "WifiInterface.h"
#include "EthernetInterface.h"
#include "LCD_Implementation.h"
#include "freeMemory.h"
#include <Arduino.h>
#endif

1
DIAG.h
View File

@ -20,4 +20,5 @@
#define DIAG_h
#include "StringFormatter.h"
#define DIAG StringFormatter::diag
#define LCD StringFormatter::lcd
#endif

79
LCDDisplay.cpp Normal file
View File

@ -0,0 +1,79 @@
/*
* © 2020, Chris Harlow. All rights reserved.
*
* This file is part of CommandStation-EX
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* It is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/
// CAUTION: the device dependent parts of this class are created in the .ini using LCD_Implementation.h
#include "LCDDisplay.h"
void LCDDisplay::clear() {
clearNative();
for (byte row=0;row<MAX_LCD_ROWS; row++) rowBuffer[row][0]='\0';
topRow=-1; // loop2 will fill from row 0
}
void LCDDisplay::setRow(byte line) {
hotRow=line;
hotCol=0;
}
size_t LCDDisplay::write(uint8_t b) {
if (hotRow>=MAX_LCD_ROWS || hotCol>=MAX_LCD_COLS) return -1;
rowBuffer[hotRow][hotCol]=b;
hotCol++;
rowBuffer[hotRow][hotCol]=0;
return 1;
}
void LCDDisplay::loop() {
if (!lcdDisplay) return;
lcdDisplay->loop2(false);
}
LCDDisplay* LCDDisplay::loop2(bool force) {
if ((!force) && (millis() - lastScrollTime)< LCD_SCROLL_TIME) return NULL;
lastScrollTime=millis();
clearNative();
int rowFirst=nextFilledRow();
if (rowFirst<0)return NULL; // No filled rows
setRowNative(0);
writeNative(rowBuffer[rowFirst]);
for (int slot=1;slot<lcdRows;slot++) {
int rowNext=nextFilledRow();
if (rowNext==rowFirst){
// we have wrapped around and not filled the screen
topRow=-1; // start again at first row next time.
break;
}
setRowNative(slot);
writeNative(rowBuffer[rowNext]);
}
displayNative();
return NULL;
}
int LCDDisplay::nextFilledRow() {
for (int rx=1;rx<=MAX_LCD_ROWS;rx++) {
topRow++;
topRow %= MAX_LCD_ROWS;
if (rowBuffer[topRow][0]) return topRow;
}
return -1; // No slots filled
}

63
LCDDisplay.h Normal file
View File

@ -0,0 +1,63 @@
/*
* © 2020, Chris Harlow. All rights reserved.
*
* This file is part of CommandStation-EX
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* It is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef LCDDisplay_h
#define LCDDisplay_h
#include <Arduino.h>
// This class is created in LCDisplay_Implementation.h
class LCDDisplay : public Print {
public:
static const int MAX_LCD_ROWS=8;
static const int MAX_LCD_COLS=16;
static const long LCD_SCROLL_TIME=3000; // 3 seconds
static LCDDisplay* lcdDisplay;
LCDDisplay();
void interfake(int p1, int p2, int p3);
// Internally handled functions
static void loop();
LCDDisplay* loop2(bool force);
void setRow(byte line);
void clear();
virtual size_t write(uint8_t b);
using Print::write;
private:
int nextFilledRow();
// Relay functions to the live driver
void clearNative();
void displayNative();
void setRowNative(byte line);
void writeNative(char * b);
unsigned long lastScrollTime=0;
int hotRow=0;
int hotCol=0;
int topRow=0;
int lcdRows;
void renderRow(byte row);
char rowBuffer[MAX_LCD_ROWS][MAX_LCD_COLS+1];
};
#endif

55
LCD_Implementation.h Normal file
View File

@ -0,0 +1,55 @@
/*
* © 2020, Chris Harlow. All rights reserved.
*
* This file is part of CommandStation-EX
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* It is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/
////////////////////////////////////////////////////////////////////////////////////
// This implementation is designed to be #included ONLY ONCE in the .ino
//
// It will create a driver implemntation and a shim class implementation.
// This means that other classes can reference the shim without knowing
// which libraray is involved.
////////////////////////////////////////////////////////////////////////////////////
#include "config.h"
#include <Wire.h>
#include "LCDDisplay.h"
LCDDisplay * LCDDisplay::lcdDisplay=0;
// Implement the LCDDisplay shim class as a singleton.
// Notice that the LCDDisplay class declaration (LCDDisplay.h) is independent of the library
// but the implementation is compiled here with dependencies on LCDDriver which is
// specific to the library in use.
// Thats the workaround to the drivers not all implementing a common interface.
#if defined(OLED_DRIVER)
#include "LCD_OLED.h"
#define CONDITIONAL_LCD_START for (LCDDisplay * dummy=new LCDDisplay();dummy!=NULL; dummy=dummy->loop2(true))
#elif defined(LCD_DRIVER)
#include "LCD_LCD.h"
#define CONDITIONAL_LCD_START for (LCDDisplay * dummy=new LCDDisplay();dummy!=NULL; dummy=dummy->loop2(true))
#else
#include "LCD_NONE.h"
#define CONDITIONAL_LCD_START if (false) /* NO LCD CONFIG */
#endif

37
LCD_LCD.h Normal file
View File

@ -0,0 +1,37 @@
/*
* © 2020, Chris Harlow. All rights reserved.
*
* This file is part of CommandStation-EX
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* It is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C LCDDriver(LCD_DRIVER); // set the LCD address, cols, rows
// DEVICE SPECIFIC LCDDisplay Implementation for LCD_DRIVER
LCDDisplay::LCDDisplay() {
lcdDisplay=this;
LCDDriver.init();
LCDDriver.backlight();
interfake(LCD_DRIVER);
clear();
}
void LCDDisplay::interfake(int p1, int p2, int p3) {(void)p1; (void)p2; lcdRows=p3; }
void LCDDisplay::clearNative() {LCDDriver.clear();}
void LCDDisplay::setRowNative(byte row) {
LCDDriver.setCursor(0, row);
LCDDriver.print(F(" "));
LCDDriver.setCursor(0, row);
}
void LCDDisplay::writeNative(char * b){ LCDDriver.print(b); }
void LCDDisplay::displayNative() { LCDDriver.display(); }

27
LCD_NONE.h Normal file
View File

@ -0,0 +1,27 @@
/*
* © 2020, Chris Harlow. All rights reserved.
*
* This file is part of CommandStation-EX
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* It is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/
// dummy LCD shim to keep linker happy
LCDDisplay::LCDDisplay() {}
void LCDDisplay::interfake(int p1, int p2, int p3) {(void)p1; (void)p2; (void)p3;}
void LCDDisplay::setRowNative(byte row) { (void)row;}
void LCDDisplay::clearNative() {}
void LCDDisplay::writeNative(char * b){ (void)b;} //
void LCDDisplay::displayNative(){}

57
LCD_OLED.h Normal file
View File

@ -0,0 +1,57 @@
/*
* © 2020, Chris Harlow. All rights reserved.
*
* This file is part of CommandStation-EX
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* It is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/
// OLED Implementation of LCDDisplay class
// Note: this file is optionally included by LCD_Implenentation.h
// It is NOT a .cpp file to prevent it being compiled and demanding libraraies even when not needed.
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 LCDDriver(OLED_DRIVER);
// DEVICE SPECIFIC LCDDisplay Implementation for OLED
LCDDisplay::LCDDisplay() {
if(LCDDriver.begin(SSD1306_SWITCHCAPVCC, 0x3C) || LCDDriver.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {
DIAG(F("\nOLED display found"));
delay(2000); // painful Adafruit splash pants!
lcdDisplay=this;
LCDDriver.setTextSize(1); // Normal 1:1 pixel scale
LCDDriver.setTextColor(SSD1306_WHITE); // Draw white text
interfake(OLED_DRIVER,0);
clear();
return;
}
DIAG(F("\nOLED display not found\n"));
}
void LCDDisplay::interfake(int p1, int p2, int p3) {(void)p1; lcdRows=p2/8; (void)p3;}
void LCDDisplay::clearNative() {LCDDriver.clearDisplay();}
void LCDDisplay::setRowNative(byte row) {
// Positions text write to start of row 1..n and clears previous text
int y=8*row;
LCDDriver.fillRect(0, y, LCDDriver.width(), 8, SSD1306_BLACK);
LCDDriver.setCursor(0, y);
}
void LCDDisplay::writeNative(char * b){ LCDDriver.print(b); }
void LCDDisplay::displayNative() { LCDDriver.display(); }

View File

@ -31,6 +31,8 @@
#define __FlashStringHelper char
#endif
#include "LCDDisplay.h"
bool Diag::ACK=false;
bool Diag::CMD=false;
bool Diag::WIFI=false;
@ -44,6 +46,14 @@ void StringFormatter::diag( const __FlashStringHelper* input...) {
send2(diagSerial,input,args);
}
void StringFormatter::lcd(byte row, const __FlashStringHelper* input...) {
if (!LCDDisplay::lcdDisplay) return;
LCDDisplay::lcdDisplay->setRow(row);
va_list args;
va_start(args, input);
send2(LCDDisplay::lcdDisplay,input,args);
}
void StringFormatter::send(Print * stream, const __FlashStringHelper* input...) {
va_list args;
va_start(args, input);
@ -56,7 +66,6 @@ void StringFormatter::send(Print & stream, const __FlashStringHelper* input...)
send2(&stream,input,args);
}
void StringFormatter::send2(Print * stream,const __FlashStringHelper* format, va_list args) {
// thanks to Jan Turoň https://arduino.stackexchange.com/questions/56517/formatting-strings-in-arduino-for-output
@ -66,6 +75,13 @@ void StringFormatter::send2(Print * stream,const __FlashStringHelper* format, va
char c=pgm_read_byte_near(flash+i);
if (c=='\0') return;
if(c!='%') { stream->print(c); continue; }
bool formatContinues=false;
byte formatWidth=0;
bool formatLeft=false;
do {
formatContinues=false;
i++;
c=pgm_read_byte_near(flash+i);
switch(c) {
@ -73,14 +89,34 @@ void StringFormatter::send2(Print * stream,const __FlashStringHelper* format, va
case 'c': stream->print((char) va_arg(args, int)); break;
case 's': stream->print(va_arg(args, char*)); break;
case 'e': printEscapes(stream,va_arg(args, char*)); break;
case 'E': printEscapes(stream,(const __FlashStringHelper*)va_arg(args, char*)); break;
case 'S': stream->print((const __FlashStringHelper*)va_arg(args, char*)); break;
case 'd': stream->print(va_arg(args, int), DEC); break;
case 'l': stream->print(va_arg(args, long), DEC); break;
case 'd': printPadded(stream,va_arg(args, int), formatWidth, formatLeft); break;
case 'l': printPadded(stream,va_arg(args, long), formatWidth, formatLeft); break;
case 'b': stream->print(va_arg(args, int), BIN); break;
case 'o': stream->print(va_arg(args, int), OCT); break;
case 'x': stream->print(va_arg(args, int), HEX); break;
case 'f': stream->print(va_arg(args, double), 2); break;
//format width prefix
case '-':
formatLeft=true;
formatContinues=true;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
formatWidth=formatWidth * 10 + (c-'0');
formatContinues=true;
break;
}
} while(formatContinues);
}
va_end(args);
}
@ -94,6 +130,17 @@ void StringFormatter::printEscapes(Print * stream,char * input) {
}
}
void StringFormatter::printEscapes(Print * stream, const __FlashStringHelper * input) {
if (!stream) return;
char* flash=(char*)input;
for(int i=0; ; ++i) {
char c=pgm_read_byte_near(flash+i);
printEscape(stream,c);
if (c=='\0') return;
}
}
void StringFormatter::printEscape( char c) {
printEscape(diagSerial,c);
}
@ -109,4 +156,27 @@ void StringFormatter::printEscape(Print * stream, char c) {
default: stream->print(c);
}
}
void StringFormatter::printPadded(Print* stream, long value, byte width, bool formatLeft) {
if (width==0) {
stream->print(value, DEC);
return;
}
int digits=(value <= 0)? 1: 0; // zero and negative need extra digot
long v=value;
while (v) {
v /= 10;
digits++;
}
if (formatLeft) stream->print(value, DEC);
while(digits<width) {
stream->print(' ');
digits++;
}
if (!formatLeft) stream->print(value, DEC);
}

View File

@ -27,6 +27,7 @@
#define __FlashStringHelper char
#endif
#include "LCDDisplay.h"
class Diag {
public:
static bool ACK;
@ -42,16 +43,19 @@ class StringFormatter
static void send(Print & serial, const __FlashStringHelper* input...);
static void printEscapes(Print * serial,char * input);
static void printEscapes(Print * serial,const __FlashStringHelper* input);
static void printEscape(Print * serial, char c);
// DIAG support
static Print * diagSerial;
static void diag( const __FlashStringHelper* input...);
static void lcd(byte row, const __FlashStringHelper* input...);
static void printEscapes(char * input);
static void printEscape( char c);
private:
static void send2(Print * serial, const __FlashStringHelper* input,va_list args);
static void printPadded(Print* stream, long value, byte width, bool formatLeft);
};
#endif

View File

@ -103,7 +103,7 @@ void WiThrottle::parse(Print & stream, byte * cmdx) {
// we have to take a copy of the cmd buffer as the reply will get built into the cmdx
byte local[150];
for (byte i=0;i<sizeof(local);i++) {
for (byte i=0;i<sizeof(local)-1;i++) {
local[i]=cmdx[i];
if (!cmdx[i]) break;
}

View File

@ -179,7 +179,11 @@ WifiInboundHandler::INBOUND_STATE WifiInboundHandler::loop2() {
break;
case GOT_CLIENT_ID3: // got "x C" before CLOSE or CONNECTED (which is ignored)
if(ch=='L') clientStatus[runningClientId]=UNUSED;
if(ch=='L') {
// CLOSE
clientStatus[runningClientId]=UNUSED;
if (runningClientId==clientPendingCIPSEND) clientPendingCIPSEND=-1;
}
loopState=SKIPTOEND;
break;

View File

@ -70,37 +70,17 @@ The configuration file for DCC++ EX Command Station
//
// Note: This feature requires an I2C enabled LCD screen using a PCF8574 based chipset.
// or one using a Hitachi HD44780.
//
// To enable, uncomment the line below and make sure only the correct LIB_TYPE line
// is uncommented below to select the library used for your LCD backpack
// OR an I2C Oled screen.
// To enable, uncomment one of the lines below
//#define ENABLE_LCD
#ifdef ENABLE_LCD
#define LIB_TYPE_PCF8574
//#define LIB_TYPE_I2C
// This defines the I2C address for the LCD device
#define LCD_ADDRESS 0x27 //common defaults are 0x27 and 0x3F
// This defines the number of columns the LCD device has
#define LCD_COLUMNS 16
// This defines the number of lines the LCD device has
#define LCD_LINES 2
#endif
// define LCD_DRIVER for I2C LCD address 0x3f,16 cols, 2 rows
// #define LCD_DRIVER 0x3F,16,2
//OR define OLED_DRIVER width,height in pixels (address auto detected)
// This will not work on a UNO due to memory constraints
// #define OLED_DRIVER 128,32
/////////////////////////////////////////////////////////////////////////////////////
//
// Enable custom command filtering
#define ENABLE_CUSTOM_FILTER false
/////////////////////////////////////////////////////////////////////////////////////
//
// Enable custom command filtering
#define ENABLE_CUSTOM_CALLBACK false
/////////////////////////////////////////////////////////////////////////////////////
//
// Enable custom command filtering
// Enable warning as memory gets depleted
#define ENABLE_FREE_MEM_WARNING false