how to save the serial input

Hello
I have connected a device to my Arduino
when I use this command I can see on the LCD what I have send

while (MySerial.available() > 0)
  {
    lcd.write(MYSerial.read());
  }

my question is how can I save the input and them print it as I want
and compere the answer I get

I remember I did this once - but i don't remember how (my computer had crash and all my files are gone :frowning: )

any help \ guidance will help

this is the code I have so far -

void loop()
{
  if (RBSerial.available() > 0)
  {
    rx_byte = RBSerial.read();       // get the character

    if (rx_byte != '\n')
    {
      // a character of the string was received
      rx_str += rx_byte;
    }
    else {
      // end of string
      Serial.print("Welcome ");
      Serial.println(rx_str);
      rx_str = "";                // clear the string for reuse
    }
  } // end: if (Serial.available() > 0)
  

}//end of loop

Thanks,

Have a look at the 2nd example in Serial Input Basics. It should do most of what you want.

...R

I have try what you have told me.
and it's working, thanks.

now I I want to use what I have got from the serial ,and compere it to known data
but it doesn't seen to work
do I need to change the string to something in order to use it?

{
  recvWithEndMarker();
  showNewData();

  if (printData == true)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(receivedChars);
    printData = false;
  }
  if (receivedChars == "hello")
  {
    lcd.setCursor(0, 1);
    Serial.println("working!!!!!!");
    lcd.print("working!");

  }
}//end of loop

Alas, C/C++ is not as simple as if (receivedChars == "hello")

You need to use the strcmp() function.

...R

Thanks I can see it's what I needed ,
but I have something strange going on now
I can only make it work the first time I'm sending a text.
after it is show me like I'm sending space before the word:
I'm sending "hello"
but I see I'm getting "_hello"

h
e
l
l
o
working!!!!!!
!
This just in ... hello
working!!!!!!


h
e
l
l
o
!
This just in ... 
hello


h
e
l
l
o
!
This just in ... 
hello

this is the code:

#include <SoftwareSerial.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
SoftwareSerial RBSerial(7, 8);

String rx_str = "";
char rx_byte = 0;
char key[] = "hello";
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x20 for a 16 chars and 2 line display


const byte numChars = 32;
char receivedChars[numChars];  // an array to store the received data

boolean newData = false;
boolean printData = false;
void setup()
{
  pinMode(5, OUTPUT);
  RBSerial.begin(9600);
  Serial.begin(9600);
  lcd.begin();
  Serial.println("Starting.....");
  digitalWrite(5, HIGH);
  lcd.setCursor(0, 0);
  lcd.print("Starting.....");
  for (int i = 0; i < 10; i++)
  {
    Serial.println("**");
    delay (100);
  }
  for (int i = 0; i < 3; i++)
  {
    lcd.backlight();
    delay(250);
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight(); // finish with backlight on
  lcd.setCursor(0, 1);
  lcd.print("Done!");
  Serial.println(F(__FILE__)); //print the file name
  Serial.println( "Done!");
  digitalWrite(5, LOW);
  delay (2000);
  lcd.clear();
}



void loop()
{
  recvWithEndMarker();
  showNewData();

  if (printData == true)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("The text is -");
    lcd.setCursor(0, 1);
    lcd.print(receivedChars);
    lcd.print("");
    printData = false;
  }
  if (strcmp (receivedChars, key) == 0 )
  {
    lcd.setCursor(0, 1);
    Serial.println("working!!!!!!");
    lcd.print("working!");
    digitalWrite(5, HIGH);
    delay(1000);
    digitalWrite(5, LOW);
  }//end of cmp
  
}//end of loop


void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = '!';
  char rc;

  // if (Serial.available() > 0) {
  while (RBSerial.available() > 0 && newData == false) {
    rc = RBSerial.read();
    Serial.println(rc);

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }
  }
}

void showNewData() {
  if (newData == true) {
    Serial.print("This just in ... ");
    Serial.println(receivedChars);
    newData = false;
    printData = true;
  }
}

from what I see and understand it's like the "ndx" doesn't get 0 after it finish the string , I'm printing the value and I can see he get the value '1' after the first time he save the text

Robin2:
Alas, C/C++ is not as simple as if (receivedChars == "hello")

It can be that simple if you use the string class. The problem is that the Arduino doesn't have enough resources to support it properly.

david1234:
Thanks I can see it's what I needed ,
but I have something strange going on now
I can only make it work the first time I'm sending a text.

I suspect you are making a common mistake. You are setting the variable newData back to false before you have used the data that has just been received.

