A frustrating lcd.clear() with LED !! Please Help !!

Hi all, the code below, why the line lcd.clear(); <—aware !!! after deleted, the LED 13 won’t light up and LCD won’t print out. why?? what does it matter the lcd.clean with LED 13 ?? what’s the relation ??
but if the lcd.clear(); stayed, then LED 13 light up and LCD print out perfectly. Please anybody help. =(

#include <LiquidCrystal.h>
#include <String.h>
#define  LED_PIN  13
#define  RESET  0
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
byte buffer; 
char bufferString[20]; 
int index = 0;

void setup() {
  Serial.begin(9600);
  pinMode(LED_PIN, OUTPUT);
  lcd.begin(16, 2);
}

void loop () {
  
  if(Serial.available()>0) 
  {  memset(bufferString,0,index);
     index = RESET;
     while (Serial.available()>0 && index < 20 )
     {  
        lcd.clear();                             // <<------------------aware !!!!!!!!-----------------
        buffer = Serial.read();             
        bufferString[index] = buffer;   
        index++;                              
     } 
     bufferString[index] = '\0';           

     if(strcmp(bufferString, "On")  == 0)
     {
       lcd.write("On");
       digitalWrite(LED_PIN,HIGH);
     } 
     else if(strcmp(bufferString, "Off")  == 0)
     {
       lcd.write("Off");
       digitalWrite(LED_PIN,LOW);
     }
  }
}

The lcd.clear() function takes time. During that time, the rest of the serial data arrives.

Reading serial data that way is not a good idea. You have no way of knowing when a complete packet has arrived, so all you can do is hope. Which, in this case, fails.

You could replace the lcd.clear() with a delay(), or write the code properly.

To write it properly, we'd need to know what was sending the data and what version of the IDE you are using.

PaulS: To write it properly, we'd need to know what was sending the data and what version of the IDE you are using.

I would add that typically commands are terminated with a carriage-return (\r) and/or a new-line (\n). This is why the Serial Monitor has the option to append these characters.

This is why the Serial Monitor has the option to append these characters.

It does. now. That is why I asked which version of the IDE OP was using, if indeed the Serial Monitor is what is being used to send the data.

Hi PaulS and mkwired , Thanks for your reply, i use the IDE latest version Arduino 1.0, and i send data from Java, and i'm not using serial monitor

//Java Code here
...
...
public void sendData(String stringToConvert)
    {   
        byte[] byteArray = stringToConvert.getBytes();
        try 
        { 
            outputStream.write(byteArray);
        }    
        catch (IOException e){System.out.print("Unable to send output stream");}
    }

i have tried used the delay(n) n=500,1000,2000 but still cannot work, why? actually i'm not really understand the statement

You have no way of knowing when a complete packet has arrived, so all you can do is hope. Which, in this case, fails. To write it properly, we'd need to know what was sending the data and what version of the IDE you are using.

because i'm a newbie in using Arduino, i know not much regarding all this. thanks for help...

outputStream.write(byteArray);

writes some stuff to the serial port. That might look like OnOffOnOffOnOnOffOff.

When you go to read the data, how do you know when to stop reading? Just temporarily running out of serial data to read is no guarantee that you have a complete packet.

No, if you were writing , you have clearly defined start and stop markers, and you could use code like this to read it:

#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[80];
byte index;

void setup()
{
   Serial.begin(57600);
   // Other stuff...
}

void loop()
{
  // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

Hi PaulS,

so sorry for providing insufficient information
in my java file, there are interface with 2 button (On) or (Off), then a single message will be send respectively either On or Off for each button was pressed. It is something like

public void sendFunction(int i)
{
     if(i == 1)
     {
       sendData("On")
     }
     else
     {
       sendData("Off") 
     }   

public void sendData(String stringToConvert)
{	
     byte[] byteArray = stringToConvert.getBytes();
     outputStream.write(byteArray);
}

and your suggestion to the arduino code will be something like… wao… impressive, i never think of this kind of code… thanks…

#include <LiquidCrystal.h>
#include <String.h>
#define  LED_PIN  13
#define  RESET  0
#define SOP '<'
#define EOP '>'
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

bool started = false;
bool ended = false;

char inData[80];
byte index;

void setup()
{
  Serial.begin(9600);
  pinMode(LED_PIN, OUTPUT);
  lcd.begin(16, 2);
}

void loop()
{
  // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }
  
 if(started && ended)
  {
     if(strcmp(inData, "On")  == 0)
     {
       lcd.clear();
       lcd.write("On");
       digitalWrite(LED_PIN,HIGH);
     } 
     else if(strcmp(inData, "Off")  == 0)
     {
       lcd.clear();
       lcd.write("Off");
       digitalWrite(LED_PIN,LOW);
     }

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

please correct me if i’m wrong

please correct me if i’m wrong

That code for the Arduino looks good. What you now need to change is the Java app.

       sendData("On")

becomes

       sendData("<On>")

I do wonder why people feel the need to send a full word between computers. A single character is usually enough, 'n' for on and 'f' for off, for example.

I do wonder why people feel the need to send a full word between computers

Anthropomorphism

I do wonder why people feel the need to send a full word between computers. A single character is usually enough

I agree that a single character is sufficient in the case shown here. But, what happens when you want to control more than one pin, or a specific pin? It is important to be able to send/receive more than character that makes up a packet.

Yes but you have a byte so that will allow you to control over 200 individual identifiable things in one go or up to 8 in any combination.

Yes but you have a byte so that will allow you to control over 200 individual identifiable things in one go or up to 8 in any combination.

True. But to read pin 8 or <S9,12> to set pin 9 to 12 (using analogWrite()) is a lot easier to understand, and more importantly expand, than knowing that the value to send to turn pin 8 on is 16 and to turn it off is 77.

Often, too, one is trying to interface with a device that sends data in a particular fashion, so, again I think it important to know how to send/receive/parse/use sentences, rather than just letters.

Hi PaulS, Thanks for all your solution, your code make my things run perfectly. a great learning from u today. Really. anyhow, why the delay(2000) above doesn't work as it seems like the delay(2000) is taking longer time than lcd.clear(), but still cannot work.. why???

anyhow, why the delay(2000) above doesn't work as it seems like the delay(2000) is taking longer time than lcd.clear(), but still cannot work.. why???

I don't know. I don't know where you put the delay(). Where you had the lcd.clear() call seems a strange place to put it, if the purpose was to clear the screen. If the purpose was a small delay, then delay(10) should have worked in place of the lcd.clear().

Hi PaulS,

wanna ask u that if Line 1 data from Serial haven’t arrive yet and it reads nothing, so the Line 1 code will stay until data arrives or Line 2 will execute even Line 1 reads nothing?
is it the Serial.read Line 1 will read a packet of data? means a whole String or character by character?

while (Serial.available()>0)
{
buffer = Serial.read(); <---------Line 1
bufferString[index] = buffer; <---------Line 2
index++; <---------Line 3
}

asking these because i think i had a mistaken concept in my mind before.

If Serial.available() says that there is no data, none of the three lines will be executed. If there is data, all three will be.

The while block will be executed until there is no more data, reading one character at a time.

Ok Ok... thanks... truly appreciate it... U have really help me a lot.. PaulS ;)

Where you had the lcd.clear() call seems a strange place to put it,

It was because it was clearing the display every time you received a single character which in effect was adding a delay to the loop already. The LCD library contains the appropriate delay there is no need to add another. In fact you can half the time that call takes by changing the library to read the busy flag and return when the display has actually finished.