Serial Read and LCD issues

guys,
need help...
I'm sending some String Text to Serial from one Arduino...

mostly this is via:

Serial.println("Hellow World");
Serial.println("AT+CLS"); //This is a command for clearing screen of LCD via serial port

and so on.

Now, the above one was serial transmitter and the serial receiver will receive them via the code below:

/*
 
 Serial config: 8N1, default baud is 9600 and user configurable.
 
 * EEPROM ADDRESSES:
   * LCD Backlight = 0-1
   * LCD type = 2-3
   * LCD BAUD = 4-5
 
*/

// include the library code:
#include <LiquidCrystal.h>
#include <EEPROM.h>

// The necessary constants
const int default_baudRate = 9600; //default
const int LCD_BL_pin = 9; //Arduino pin 9 for bakclight control via PWM

// The special commands
const String LCD_clear = "AT+CLS"; //The CLS command
const String LCD_newLine = "AT+NL"; //This is \n (new line) Currently ONLY for 2 line display
const String LCD_setCursor = "AT+CR="; //Command for setting cursor. Trailing will be Col and Row seperated by , [e.g. 02,01]
const String LCD_conf = "AT+CONF"; //Command to enter config mode from anywhere.
const String LCD_stat = "AT+STAT"; //Command to see the current running config.

// The necessary variables
String sub_str = "";
String str_rx = "";
unsigned long interval = 10000; //in ms. 
unsigned long current_time_val;
unsigned long prev_time_val = 0;
int row = 0;
int col = 0;
int backlight;
int LCD_type; //(1=16x2, 2=16x4, 3=20x2, 4=20x4)
int LCD_baud;
int LCD_col;
int LCD_row;

// initialize the library with the numbers of the interface pins
//LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);
LiquidCrystal lcd(14, 15, 16, 17, 18, 19);

void setup() {
  
  // Read the parameters from EEPROM
  backlight = EEPROMReadInt(0);
  LCD_type = EEPROMReadInt(2);
  LCD_baud = EEPROMReadInt(4);
  
  // Now config the system as per that:
  backlight = ((255*backlight)/100);
  analogWrite(LCD_BL_pin, backlight);
  switch (LCD_type) {
  case 1:    // 16x2 LCD
    LCD_col = 16;
    LCD_row = 2;
    break;
  case 2:    // 16x4 LCD
    LCD_col = 16;
    LCD_row = 4;
    break;
  case 3:    // 20x2 LCD
    LCD_col = 20;
    LCD_row = 2;
    break;
  case 4:    // 20x4 LCD
    LCD_col = 20;
    LCD_row = 4;
    break;
    
  default :
    LCD_col = 16;
    LCD_row = 2;
    break;
  } 
  
  // set up the LCD's number of columns and rows: 
  lcd.begin(LCD_col, LCD_row);
  // initialize the serial communications with default baud of 9600 for config mode:
  Serial.begin(default_baudRate);
    
  //The splash screen. Branding indeed...
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.write("Serial LCD");
  lcd.setCursor(0,1);
  lcd.write("Firmware 1.1");
  smartDelay(1500);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.write("An R&D From");
  lcd.setCursor(0,1);
  lcd.write("banglardamal.org");
  smartDelay(1500);
  lcd.clear();
  Serial.println("Splash Screen Printed");

  //Config the display
  if ((str_rx == LCD_conf) || (str_rx == "conf t")) {
    str_rx = ""; 
    configMode();
  }
  
  //config complete/no config requires, move to operational config.
  Serial.end();
  Serial.begin(LCD_baud);
  
}

