Serial.find(); Find different strings at the same time. HELP!!!

Hi everyone, :slight_smile:

I know, when Serial.find function times out it clears buffer. So I have a question:

Example:

if (Serial.find("ON")) {
//Do something...
}
if (Serial.find("OFF)) {
//Do something...
}

Default timeout for .find = 1000ms. When I send "ON" when it searching "OFF" this function will not find "OFF" and will timeout and clear buffer and the second function will not find "ON" because buffer is empty now. So my question is:

Can I search for two different strings at the same time?

Thanks for all :)))))

Best regards,
DADA

Hi, welcome to the forum,

The find() is not ment to read parameters. You have to read the characters and put them in a buffer and test that buffer.

Suppose the text is "COMMAND=ON". Then you could "find()" the "COMMAND=" and read the text after that.
If the text would be "COMMAND=128". Then a "find()" followed by a "parseInt()" could be used.

The function with the timeout, like find() and parseInt() can be handy. In my sketches, I don't always use them. I often write my own code that reads the text, with full control about timeouts, the NewLine and/or CarriageReturn at the end, perhaps a checksum, and so on.
When there are more things going on in my sketch, I can't afford to wait for the serial incoming data, as the find() and parseInt() do. I just drop every available() character in a buffer, and process that buffer whenever I want to.

first of all... c...o...d...e... ...t...a...g...s

second...the simple answer is no, you cannot do 2 things at the same time, but there is absolutely no reason to.

just create a character buffer and fill it with the Serial.read(), then compare "ON" and "OFF" to that

Daduka:

Can I search for two different strings at the same time?

Yes, easily. The method is called Parsing - Wikipedia

In lexical analyses you normally would need to tell what makes a "word", that you are looking for. Exampe: You could define that a "word" starts and ends with a "letter of the alphabet". So every character that is not a letter can be sorted out and never can belong to a word. So typically you "parse" the incoming data char by char until you have found a single "word". Then you can compare the word found against a stored list of words you like to find.

Hi again :slight_smile:

Thanks for fast reply.

So... I want to turn LED on or off with sending "ON" or "OFF" to ESP8266. Then ESP8266 will send data to Arduino like that > +IPD,0,2:ON or +IPD,0,3:OFF. When I will send "ON" or "OFF" to ESP8266 and the module will send this data to Arduino, I want Arduino to shearch for "ON" or "OFF" and then turn LED on or off.
Someone can write simple code example for that? Only functions to find "ON" or "OFF" from serial data. :)))

Thanks again :wink: (y)

Best regards,
DADA

Daduka:
So... I want to turn LED on or off with sending "ON" or "OFF" to ESP8266. Then ESP8266 will send data to Arduino like that > +IPD,0,2:ON or +IPD,0,3:OFF. When I will send "ON" or "OFF" to ESP8266 and the module will send this data to Arduino, I want Arduino to shearch for "ON" or "OFF" and then turn LED on or off.
Someone can write simple code example for that? Only functions to find "ON" or "OFF" from serial data. :)))

I'm guessing that your device is sending 'lines' which are terminated with sone invisible end-of-line control character?

Here is some code for reading lines from such devices:

char* readLine(char c)
{ // parameter 'c' ==> character that was read
  // return NULL ==> line not ready yet
  // return pointer ==> points to received lineBuffer
  static char lineBuffer[25]; // define maximum string length + terminating '\0'
  static byte counter=0;
  if (counter==0) memset(lineBuffer,0,sizeof(lineBuffer));// clear buffer before using it
  if (c<32) // non printable control character, line finished
  {
    if (counter==0) return NULL;
    counter=0;
    return lineBuffer;
  }
  else if (counter<sizeof(lineBuffer)-1) // printable character received and we have room for it
  {
    lineBuffer[counter]=c; // insert character into lineBuffer
    counter++; // increment character counter
  }
  return NULL;
}

 
void setup() 
{ 
  Serial.begin(9600);
} 
 
void loop() 
{ 
  if (Serial.available())
  {
    char c=Serial.read();
    char* command= readLine(c);
    if (command!=NULL)
    {
      if (strstr(command,"ON")!=NULL) Serial.println("Command ON found");
      else if (strstr(command,"OFF")!=NULL) Serial.println("Command OFF found");
    }
  }
}

Code can be used with the serial monitor if CR and/or NL are activated left from the baud rate in the serial monitor. But you can read the characters from any other device and call the 'readLine()' function with the character read as a parameter and get back either NULL (nothing) or a pointer to the line buffer containing the line (maximum length is defined within the function).

Can I search for two different strings at the same time?

You can capture what is sent and then look for the commands. Below is some very simple serial capture code.

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

//A very simple example of sending a string of characters 
//from the serial monitor, capturing the individual 
//characters into a String, then evaluating the contents 
//of the String to possibly perform an action (on/off board LED).

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.indexOf("on") >=0)
    {
      digitalWrite(ledPin, HIGH);
      Serial.println("LED ON");
    }

    if(readString.indexOf("off") >=0)
    {
      digitalWrite(ledPin, LOW);
      Serial.println("LED OFF");
    }

    readString="";
  } 
}

Thanks you... I understand the basics of functionality...

But when using zoomkats code when I send "on" LED turns on but when i send "asdaonasd" it turns on again. I want, that arduino only react on "ON" or "OFF"...

Can you help me?

Thanks again :)))

Best regards,
DADA

But when using zoomkats code when I send "on" LED turns on but when i send "asdaonasd" it turns on again. I want, that arduino only react on "ON" or "OFF"...

