void setup() {
// set up the LCD's number of columns and rows:
lcd.begin();
lcd.backlight();
// initialize the serial communications:
Serial.begin(9600);
}
void loop() {
// when characters arrive over the serial port...
if (Serial.available()) {
// wait a bit for the entire message to arrive
delay(100);
// clear the screen
lcd.clear();
// read all the available characters
while (Serial.available() > 0) {
// display each character to the LCD
lcd.write(Serial.read());
}
}
}
It is not a video monitor and should not be confused with one.
This means you have to decide what you want to print on each line. Even if you coded a means to wrap over to the second line - which you can do - you would still have a problem when you received more than 32 characters, wouldn't you?
You will have to write the code to put the characters where you want to put them on the display, and you will have to think out what the purpose of displaying them is in the first place. Clearly "lcd.write" only does this to a limited extent.
You are very lucky that the I2C backpack you have actually happens to match the LiquidCrystal_I2C library you are using. Most of the time it does not.
In answer to your question ... "How can I use both lines for long messages? ":
You have to count the characters as they arrive. After the first 16 you have to reposition the cursor to the beginning of the second row. After the next 16 you run into the problem mentioned by Paul.
Counting characters and manually doing linewrapping is a pain.
The easiest way is to switch to using the hd44780 library and use the hd44780_I2Cexp i/o class.
It has many features over the library you are using, including support for wrapping long lines.
Install the hd44780 library from the IDE library manager.
Run the included diagnostic, I2CexpDiag, to make sure everything is working.
Then you can look at and run the included LineWrap example to see an example of how to turn on and use automatic line wrapping.
The library includes lots of documentation, that can be accessed using the included Documentation example sketch included in the hd44780 library package.
Just keep in mind that currently the hd44780 library will do line wrapping but not scrolling when the bottom line is exceeded.
So if you run beyond the bottom line, it will wrap back to the top line.
i.e. a VERY long line will wrap around back to the top line and then wrap lines down and even go back to the top depending on how long it is.
Scrolling will be added, it just isn't there yet.
But for your current application, it may offer what want/need.
I am trying to get it going rurally hard but not getting any good result, lol
Idea is to send message to LCD thru Bluetooth.
Now making it scroll to 2nd line after 16 symbols. after all lines filled up, I want to go back to 0,0 and start all over.
Trying it new way with hd44780 library package
here is my current code
#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() {
Serial.begin(9600);
// lcd.begin();
int status;
status = lcd.begin(LCD_COLS, LCD_ROWS);
if(status) // non zero status means it was unsuccesful
{
status = -status; // convert negative status value to positive number
// 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() {
int i=0;
char commandbuffer[100];
if(Serial.available()){
delay(100);
while( Serial.available() && i< 99) {
commandbuffer[i++] = Serial.read();
}
commandbuffer[i++]='\0';
}
if(i>0)
Serial.println((char*)commandbuffer);
lcd.clear();
lcd.cursor();
char c = ((char*)commandbuffer);
for(int i=2*LCD_COLS*LCD_ROWS; i; i--)
lcd.print(c);
// lcd.setCursor(1, 0);
// lcd.print((char*)commandbuffer);
if(c > 0x7e) // wrap back to beginning of printable ASCII chars
c = '!';
// delay(1000);
// lcd.clear();
}
I got going! Showing two lines and all that. But somehow its very flickery and text is fading away.
I really want to make it look nice. Could you please suggest how to improve it?
Here is my code and pic
#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() {
Serial.begin(9600);
// lcd.begin();
int status;
status = lcd.begin(LCD_COLS, LCD_ROWS);
if(status) // non zero status means it was unsuccesful
{
status = -status; // convert negative status value to positive number
// 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() {
int i=0;
char commandbuffer[100];
if(Serial.available()){
delay(100);
while( Serial.available() && i< 99) {
commandbuffer[i++] = Serial.read();
}
commandbuffer[i++]='\0';
}
if(i>0)
Serial.println((char*)commandbuffer);
lcd.clear();
lcd.cursor();
char c = ((char*)commandbuffer);
for(int i=2*LCD_COLS*LCD_ROWS; i; i--)
lcd.print(c);
// lcd.setCursor(1, 0);
lcd.print((char*)commandbuffer);
// if(c > 0x7e) // wrap back to beginning of printable ASCII chars
// c = '!';
// delay(1000);
// lcd.clear();
}
So what did you do/change to get it to look better?
BTW, you can slow down the printing if you want by telling the hd44780 library that the display is very slow.
This will slow down how fast it sends the characters to the display. If set slow enough, it will slow things down enough to see the characters show on the display like they are being typed.
Just keep in mind that while this output is going on, nothing else is happening on the Arduino, so if messages are continue to come in, buffers may overflow and the messages may get lost.
To slow things down use:
setExecTimes(chUs, insUs);
chUS is the time in microseconds for the clear/home instructions - I would recommend leaving that the default of 2ms
insUs is the time in microseconds for other instructions like data writes.
To slow each character down to 100ms which will be slow enough to see the characters written to the display use:
lcd.setExecTimes(2000L, 80000L);
If you want it slower or faster just alter the 2nd parameter accordingly but don't go below the default of 38us.