void loop() 
{
  str_rx = "";
  sub_str = "";
  
  // when characters arrive over the serial port...
  if (Serial.available() > 0) {
    //Read until the newline \n comes from serial
    str_rx = String(Serial.readStringUntil('\n'));
    analogWrite(LCD_BL_pin, backlight);
    prev_time_val = current_time_val; //Reset the timeout for one more full cycle
    
    //Set parameters like line number, and then print data.
    if (str_rx == LCD_clear) { //The CLS.
      lcd.clear();
      str_rx = "";    
    }
    
    if (str_rx == LCD_newLine) { //currently only for 2 line display
      lcd.setCursor(0,1);
      str_rx = "";   
    }

    if (str_rx.startsWith(LCD_setCursor)) { //Set cursor to Col, Row
      sub_str = str_rx.substring(6,8); //Skip the AT+CR= And Col is two char. (01)
      col = sub_str.toInt();
      sub_str = str_rx.substring(9,11); //Row is after the , and till \n, two char (01)
      row = sub_str.toInt();
      lcd.setCursor(col, row);
      str_rx = "";
    }    
      
    if (str_rx == LCD_conf) { // Conf mode force entry
      str_rx = ""; 
      configMode();   
    }
    
    else { // display each character to the LCD
      lcd.print(str_rx);
    }
  }
  //The timeout for BackLight dimming
  LCD_BL_dim();
}

// This custom version of delay() ensures that the gps object is being "fed".
static void smartDelay(unsigned long ms) {
  unsigned long start = millis();
  do {
    //while (Serial.available()){
    while (Serial.available() > 0){  
      str_rx = String(Serial.readStringUntil('\n'));
    }
  } 
  while (millis() - start < ms);
}

// Function for LCD Backlight dimming
void LCD_BL_dim() {
  current_time_val = millis();
  if ((current_time_val - prev_time_val) > interval) {
    prev_time_val = current_time_val; 
    analogWrite(LCD_BL_pin, 5);
  }    
}

And for simplicity, i haven't added the extra functions here... but functions works fine.

Now, when I use the serial monitor and type something to my arduino+LCD, it works "exactly" fine. Then when I send a string via the serial of another arduino, i get nothing or garbage... even all scattered and not the way it was supposed to be... (serial monitor works fully ok).

any ideas where i'm missing something??

Connected the GND between the two Arduino's?

yepp

Which pins are being used for the serial interface to the LCD ?

i'm using atmega328 with lcd. there the hardware UART is being used... and for other one, normally i prefer to use software uart...

pins are all in perfect order and lcd interfacing is also ok... those have been checked... the first line from the other arduino comes to serial-lcd device perfectly and then it's not working... somewhere something is wrong, as direct serial input from PC works 100% perfect

So, are you using hardware serial (pins 0 and 1) to communicate with the LCD and the Serial monitor within the same program ? I see no sign of SoftwareSerial in the program that you posted.

aq_mishu:
Now, when I use the serial monitor and type something to my arduino+LCD, it works "exactly" fine. Then when I send a string via the serial of another arduino, i get nothing or garbage...

Is your other Arduino adding a newline at the end of the transmission?

If you use the code in the Thread serial input basics (rather than readBytesuntil() ) for debug purposes you could temporarily print out the data that is actually received as it is received.

...R

Okey,
First of all, When i type in terminal, it's fine...

now using an arduino board, when i send text using Serial.println("abc"); then it's not properly coming out

[please do consider, i have used AT+CLS for LCD clear, and before each writing, though i am sending this, not helping.]

Now, in the board where the LDC is hooked, that is having this code that i posted at the beginning.

From the source arduino, i tired both hardware and software serials.

Is the BAUD rate of the transmitter and receiver boards the same?

yep... baud is fine... the texts are coming, but not in proper format

When you send "abc", what do you get?

i get abc... but when sending AT+CLS for clearing screen or when sending newlines or these, it is not reacting perfectly...

sometimes even other texts are also not coming full...

Anyway, first tell me, can you find any error in code?? or it looks fine???

Mens when Arduino 1 will send "hello world"; "AT+CLS" as clear screen, "my name: ", "AT+NL" as new line and "Mishu" and oops, if increment number say SL Num 1,.... then will it do that??

Arduino 2 is the receiver that will run the code i attached above.

aq_mishu:
Mens when Arduino 1 will send "hello world"; "AT+CLS" as clear screen, "my name: ", "AT+NL" as new line and "Mishu" and oops, if increment number say SL Num 1,.... then will it do that??