What you originally said, which is what the posted code does:

Only functions to find "ON" or "OFF" from serial data. :)))

The posted code does find the "ON" or "OFF" in the String captured. You need to rethink what you have requested and what character strings that are being sent.

To only respond to a complete exact string, instead of (readString.indexOf("off") >=0) use readString == "off\r". Remember you will have a line feed or carriage return character or both at the end depending on your terminal, so that has to be included in your comparison string (\r, \n, \r\n, or \n\r).

Daduka:
Can you help me?

Have you tried the link to serial input basics that @Delta_G gave you in Reply #5. Simple reliable ways to receive data. There is also a parse example.

...R

Remember you will have a line feed or carriage return character or both at the end depending on your terminal, so that has to be included in your comparison string (\r, \n, \r\n, or \n\r).

Not all character strings sent may have those delimiters included.

Well one could always do:

if (Serial.find("ON")) {
//Do something...
}
else {// if it's not ON it must be OFF
//Do something...
}

jurs:
Yes, easily. The method is called Parsing - Wikipedia

In lexical analyses you normally would need to tell what makes a "word", that you are looking for. Exampe: You could define that a "word" starts and ends with a "letter of the alphabet". So every character that is not a letter can be sorted out and never can belong to a word. So typically you "parse" the incoming data char by char until you have found a single "word". Then you can compare the word found against a stored list of words you like to find.

Hi, i'm working on the same project with arduino Uno and i have trouble classifying my data. I have 3 types of data from 3 sensors with timestamp. Now i want to ask the start and stop time and get the data between these times from my SD card. Here is the code i wrote so far:

[left]#include "RTClib.h" // Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <dht.h>  //library for humidity sensor
#include <SPI.h>
#include <SD.h>

#define DHT11_PIN A1 //introducing the type and which pin it is connected to

const int chipSelect = 10;
RTC_DS1307 rtc;
dht DHT; // introducing the humidity sensor

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
char val; //making a variable for reading serial port
float cellvalue=0; //making a float variable for photocell numbers
float cellpin=A0;
float readvalue; //reading photocell numbers
String starttime;
String stoptime;
File dataFile;


     void setup(){
      Serial.begin(9600);
     while (!Serial){ // for Leonardo/Micro/Z
     }
       Serial.print("Initializing SD card...");  // see if the card is present and can be initialized:
       
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");       // don't do anything more:
    while (1);
  }
    Serial.println("card initialized.");
     if (! rtc.begin()) {
     Serial.println("Couldn't find RTC");
     while (1);}
     rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));  // This line sets the RTC with an explicit date & time, for example to set
     rtc.adjust(DateTime(2019, 11, 27, 10, 24, 20));    // January 21, 2014 at 3am you would call:
     File dataFile = SD.open("datalog6.txt");
     

     }
     
     
              void loop() {
               
                Serial.print("entert start time:   ");
                while ( Serial.available()==0){ }
                starttime= Serial.readString();

                 Serial.print("entert stop time:   ");
                while ( Serial.available()==0){ }
                stoptime= Serial.readString();
               
               
              if (Serial.available()) { //writing the values into serial port
              val=Serial.read();             
              int chk = DHT.read11(DHT11_PIN); // making variables for each sensor
              int t= DHT.temperature;
              int h=DHT.humidity;
              int l=sendvalue; //photocell
              }
              char c;
              if(Serial.available())    { 
              c = Serial.read(); 
              if(c=='t')
              sendvalue();  // if the file is available, write to it:
              else {    // if the file isn't open, pop up an error:
              Serial.println("error opening datalog.txt");
              } }
              search();
               RTC_Sensor();
              SD_log();  }


                  void SD_log(){
                  String dataString = "";  // make a string for assembling the data to log:           
                  for (int analogPin = 0; analogPin < 3; analogPin++) { // read three sensors and append to the string:
                  int sensor = analogRead(analogPin);
                  dataString += String(sensor);
                  if (analogPin < 2) {
                  dataString += ",";}}
                  File dataFile = SD.open("datalog6.txt", FILE_WRITE); // open the file. note that only one file can be open at a time, so you have to close this one before opening another.
                  if (dataFile) { // if the file is available, write to it:
                  DateTime now = rtc.now();
                          dataFile.print(now.year(), DEC);
                          dataFile.print('/');
                          dataFile.print(now.month(), DEC);
                          dataFile.print('/');
                          dataFile.print(now.day(), DEC);
                          dataFile.print(" ,");
                         dataFile.print(now.hour(), DEC);
                          dataFile.print(':');
                          dataFile.print(now.minute(), DEC);
                          dataFile.print(':');
                          dataFile.print(now.second(), DEC);
                          dataFile.print( ",");
                         
                          dataFile.println(dataString);
                          dataFile.close();
                          }
                          else {  // if the file isn't open, pop up an error:
                          Serial.println("error opening datalog6.txt");  } }

     void RTC_Sensor() {                                             
    readvalue=analogRead(A0); //photocell is connected to pin a3 so we read analog changes
                                             }
     
 void sendvalue(){
         File dataFile = SD.open("datalog6.txt");   
         if (dataFile) {
         while (dataFile.available()) {
         Serial.write(dataFile.read());
    }
         dataFile.close();
    }}

     void search() {
     while (dataFile.available()) {
      dataFile.find(starttime)
      Serial.print(starttime);[/left]

Farnaz_201:
Hi, i'm working on the same project with arduino Uno and i have trouble classifying my data.

You have been getting a great deal of help in your own Thread so why are you resurrecting this very dead Thread?

...R