mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-27 19:57:38 +00:00
P012 - Fix/handle lines exceeding LCD width + allow to clear line b4 print (#852)
* Update Library LiquidCrystal_I2C to the latest version * Fix LCD command (when message is longer than columns) that get split into the wrong lines - issue #603 * Added a "LCD command mode" parameter to handle how exceeding message would be treated, and if the line should be first padded with space.
This commit is contained in:
Regular → Executable
+21
-11
@@ -1,11 +1,4 @@
|
||||
//www.DFRobot.com
|
||||
//last updated on 21/12/2011
|
||||
//Tim Starling Fix the reset bug (Thanks Tim)
|
||||
//wiki doc http://www.dfrobot.com/wiki/index.php?title=I2C/TWI_LCD1602_Module_(SKU:_DFR0063)
|
||||
//Support Forum: http://www.dfrobot.com/forum/
|
||||
//Compatible with the Arduino IDE 1.0
|
||||
//Library version:1.1
|
||||
|
||||
// Based on the work by DFRobot
|
||||
|
||||
#include "LiquidCrystal_I2C.h"
|
||||
#include <inttypes.h>
|
||||
@@ -16,7 +9,7 @@
|
||||
#define printIIC(args) Wire.write(args)
|
||||
inline size_t LiquidCrystal_I2C::write(uint8_t value) {
|
||||
send(value, Rs);
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -59,6 +52,11 @@ LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t l
|
||||
_backlightval = LCD_NOBACKLIGHT;
|
||||
}
|
||||
|
||||
void LiquidCrystal_I2C::oled_init(){
|
||||
_oled = true;
|
||||
init_priv();
|
||||
}
|
||||
|
||||
void LiquidCrystal_I2C::init(){
|
||||
init_priv();
|
||||
}
|
||||
@@ -134,6 +132,7 @@ void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
|
||||
void LiquidCrystal_I2C::clear(){
|
||||
command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero
|
||||
delayMicroseconds(2000); // this command takes a long time!
|
||||
if (_oled) setCursor(0,0);
|
||||
}
|
||||
|
||||
void LiquidCrystal_I2C::home(){
|
||||
@@ -221,6 +220,15 @@ void LiquidCrystal_I2C::createChar(uint8_t location, uint8_t charmap[]) {
|
||||
}
|
||||
}
|
||||
|
||||
//createChar with PROGMEM input
|
||||
void LiquidCrystal_I2C::createChar(uint8_t location, const char *charmap) {
|
||||
location &= 0x7; // we only have 8 locations 0-7
|
||||
command(LCD_SETCGRAMADDR | (location << 3));
|
||||
for (int i=0; i<8; i++) {
|
||||
write(pgm_read_byte_near(charmap++));
|
||||
}
|
||||
}
|
||||
|
||||
// Turn the (optional) backlight off/on
|
||||
void LiquidCrystal_I2C::noBacklight(void) {
|
||||
_backlightval=LCD_NOBACKLIGHT;
|
||||
@@ -309,6 +317,8 @@ void LiquidCrystal_I2C::printstr(const char c[]){
|
||||
|
||||
|
||||
// unsupported API functions
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
void LiquidCrystal_I2C::off(){}
|
||||
void LiquidCrystal_I2C::on(){}
|
||||
void LiquidCrystal_I2C::setDelay (int cmdDelay,int charDelay) {}
|
||||
@@ -318,5 +328,5 @@ uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t graphtype){return 0;}
|
||||
void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_col_end){}
|
||||
void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len, uint8_t pixel_row_end){}
|
||||
void LiquidCrystal_I2C::setContrast(uint8_t new_val){}
|
||||
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
||||
Regular → Executable
+7
-2
@@ -1,4 +1,4 @@
|
||||
//DFRobot.com
|
||||
//YWROBOT
|
||||
#ifndef LiquidCrystal_I2C_h
|
||||
#define LiquidCrystal_I2C_h
|
||||
|
||||
@@ -77,14 +77,18 @@ public:
|
||||
void autoscroll();
|
||||
void noAutoscroll();
|
||||
void createChar(uint8_t, uint8_t[]);
|
||||
void createChar(uint8_t location, const char *charmap);
|
||||
// Example: const char bell[8] PROGMEM = {B00100,B01110,B01110,B01110,B11111,B00000,B00100,B00000};
|
||||
|
||||
void setCursor(uint8_t, uint8_t);
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
virtual size_t write(uint8_t);
|
||||
#else
|
||||
virtual void write(uint8_t);
|
||||
#endif
|
||||
void command(uint8_t);
|
||||
void init();
|
||||
void oled_init();
|
||||
|
||||
////compatibility API function aliases
|
||||
void blink_on(); // alias for blink()
|
||||
@@ -118,6 +122,7 @@ private:
|
||||
uint8_t _displaycontrol;
|
||||
uint8_t _displaymode;
|
||||
uint8_t _numlines;
|
||||
bool _oled = false;
|
||||
uint8_t _cols;
|
||||
uint8_t _rows;
|
||||
uint8_t _backlightval;
|
||||
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
# LiquidCrystal_I2C
|
||||
LiquidCrystal Arduino library for the DFRobot I2C LCD displays
|
||||
@@ -1,69 +0,0 @@
|
||||
1,6c1
|
||||
< //www.DFRobot.com
|
||||
< //last updated on 26/11/2010
|
||||
< //Tim Starling Fix the reset bug (Thanks Tim)
|
||||
< //wiki doc http://www.dfrobot.com/wiki/index.php?title=I2C/TWI_LCD1602_Module_(SKU:_DFR0063)
|
||||
< //Support Forum: http://www.dfrobot.com/forum/
|
||||
<
|
||||
---
|
||||
> // LiquidCrystal_I2C V2.0
|
||||
10d4
|
||||
< #include "WProgram.h"
|
||||
12c6
|
||||
<
|
||||
---
|
||||
> #include "Arduino.h"
|
||||
67c61
|
||||
< delay(50);
|
||||
---
|
||||
> delayMicroseconds(50000);
|
||||
77,90c71,84
|
||||
< // we start in 8bit mode, try to set 4 bit mode
|
||||
< write4bits(0x03 << 4);
|
||||
< delayMicroseconds(4500); // wait min 4.1ms
|
||||
<
|
||||
< // second try
|
||||
< write4bits(0x03 << 4);
|
||||
< delayMicroseconds(4500); // wait min 4.1ms
|
||||
<
|
||||
< // third go!
|
||||
< write4bits(0x03 << 4);
|
||||
< delayMicroseconds(150);
|
||||
<
|
||||
< // finally, set to 4-bit interface
|
||||
< write4bits(0x02 << 4);
|
||||
---
|
||||
> // we start in 8bit mode, try to set 4 bit mode
|
||||
> write4bits(0x03);
|
||||
> delayMicroseconds(4500); // wait min 4.1ms
|
||||
>
|
||||
> // second try
|
||||
> write4bits(0x03);
|
||||
> delayMicroseconds(4500); // wait min 4.1ms
|
||||
>
|
||||
> // third go!
|
||||
> write4bits(0x03);
|
||||
> delayMicroseconds(150);
|
||||
>
|
||||
> // finally, set to 4-bit interface
|
||||
> write4bits(0x02);
|
||||
225c219
|
||||
< inline void LiquidCrystal_I2C::write(uint8_t value) {
|
||||
---
|
||||
> inline size_t LiquidCrystal_I2C::write(uint8_t value) {
|
||||
226a221
|
||||
> return 0;
|
||||
235,238c230,233
|
||||
< uint8_t highnib=value&0xf0;
|
||||
< uint8_t lownib=(value<<4)&0xf0;
|
||||
< write4bits((highnib)|mode);
|
||||
< write4bits((lownib)|mode);
|
||||
---
|
||||
> uint8_t highnib=value>>4;
|
||||
> uint8_t lownib=value & 0x0F;
|
||||
> write4bits((highnib)|mode);
|
||||
> write4bits((lownib)|mode);
|
||||
248c243
|
||||
< Wire.send((int)(_data) | _backlightval);
|
||||
---
|
||||
> Wire.write((int)(_data) | _backlightval);
|
||||
Regular → Executable
+4
-4
@@ -1,4 +1,4 @@
|
||||
//DFRobot.com
|
||||
//YWROBOT
|
||||
//Compatible with the Arduino IDE 1.0
|
||||
//Library version:1.1
|
||||
#include <Wire.h>
|
||||
@@ -19,7 +19,7 @@ uint8_t check[8] = {0x0,0x1,0x3,0x16,0x1c,0x8,0x0};
|
||||
uint8_t cross[8] = {0x0,0x1b,0xe,0x4,0xe,0x1b,0x0};
|
||||
uint8_t retarrow[8] = { 0x1,0x1,0x5,0x9,0x1f,0x8,0x4};
|
||||
|
||||
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
|
||||
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
|
||||
|
||||
void setup()
|
||||
{
|
||||
@@ -52,7 +52,7 @@ void displayKeyCodes(void) {
|
||||
while (1) {
|
||||
lcd.clear();
|
||||
lcd.print("Codes 0x"); lcd.print(i, HEX);
|
||||
lcd.print("-0x"); lcd.print(i+16, HEX);
|
||||
lcd.print("-0x"); lcd.print(i+15, HEX);
|
||||
lcd.setCursor(0, 1);
|
||||
for (int j=0; j<16; j++) {
|
||||
lcd.printByte(i+j);
|
||||
@@ -67,4 +67,4 @@ void loop()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Regular → Executable
+11
-3
@@ -1,20 +1,28 @@
|
||||
//DFRobot.com
|
||||
//YWROBOT
|
||||
//Compatible with the Arduino IDE 1.0
|
||||
//Library version:1.1
|
||||
#include <Wire.h>
|
||||
#include <LiquidCrystal_I2C.h>
|
||||
|
||||
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
|
||||
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
|
||||
|
||||
void setup()
|
||||
{
|
||||
lcd.init(); // initialize the lcd
|
||||
|
||||
lcd.init();
|
||||
// Print a message to the LCD.
|
||||
lcd.backlight();
|
||||
lcd.setCursor(3,0);
|
||||
lcd.print("Hello, world!");
|
||||
lcd.setCursor(2,1);
|
||||
lcd.print("Ywrobot Arduino!");
|
||||
lcd.setCursor(0,2);
|
||||
lcd.print("Arduino LCM IIC 2004");
|
||||
lcd.setCursor(2,3);
|
||||
lcd.print("Power By Ec-yuan!");
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
}
|
||||
|
||||
Regular → Executable
+2
-2
@@ -1,14 +1,14 @@
|
||||
/*
|
||||
* Displays text sent over the serial port (e.g. from the Serial Monitor) on
|
||||
* an attached LCD.
|
||||
* DFRobot.com
|
||||
* YWROBOT
|
||||
*Compatible with the Arduino IDE 1.0
|
||||
*Library version:1.1
|
||||
*/
|
||||
#include <Wire.h>
|
||||
#include <LiquidCrystal_I2C.h>
|
||||
|
||||
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
|
||||
LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
|
||||
|
||||
void setup()
|
||||
{
|
||||
|
||||
Regular → Executable
Executable
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "LiquidCrystal_I2C",
|
||||
"keywords": "LCD, liquidcrystal, I2C",
|
||||
"description": "A library for DFRobot I2C LCD displays",
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/marcoschwartz/LiquidCrystal_I2C.git"
|
||||
},
|
||||
"frameworks": "arduino",
|
||||
"platforms":
|
||||
[
|
||||
"atmelavr",
|
||||
"espressif8266"
|
||||
]
|
||||
}
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
name=LiquidCrystal_I2C
|
||||
version=1.1.4
|
||||
author=Frank de Brabander
|
||||
maintainer=Marco Schwartz <marcolivier.schwartz@gmail.com>
|
||||
sentence=A library for I2C LCD displays.
|
||||
paragraph= The library allows to control I2C displays with functions extremely similar to LiquidCrystal library. THIS LIBRARY MIGHT NOT BE COMPATIBLE WITH EXISTING SKETCHES.
|
||||
category=Display
|
||||
url=https://github.com/marcoschwartz/LiquidCrystal_I2C
|
||||
architectures=avr
|
||||
+81
-10
@@ -68,6 +68,7 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
|
||||
}
|
||||
addFormSelectorI2C(string, F("plugin_012_adr"), 16, optionValues, choice);
|
||||
|
||||
|
||||
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
|
||||
String options2[2];
|
||||
options2[0] = F("2 x 16");
|
||||
@@ -75,6 +76,7 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
|
||||
int optionValues2[2] = { 1, 2 };
|
||||
addFormSelector(string, F("Display Size"), F("plugin_012_size"), 2, options2, optionValues2, choice2);
|
||||
|
||||
|
||||
char deviceTemplate[4][80];
|
||||
LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));
|
||||
for (byte varNr = 0; varNr < 4; varNr++)
|
||||
@@ -88,14 +90,23 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
|
||||
string += F("'>");
|
||||
}
|
||||
|
||||
string += F("<TR><TD>Display button:<TD>");
|
||||
|
||||
addRowLabel(string, "Display button");
|
||||
addPinSelect(false, string, "taskdevicepin3", Settings.TaskDevicePin3[event->TaskIndex]);
|
||||
|
||||
char tmpString[128];
|
||||
|
||||
char tmpString[128];
|
||||
sprintf_P(tmpString, PSTR("<TR><TD>Display Timeout:<TD><input type='text' name='plugin_12_timer' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
|
||||
string += tmpString;
|
||||
|
||||
|
||||
String options3[3];
|
||||
options3[0] = F("Continue to next line (as in v1.4)");
|
||||
options3[1] = F("Truncate exceeding message");
|
||||
options3[2] = F("Clear then truncate exceeding message");
|
||||
int optionValues3[3] = { 0,1,2 };
|
||||
addFormSelector(string, F("LCD command Mode"), F("plugin_012_mode"), 3, options3, optionValues3, Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
|
||||
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
@@ -105,6 +116,7 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_012_adr"));
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_012_size"));
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = getFormItemInt(F("plugin_12_timer"));
|
||||
Settings.TaskDevicePluginConfig[event->TaskIndex][3] = getFormItemInt(F("plugin_012_mode"));
|
||||
|
||||
char deviceTemplate[4][80];
|
||||
for (byte varNr = 0; varNr < 4; varNr++)
|
||||
@@ -201,29 +213,88 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
|
||||
|
||||
case PLUGIN_WRITE:
|
||||
{
|
||||
byte rows = 2;
|
||||
byte cols = 16;
|
||||
if (Settings.TaskDevicePluginConfig[event->TaskIndex][1] == 2){
|
||||
rows = 4;
|
||||
cols = 20;
|
||||
}
|
||||
|
||||
String tmpString = string;
|
||||
int argIndex = tmpString.indexOf(',');
|
||||
if (argIndex)
|
||||
tmpString = tmpString.substring(0, argIndex);
|
||||
|
||||
if (lcd && tmpString.equalsIgnoreCase(F("LCD")))
|
||||
{
|
||||
success = true;
|
||||
argIndex = string.lastIndexOf(',');
|
||||
tmpString = string.substring(argIndex + 1);
|
||||
lcd->setCursor(event->Par2 - 1, event->Par1 - 1);
|
||||
lcd->print(tmpString.c_str());
|
||||
|
||||
int colPos = event->Par2 - 1;
|
||||
int rowPos = event->Par1 - 1;
|
||||
|
||||
//clear line before writing new string
|
||||
if (Settings.TaskDevicePluginConfig[event->TaskIndex][3] == 2){
|
||||
lcd->setCursor(colPos, rowPos);
|
||||
for (byte i = colPos; i < cols; i++) {
|
||||
lcd->print(F(" "));
|
||||
}
|
||||
}
|
||||
|
||||
// truncate message exceeding cols
|
||||
lcd->setCursor(colPos, rowPos);
|
||||
if(Settings.TaskDevicePluginConfig[event->TaskIndex][3] == 1 || Settings.TaskDevicePluginConfig[event->TaskIndex][3] == 2){
|
||||
lcd->setCursor(colPos, rowPos);
|
||||
for (byte i = 0; i < cols - colPos; i++) {
|
||||
if(tmpString[i]){
|
||||
lcd->print(tmpString[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// message exceeding cols will continue to next line
|
||||
else{
|
||||
// Fix Weird (native) lcd display behaviour that split long string into row 1,3,2,4, instead of 1,2,3,4
|
||||
boolean stillProcessing = 1;
|
||||
byte charCount = 1;
|
||||
while(stillProcessing) {
|
||||
if (++colPos > cols) { // have we printed 20 characters yet (+1 for the logic)
|
||||
rowPos += 1;
|
||||
lcd->setCursor(0,rowPos); // move cursor down
|
||||
colPos = 1;
|
||||
}
|
||||
|
||||
//dont print if "lower" than the lcd
|
||||
if(rowPos < rows ){
|
||||
lcd->print(tmpString[charCount - 1]);
|
||||
}
|
||||
|
||||
if (!tmpString[charCount]) { // no more chars to process?
|
||||
stillProcessing = 0;
|
||||
}
|
||||
charCount += 1;
|
||||
}
|
||||
//lcd->print(tmpString.c_str());
|
||||
// end fix
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (lcd && tmpString.equalsIgnoreCase(F("LCDCMD")))
|
||||
{
|
||||
success = true;
|
||||
argIndex = string.lastIndexOf(',');
|
||||
tmpString = string.substring(argIndex + 1);
|
||||
if (tmpString.equalsIgnoreCase(F("Off")))
|
||||
lcd->noBacklight();
|
||||
else if (tmpString.equalsIgnoreCase(F("On")))
|
||||
lcd->backlight();
|
||||
else if (tmpString.equalsIgnoreCase(F("Clear")))
|
||||
lcd->clear();
|
||||
if (tmpString.equalsIgnoreCase(F("Off"))){
|
||||
lcd->noBacklight();
|
||||
}
|
||||
else if (tmpString.equalsIgnoreCase(F("On"))){
|
||||
lcd->backlight();
|
||||
}
|
||||
else if (tmpString.equalsIgnoreCase(F("Clear"))){
|
||||
lcd->clear();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user