This looks to me like a jumble. Are you trying to say that Arduino 1 sends 5 separate messages like this
hello world
AT+CLS
my name:
AT+NL
Mishu

What has "oops" got to do with it?

Is the line AT+CLS the 6 characters A T + C L and S ?

Did you try my suggestion in Reply #6 so that you can see what is actually being received?

Draw a diagram showing clearly how everything is connected and post a photo of the drawing.

...R

guys,

Just use the same board, no LCD at all... just one Software serial out and hardware serial in.

Then the code was simple::

  delay(2000);
  i = i++;
  portOne.print("sample: ");
  portOne.println(i);
  delay(1000);
  portOne.println("AT+CLS");

for software serial and then output came as

Splash Screen Printed
input came: sample: 1
input came: AT+CLS
input came: sample: 2
input came: AT+CLS
input came: sample: 3
input came: AT+CLS
input came: sample: 4
input came: AT+CLS
input came: sample: 5
input came: AT+CLS
input came: sample: 6
input came: AT+CLSsample: sample: 8
input came: sample: sample: 10sample: sample: 12sample: 13
input came: AT+CLS
input came: sample: 14
input came: AT+CLS
input came: sample: 15
input came: AT+CLS

in hardware serial.

Used mega2560 board, pin3 for sSerial Tx, and Hardware Serial as Rx.
AT+CLS has 6 chars.

any idea guys???

aq_mishu:
Then the code was simple::

aq_mishu:
any idea guys???

When you said "then the code was simple" I assumed you had everything working.

Is the code in Reply #13 your latest version?
Remind us of what actually happens and what you would like to happen?

...R

yep... just made some modification to see the output in serial. as I'm using the same board for testing purpose...

Actually i'm planning to make my own lcd-backpack...

Update::::

A small update... i think the buffer is getting full (though there is no particular reason for such small strings). I'm doing a different approach... adding a small delay from 10 till 1000 (i call smart delay actually, that i copied from other source)... and printing the mills() value using a loop... to constantly see what happens...

How about answering the 2 questions in Reply #15

And post the latest code.

...R

ok... all i was looking for is to make a Serial LCD backpack based on ATMega328p. (SMD Version). Which is also a clone (or customised in my own size) of Arduino Nano.

So, I want that a uC will send text over serial (not PC, but uC). And this backpack will receive it, and will send it to LCD. [actually i need to save some pins on my actual uC and thus need a slave for driving the display].

Now, here is the latest code, and output is still

Splash Screen Printed
input came: sample: 1
input came: AT+CLS
input came: sample: 2
input came: AT+CLS
input came: sample: 3
input came: AT+CLS
input came: sample: 4
input came: AT+CLS
input came: sample: 5
input came: AT+CLS
input came: sample: 6
input came: AT+CLSsample: sample: 8
input came: sample: sample: 10sample: sample: 12sample: 13
input came: AT+CLS
input came: sample: 14
input came: AT+CLS
input came: sample: 15
input came: AT+CLS

=================

The uC is sending using SoftSerial and the backpack is receiving using HW Serial. Bauds are fine. The code i'm posting here is the latest (and i'm using the same board for this time for the test drive only... a m2560)

#include <SoftwareSerial.h> //test

SoftwareSerial portOne(2,3); //test

/*
 LCD Backpack - Serial Input
 
 Firmware Version 1.1
 Firmware Release Date: dd/mm/yyyy
 For Hardware Version 1.x (except 1.1)
 
 Written By: Abdul Quader Munshi (Mishu) (S21VM)
             aq_mishu@yahoo.com
             
 Developed for: banglardamal.org
 
 The Target Hardware is based on ATmega 328 chip, 16MHz XTAL. Thus Arduino
 code must be according to same. (Try Arduino nano 328)
 
 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the 
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.
 
 This sketch displays text sent over the serial port 
 (e.g. from the Serial Monitor) on an attached LCD.
 
 The circuit:
 * LCD RS pin to digital pin D14
 * LCD Enable pin to digital pin D15
 * LCD D4 pin to digital D16
 * LCD D5 pin to digital D17
 * LCD D6 pin to digital D18
 * LCD D7 pin to digital D19
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 
 Serial config: 8N1, default baud is 9600 and user configurable.
 
 * EEPROM ADDRESSES:
   * LCD Backlight = 0-1
   * LCD type = 2-3
   * LCD BAUD = 4-5
 
*/