And I think all the stuff you have added into loop() should be encompassed in the if (printData == true). And why not just do it if (newData == true) { as in showNewData()

And it would be easier to maintain the program is you put your new code into a new function thus keeping loop() very simple.

...R

A very simple example of serial capture and compare what was captured.

// zoomkat 8-6-10 serial I/O string test
// type a string in serial monitor. then send or enter
// for IDE 0019 and later

int ledPin = 13;
String readString;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT); 
  Serial.println("serial on/off test 0021"); // so I can keep track
}

void loop() {

  while (Serial.available()) {
    delay(3);  
    char c = Serial.read();
    readString += c; 
  }

  if (readString.length() >0) {
    Serial.println(readString);

    if (readString == "on")     
    {
      digitalWrite(ledPin, HIGH);
      Serial.println("LED ON");
    }
    if (readString == "off")
    {
      digitalWrite(ledPin, LOW);
      Serial.println("LED OFF");
    }
    readString="";
  } 
}

Thanks for the advice ,
but i still can't figure out where to put

newData= false

as I see the code "recvWithEndMarker"
I'm checking if the data is the endMarker
if it isn't I'm saving it into the string , if it's the endMark
I'm ending the string, and go on to the print function

so where do you think I should make the newData=false ?
I don't understand why he is still counting after the newData=true (should stop counting) no?

#include <SoftwareSerial.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
SoftwareSerial RBSerial(7, 8);

String rx_str = "";
char rx_byte = 0;
char key[] = "1234";



LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x20 for a 16 chars and 2 line display

static byte ndx = 0;
const byte numChars = 32;
char receivedChars[numChars];  // an array to store the received data

boolean newData = false;
boolean printData = false;
void setup()
{
  pinMode(5, OUTPUT);
  RBSerial.begin(9600);
  Serial.begin(9600);
  lcd.begin();
  Serial.println("Starting.....");
  digitalWrite(5, HIGH);
  lcd.setCursor(0, 0);
  lcd.print("Starting.....");
  for (int i = 0; i < 10; i++)
  {
    Serial.println("**");
    delay (100);
  }
  for (int i = 0; i < 3; i++)
  {
    lcd.backlight();
    delay(250);
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight(); // finish with backlight on
  lcd.setCursor(0, 1);
  lcd.print("Done!");
  Serial.println(F(__FILE__)); //print the file name
  Serial.println( "Done!");
  digitalWrite(5, LOW);
  delay (2000);
  lcd.clear();
}



void loop()
{
  recvWithEndMarker();
  showNewData();

  if (printData == true)
  {
    PrintData();
  }
  if (strcmp (receivedChars, key) == 0 )
  {
    lcd.setCursor(0, 1);
    Serial.println("working!!!!!!");
    lcd.print("working!");
    digitalWrite(5, HIGH);
    delay(1000);
    digitalWrite(5, LOW);
  }//end of cmp

}//end of loop


void recvWithEndMarker() {
  //static byte ndx = 0;
  char endMarker = '!';
  char rc;
if (newData == true)
{
  ndx=0;
}
  while (RBSerial.available() > 0 && newData == false) {
    rc = RBSerial.read();
    //Serial.println(rc);

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      Serial.println(ndx);
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }

    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }

  }
}

void showNewData() {
  if (newData == true) {
    Serial.print("This just in ... ");
    Serial.println(receivedChars);
    newData = false;
    printData = true;
    ndx = 0;

  }
}

void PrintData ()
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("The text is -");
  lcd.setCursor(0, 1);
  lcd.print(receivedChars);
  lcd.print("");
  printData = false;
}

Thanks,

david1234:
so where do you think I should make the newData=false ?
I don't understand why he is still counting after the newData=true (should stop counting) no?

I don't understand why you think it counts after newData=true. Where do you see that in the code?

The idea of the newData variable is to act as a flag to tell the other parts of the program that a new message has been received. And it is also use to tell the function recvWithEndMarker() that it may overwrite the buffer receivedChars[] with new incoming data.

Consequently you should only change newData back to false when you no longer need the data in receivedChars[]

I presume you realize you can change the size of receivedChars[] to suit your own needs by changing the constant numChars

Hope this helps.

...R

I understand all this (I think)
this is why I change it after I get the final char (the endMarker)

void recvWithEndMarker() {
  //static byte ndx = 0;
  char endMarker = '!';
  char rc;
  //if (newData == true)
  //{
  //  ndx=0;
  //}
 while (RBSerial.available() > 0 && newData == false) {
    rc = RBSerial.read();
    //Serial.println(rc);

    if (rc != endMarker) {
      receivedChars[ndx] = rc;
      ndx++;
      Serial.println(ndx);
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }

    }
    else {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;
    }

  }
}
    }

am I wrong? what am I missing?

You seem to have mucked around with my code and it has been difficult to see the differences and to figure out whether they really matter.

Use the AutoFormat tool to make the layout of your code consistent and readable.

For some reason you have added

