Line 1 end wrap around to next line on 16.2 LCD display over lcd.write()

On my Arduino Uno with IDE 1.0.6 I got my serial interface I2C 1602 LCD working with some example sketches found on this forum (thanks for sharing). One of these sketches gave me the option to enter some characters in the Serial-Monitor. After hitting the Send-button in this window, the data is transfered into the buffers of the Arduino by the Sketch-commands: // read all the available characters while (Serial.available() > 0) { // display each character to the LCD lcd.write(Serial.read()); }

As my LCD-display is defined as: lcd.begin(16,2); I expected after entering 17 characters into the Serial-monitor, that the last character should be wrapped to the second line. What happens is that the first 16 characters are displayed in line 1 of the LCD-display and the 17th character is ignored. But if I enter over 30 characters, the second line is populated with a few of the last characters entered. In other words the LCD-definition (16,2) is not applied for wrapping a 2 x 16 characters input from the serial input.

Any suggestions how to improve this?

I'm thinking of substrings, but this is nearly a work-around for an incorrect driver.

IMG_0560[1].JPG|3264x2448

Take a look at this article on how the lcd controller memory is organized http://web.alfredstate.edu/weimandn/lcd/lcd_addressing/lcd_addressing_index.html

It explains why and where you see the line wrap.

If you want to see line wrap at character 17, you will have to count your input characters and setCursor(0,1) after 16.

Thanks that explains all.

With the "lcd.setCursor(0,1)" the second line is addressed indeed, but cursor-positions from the "Serial.read()" still refer to positions in the first line. I guess that a simple "if(Serial.read()) > 10" is not enough to get the characters shifted to the next line.

Would there be a code-example for how to place the ASCII-characters of the "Serial.read()" positions hex()10 till hex(1F) into hex(40) till hex(4F)?

Maybe an easier option is to read the Characters corresponding to Serial.read() and put these in a string of 32 characters and lcd.print() them as 2 substrings?

You should keep in mind that these displays were intended to deliver short concise messages such as "Add Toner". They were never intended to emulate or replace a computer monitor screen.

The LiquidCrystal library is primarily designed to implement the command set present in the LCD controller although it adds some simplified cursor positioning that works on most displays.

With the "lcd.setCursor(0,1)" the second line is addressed indeed, but cursor-positions from the "Serial.read()" still refer to positions in the first line.

I'm not sure what you mean by this. You can't implement cursor positioning (or any other LCD controller commands) via Serial.read().

The typically poorly explained sketch you got from the Arduino reference pages merely shows how you can display ASCII characters, in this case coming in via Serial.read(), on the display. Any commands to manipulate the display such as cursor positioning have to be provided by using other functions available in the library.

Maybe an easier option is to read the Characters corresponding to Serial.read() and put these in a string of 32 characters and lcd.print() them as 2 substrings?

I think that the solution recommended by cattledog is a lot easier.

Don

Marpytoys: On my Arduino Uno with IDE 1.0.6 I got my serial interface I2C 1602 LCD working with some example sketches found on this forum (thanks for sharing). One of these sketches gave me the option to enter some characters in the Serial-Monitor. After hitting the Send-button in this window, the data is transfered into the buffers of the Arduino by the Sketch-commands: // read all the available characters while (Serial.available() > 0) { // display each character to the LCD lcd.write(Serial.read()); }

As my LCD-display is defined as: lcd.begin(16,2); I expected after entering 17 characters into the Serial-monitor, that the last character should be wrapped to the second line. What happens is that the first 16 characters are displayed in line 1 of the LCD-display and the 17th character is ignored. But if I enter over 30 characters, the second line is populated with a few of the last characters entered. In other words the LCD-definition (16,2) is not applied for wrapping a 2 x 16 characters input from the serial input.

Any suggestions how to improve this?

I'm thinking of substrings, but this is nearly a work-around for an incorrect driver.

It's not the driver's fault. Internally, the HD44780 LCD chip character memory is laid out like this:

Line 0: Char 0, 1, 2, 3......37, 38, 39
Line 1: Char 40, 41, 42......77, 78, 79

This is done so that the same chipset can be used for any LCD from 16x2 to 40x2 without hardware changes.

When you do a LCD.setCursor (x, y) an offset is automatically added to the parameters in order to "skip into" the next line's worth of character ram and hide this memory layout.

Now, of course, the LiquidCrystal library code COULD very easily look at the row and column numbers it got from LCD.begin() and wrap intelligently (as well as handling basic control codes line newline and backspace) but alas the stock library doesn't do this.

Marpytoys:
Maybe an easier option is to read the Characters corresponding to Serial.read() and put these in a string of 32 characters and lcd.print() them as 2 substrings?

What I used to do in my Motorola 68HC11 days was to make a “virtual LCD” in ram. I could put any character anywhere I wanted it, then just call the “update_LCD” subroutine to copy the virtual LCD to the real one.

You could do something like this:

// code here.....
    char line1[16];
    char line2[16];
    sprintf (line1, "TEMP %d  F", t);
    line1[7] = 0x01; // put custom degrees symbol in buffer
    line2[0] = 'H';
    line2[1] = 'I";
    updateLcd ();
//...... more code
void updateLcd (void)
{
    uint8_t x;
    for (x = 0; x < 16; x++) {
        LCD.setCursor (x, 0);
        LCD.print ((char) line1[x]);
        LCD.setCursor (x, 1);
        LCD.print ((char) line2[x]);
    }
}

Now, the above code is slow and absurd, but it shows the idea of making it easier in your mind to “see” what you will get by using a virtual display then updating it as necessary.

Hope this helps.