// include the library code:
#include <LiquidCrystal.h>
#include <EEPROM.h>

int i=0; //test

// The necessary constants
const int default_baudRate = 9600; //default
const int LCD_BL_pin = 13; //Arduino pin 9 for bakclight control via PWM

// The special commands
const String LCD_clear = "AT+CLS"; //The CLS command
const String LCD_newLine = "AT+NL"; //This is \n (new line) Currently ONLY for 2 line display
const String LCD_setCursor = "AT+CR="; //Command for setting cursor. Trailing will be Col and Row seperated by , [e.g. 02,01]
const String LCD_conf = "AT+CONF"; //Command to enter config mode from anywhere.
const String LCD_stat = "AT+STAT"; //Command to see the current running config.

// The necessary variables
String sub_str = "";
String str_rx = "";
unsigned long interval = 10000; //in ms. 
unsigned long current_time_val;
unsigned long prev_time_val = 0;
int row = 0;
int col = 0;
int backlight;
int LCD_type; //(1=16x2, 2=16x4, 3=20x2, 4=20x4)
int LCD_baud;
int LCD_col;
int LCD_row;

// initialize the library with the numbers of the interface pins
//LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);
LiquidCrystal lcd(14, 15, 16, 17, 18, 19);

void setup() {
  
  // Read the parameters from EEPROM
  backlight = EEPROMReadInt(0);
  LCD_type = EEPROMReadInt(2);
  LCD_baud = EEPROMReadInt(4);
  
  // Now config the system as per that:
  backlight = ((255*backlight)/100);
  analogWrite(LCD_BL_pin, backlight);
  switch (LCD_type) {
  case 1:    // 16x2 LCD
    LCD_col = 16;
    LCD_row = 2;
    break;
  case 2:    // 16x4 LCD
    LCD_col = 16;
    LCD_row = 4;
    break;
  case 3:    // 20x2 LCD
    LCD_col = 20;
    LCD_row = 2;
    break;
  case 4:    // 20x4 LCD
    LCD_col = 20;
    LCD_row = 4;
    break;
    
  default :
    LCD_col = 16;
    LCD_row = 2;
    break;
  } 
  
  // set up the LCD's number of columns and rows: 
  lcd.begin(LCD_col, LCD_row);
  // initialize the serial communications with default baud of 9600 for config mode:
  Serial.begin(default_baudRate);
    
  //The splash screen. Branding indeed...
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Serial LCD");
  lcd.setCursor(0,1);
  lcd.print("Firmware 1.1");
  smartDelay(1500);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("An R&D From");
  lcd.setCursor(0,1);
  lcd.print("banglardamal.org");
  smartDelay(1500);
  lcd.clear();
  Serial.println("Splash Screen Printed");

  //Config the display
  if ((str_rx == LCD_conf) || (str_rx == "conf t")) {
    str_rx = ""; 
    configMode();
  }
  
  //config complete/no config requires, move to operational config.
  Serial.end();
  Serial.begin(LCD_baud);
  portOne.begin(LCD_baud);
  
}