if (newData == true)
{
     ndx=0;
}

I think that will completely screw up the process. The function recvWithEndMarker() does not necessarily receive the entire message in a single iteration. If the index is reset halfway through you will just get garbage.

Why not use my code completely unchanged apart from the different end-marker. Then it is much easier to help.

I still do not understand the thinking behind your question in Reply #10. Why do you need to change anything? What do you think you need to change?

...R

maybe you didn't notice but this part you have talk about is not in use (comment).
but I will remove it - no problem.

let me explain again what is the problem
when I send a text it only work for me for the first time
after it I'm getting wrong compering...
it's getting me garbage for the first char
look

Starting.....
**
**
**
**
**
**
**
**
**
**
ReadSerial_LCD_Save_Input.ino
Done!
1
2
3
4
This just in ... 1234
working!!!!!!
1
2
3
4
5
This just in ... 
1234
1
2
3
4
5
This just in ... 
1234
1

it's seem that after he finish printing he get some data from some where , I don;t understand from where

this is the code:

#include <SoftwareSerial.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
SoftwareSerial RBSerial(7, 8);

String rx_str = "";
char rx_byte = 0;
char key[] = "1234";



LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x20 for a 16 chars and 2 line display

static byte ndx = 0;
const byte numChars = 32;
char receivedChars[numChars];  // an array to store the received data

boolean newData = false;
boolean printData = false;
void setup()
{
  pinMode(5, OUTPUT);
  RBSerial.begin(9600);
  Serial.begin(9600);
  lcd.begin();
  Serial.println("Starting.....");
  digitalWrite(5, HIGH);
  lcd.setCursor(0, 0);
  lcd.print("Starting.....");
  for (int i = 0; i < 10; i++)
  {
    Serial.println("**");
    delay (100);
  }
  for (int i = 0; i < 3; i++)
  {
    lcd.backlight();
    delay(250);
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight(); // finish with backlight on
  lcd.setCursor(0, 1);
  lcd.print("Done!");
  Serial.println(F(__FILE__)); //print the file name
  Serial.println( "Done!");
  digitalWrite(5, LOW);
  delay (2000);
  lcd.clear();
}



void loop()
{
  recvWithEndMarker();
  showNewData();

  if (printData == true)
  {
    LCDPrint();
  }

  CmpString();

}//end of loop


void recvWithEndMarker() {
  //static byte ndx = 0;
  char endMarker = '!';
  char rc;

  while (RBSerial.available() > 0 && newData == false)
  {
    rc = RBSerial.read();
    //Serial.println(rc);

    if (rc == endMarker)
    {
      receivedChars[ndx] = '\0'; // terminate the string
      ndx = 0;
      newData = true;

    }


    else
    {
      receivedChars[ndx] = rc;
      ndx++;
      Serial.println(ndx);
      if (ndx >= numChars) {
        ndx = numChars - 1;
      }
    }

  }
}

void showNewData() {
  if (newData == true) {
    Serial.print("This just in ... ");
    Serial.println(receivedChars);
    newData = false;
    printData = true;
    ndx = 0;

  }
}

void LCDPrint ()
{
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("The text is -");
  lcd.setCursor(0, 1);
  lcd.print(receivedChars);
  lcd.print("");
  printData = false;
  delay (2000); // show the text for 2 secounds

}

void CmpString ()
{
  if (strcmp (receivedChars, key) == 0 )
  {
    lcd.setCursor(0, 1);
    Serial.println("working!!!!!!");
    lcd.print("working!");
    digitalWrite(5, HIGH);
    delay(1000);
    digitalWrite(5, LOW);

  }
}

I took your code and only added the part of the printing to LCD and compare

wait!
I have found my problem !

when I send text manually is O.K
but when my device do it - he sending 1 more byte or something - and this is why it doesn't work for me .

I'm trying to see what is the extra char is but I get blank
so I have try to block " " - didn't work
so I have try all kind of things - until I understand he is sending me '\r' at the end

so now it's working!
and I can ignore this now when I read

if ((rc != endMarker)&&(rc != '\r'))
   {
     receivedChars[ndx] = rc;
     ndx++;
     Serial.println(ndx);
     if (ndx >= numChars) {
       ndx = numChars - 1;
     }
   }

my question is -how do I convert from char to ascii ? that why I will see the code (13 for \r)
?

Thanks ,

Change

Serial.println(rc);

to

Serial.println(rc,HEX);

to see the ASCII character code being received. It will probably be 0x0A or 0x0C (or maybe both).

Thanks !

david1234:
when I send text manually is O.K
but when my device do it - he sending 1 more byte or something - and this is why it doesn't work for me .

That sounds like you are not using the proper character for the end marker. The end marker should be the last character that is sent by the sending program - not the last character that you are interested in.

...R