void loop() 
{
  str_rx = "";
  sub_str = "";
  
  //test start
 
  portOne.println("AT+CLS");
  delay(1000);
  portOne.print("Time: ");
  portOne.println(millis());
  delay(1000);
  //test done
  
  // when characters arrive over the serial port...
  
  if (Serial.available() > 0) {
    //Read until the newline \n comes from serial
    str_rx = String(Serial.readStringUntil('\n'));
    Serial.println(str_rx);
    analogWrite(LCD_BL_pin, backlight);
    prev_time_val = current_time_val; //Reset the timeout for one more full cycle
    
    //Set parameters like line number, and then print data.
    if (str_rx == LCD_clear) { //The CLS.
      lcd.clear();
      str_rx = "";    
    }
    
    if (str_rx == LCD_newLine) { //currently only for 2 line display
      lcd.setCursor(0,1);
      str_rx = "";   
    }

    if (str_rx.startsWith(LCD_setCursor)) { //Set cursor to Col, Row
      sub_str = str_rx.substring(6,8); //Skip the AT+CR= And Col is two char. (01)
      col = sub_str.toInt();
      sub_str = str_rx.substring(9,11); //Row is after the , and till \n, two char (01)
      row = sub_str.toInt();
      lcd.setCursor(col, row);
      str_rx = "";
    }    
      
    if (str_rx == LCD_conf) { // Conf mode force entry
      str_rx = ""; 
      configMode();   
    }
    
    else { // display each character to the LCD
      lcd.print(str_rx);
      
    }
  }
  //The timeout for BackLight dimming
  LCD_BL_dim();
}

// This custom version of delay() ensures that the gps object is being "fed".
static void smartDelay(unsigned long ms) {
  unsigned long start = millis();
  do {
    //while (Serial.available()){
    while (Serial.available() > 0){  
      str_rx = String(Serial.readStringUntil('\n'));
    }
  } 
  while (millis() - start < ms);
}

// Function for LCD Backlight dimming
void LCD_BL_dim() {
  current_time_val = millis();
  if ((current_time_val - prev_time_val) > interval) {
    prev_time_val = current_time_val; 
    analogWrite(LCD_BL_pin, 5);
  }    
}

// Config mode function
void configMode() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.write("Config Mode");   
  Serial.println("Config mode");
  while (str_rx != "exit") {
    if (Serial.available() > 0) {
      //Read until the newline \n comes from serial
      str_rx = String(Serial.readStringUntil('\n'));
    }
    
    if (str_rx.startsWith("bright=")) { //Set cursor to Col, Row
      sub_str = str_rx.substring(7); //Skip the AT+CR= And Col is two char. (01)
      int blBright = sub_str.toInt();
      EEPROMWriteInt(0, blBright);
      analogWrite(LCD_BL_pin, blBright);
      Serial.print("Brightness set to: ");
      Serial.print(blBright);
      Serial.println("%");
      str_rx = "";
      sub_str = "";
    }
    
    if (str_rx.startsWith("baud=")) { //Set cursor to Col, Row
      sub_str = str_rx.substring(5); //Skip the AT+CR= And Col is two char. (01)
      int newBaud = sub_str.toInt();
      EEPROMWriteInt(4, newBaud);
      Serial.print("Baud Rate set to: ");
      Serial.println(newBaud);
      str_rx = "";
      sub_str = "";
    }
    
    if (str_rx.startsWith("lcdtype=")) { //Set cursor to Col, Row
      sub_str = str_rx.substring(8); //Skip the AT+CR= And Col is two char. (01)
      int LCD_type = sub_str.toInt();
      EEPROMWriteInt(2, LCD_type);
      Serial.print("LCD Type set to: ");
      Serial.println(LCD_type);
      str_rx = "";
      sub_str = "";
    }
    
  }
  soft_reset();
}

//This function will write a 2 byte integer to the eeprom at the specified address and address + 1
void EEPROMWriteInt(int p_address, int p_value) {
  byte lowByte = ((p_value >> 0) & 0xFF);
  byte highByte = ((p_value >> 8) & 0xFF);
  EEPROM.write(p_address, lowByte);
  EEPROM.write(p_address + 1, highByte);
}

//This function will read a 2 byte integer from the eeprom at the specified address and address + 1
unsigned int EEPROMReadInt(int p_address) {
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);
  return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}


void soft_reset() {
  Serial.println("Reboot in 3 seconds...");
  delay(3000); 
  asm volatile (" jmp 0 "); 
}