Serial read in array instead of string

I am trying to understand and implement reading from serial in array instead of using string. I am playing with nextion display and i can get this done with library but i don’t want to because i am trying to learn and understand what am i doing unstead of copy pasting the examples…

So when i press the button on display it sends data in hex which ends in FF FF FF which indicates the end of message… If I upload this example which works fine I see on serial monitor something like “10101011255255255” which is in decimal…

#include <SoftwareSerial.h> //Include the library
bool button = false; //will store the button state

SoftwareSerial mySerial(10, 11); // RX, TX

String message;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(57600); //open the serial port
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }


  Serial.println("Serial On");
  pinMode(13, OUTPUT);
  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
}

void loop() { // run over and over
  while (!mySerial.available()){ //While no data is coming in from the Nextion
    if (message.length() > 14){ //This was the easiest way for me to check that the whole message has been received. Some messages might be longer, but the shortest ones are 15 characters.
      Serial.println(message);   //See what the entire message that the Arduino receives from the Nextion
      Serial.print("button state: "); 
      Serial.println(button); //See what state the button is in
      
      Serial.print("message[3]: "); //according to the Nextion message structure, item 4 will be the page number.
      Serial.println(message[3]); //See what message[3] (the fourth character in the message) is

      Serial.print("message[4]: "); //according to the Nextion message structure, item5 will be the component number.
      Serial.println(message[4]); //See what message[4] (the fifth character in the message) is
      
      if (button == false && message[3] == '0' && message[4] == '1' ){ //Test that the button is off and that it was indeed this button that has been pressed
        button = true; //The button is now pressed
        digitalWrite(13, HIGH); //Switch on the led
        Serial.println("case 1"); //For debugging. Check that the 'if' was entered
        message = ""; //Clear the message, otherwise the next if will also be activated
      }
      else{ //Else the button is on and that it was indeed this button that has been pressed
        button = false; //The button has been deactivated 
        digitalWrite(13, LOW); //Switch the led off
        Serial.println("case 2"); //For debugging. Check that the 'if' was entered
        message = ""; //Clear the message, otherwise we might get mixed messages       
      }      
    }
  }
  
  while (mySerial.available()){ //Is data coming through the serial from the Nextion?
    message.concat(mySerial.read()); //If so, construct the message
    } 
}

So I was reading about serial examples a lot (although i don’t understand lot of things) and tried to write my own code for printing this while storing in array… I tried also with char array - didn’t work and the last try was something like this which also didn’t work… I know that i wrote it down wrongly because message is ending up with 3 255 instead of one 255 like in my code but i don’t have an idea how to write that and would be satisfied for beggining to get ANYTHING printed on serial monitor :(… If you could go through my code and try to explain me on “low level” (because i obviously suck at this) what is so wrong and what should I do and why i would be very thankfull :)… Btw i set up baud like i should… Here is my code, i added up a lot of comments so it is not a problem to track i think… Thanks guys

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11);


boolean message = false;
const byte bytenumber = 20; // maximum numbers of bytes
byte incomingbyte[bytenumber]; // array for incoming bytes
byte bytereceived = 0; //for storing the lenght of index/bytenumber



void setup() {

  Serial.begin(57600); //open the serial port
  while (!Serial) {
    ;
  }

  mySerial.begin(9600); //open software serial port
}

void receive() { //function for receiving data
  byte index = 0;
  byte endflag = "255"; // 255 indicates end of data


  // while reciveing
  while (mySerial.available() > 0 && message == false) // while we receiving
  {

    byte in = mySerial.read();
    if (in != endflag) { //if incoming byte is not 255 keep storing
      incomingbyte[index] = in;
      index++;
      if (index >= bytenumber) {
        index = bytenumber - 1;
      } //end if
    } // end if

    else if (in == endflag) { //if incoming byte is 255
      message = true;
      incomingbyte[index] = '\0'; //terminate
      bytereceived = index;
      index = 0;
    } // end else if
  } // end while
} // end receive

void printing() {
  if (message == true) {
    for (byte i = 0; i < bytereceived; i++) {
      Serial.println(incomingbyte[i]);
    } //end for
    message = false;
  } //end if

} //end function


void loop() {
  receive();
  printing();

}
byte endflag = "255";

This is a problem for a start. A byte can hold a single value from 0 to 255 but “255” is a 3 byte constant string

Did you perhaps mean

byte endflag = 255;

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data. There is also a parse example to illustrate how to extract numbers from the received text.

...R

Thanks for replying… yes i tried also with 255 without quotes. I also write this code very similar to tutorial similar to serial input basics but there is nowhere example of how to setup program to read 3 stop bytes and i have no idea how to do that… i am aware that my program wont run because even if it reads first 255 byte it will read again second 255 and there wont be anything to print. But i posted the code to show that i have something to show, i cant and wouldnt just ask someone to write everything for me, i want help so that i can write it by myself or at least look in that example and figure something out. Is it maybe better to go with char array or this should should work but i need only implement something to read 3 255 bites and then print? How can i do that?

VTI_16V:
Thanks for replying... yes i tried also with 255 without quotes. I also write this code very similar to tutorial similar to serial input basics but there is nowhere example of how to setup program to read 3 stop bytes and i have no idea how to do that..

Do you know why the data uses 3 end-marker bytes?

What would happen if you just treated the first one as the end of the message?

You could extend my example to count the end-markers until it gets 3 of them. If an end-marker is followed by another byte value then reset the counter back to 0. This may work

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

...R

Thank you robin so much... i will try tommorow and post here what happened... Btw i would like to ask few more things just to clear some basic things up... Do you think that this approach is fine or would it be better to try and store message in char array regarding the way that data is sent in hex? Does conversion goes automatically? I mean if arduino prints on serial "10101011255255255" what is decimal value... Can i declare for comparing char char c = ´ÿ´? In the conversion table it says that hex "FF" is lenght of 1 char which is ÿ? So if i write if(incomingbyte == c) is that going to work automatically or should I first get that 255 and convert it to ASCII ÿ manually for comparing? It also confuses me when you are storing 10101011255255255 to char array how does arduino knows which number are which char's? I don't see any space between thoose numbers, does it have something in software implemented like termination which is not visible or maybe whenever it recives enough bits that can transform into char it does it? Probabbly silly question and offtopic, I apologize for that but it would clear some basic thing up for me or if you have some link which describes that i would be happy to read about it... You already helped a lot, thanks for that :slight_smile:

VTI_16V:
Do you think that this approach is fine or would it be better to try and store message in char array regarding the way that data is sent in hex? Does conversion goes automatically? I mean if arduino prints on serial "10101011255255255" what is decimal value... Can i declare for comparing char char c = ´ÿ´? In the conversion table it says that hex "FF" is lenght of 1 char which is ÿ? So if i write if(incomingbyte == c) is that going to work automatically or should I first get that 255 and convert it to ASCII ÿ manually for comparing? It also confuses me when you are storing 10101011255255255 to char array how does arduino knows which number are which char's? I don't see any space between thoose numbers, does it have something in software implemented like termination which is not visible or maybe whenever it recives enough bits that can transform into char it does it? Probabbly silly question and offtopic, I apologize for that but it would clear some basic thing up for me or if you have some link which describes that i would be happy to read about it... You already helped a lot, thanks for that :slight_smile:

I can't make sense of all that. Maybe you can re-write it more clearly?

Can you post an example of the messages that are being sent to the Arduino?

In general my preference is to receive a complete message before trying to parse it.

...R

Of course! Here are the news. So i did this as you told me and i putted a serialprintln for stop bites. It is ok, i get 1,2,3 on serial monitor so counting stop bites is ok now… But it doesn’t print the other bytes before stop bytes which is located at printing function… So this works

else if (in == endflag) { //if incoming byte is 255
      endmarker++;
      Serial.println(endmarker);
      if (endmarker>=endmarkercount){
      message = true;
      incomingbyte[index] = '\0'; //terminate
      bytereceived = index;
      index = 0;
      } //end if
    } // end else if
  } // end while
} // end receive

and this still doesn’t work althougt the end bytes are read and message is true… Maybe something wrong with whis incomingbyte*?*
```
*void printing() {
  if (message == true) {
    for (byte i = 0; i < bytereceived; i++) {
      Serial.println(incomingbyte[i]);
    } //end for
    message = false;
  } //end if

} //end function*
```
Forget about the thing i asked before about comparison, I found a good topic that gave me the answer :smiley:

Please post the complete current code.

VTI_16V:
Of course! Here are the news.

I don't know what the "Of course" refers to because you have not responded to my immediately preceding Reply #6

At the very least provide some examples of the data being sent to the Arduino. Without that we are flying blind.

...R

Hmm sorry, here is the data that comes to arduino when I press a button.

Only 101011255255255 is relevant, the other is for debugging purposes… It is from example that i copy pasted from here http://www.instructables.com/id/Getting-Started-With-Nextion-and-Arduino-Uno-pt-2/

here is the complete code now, it doesn’t want to print array in printing function

#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11);


boolean message = false;
const byte bytenumber = 20; // maximum numbers of bytes
byte incomingbyte[bytenumber]; // array for incoming bytes
byte bytereceived = 0; //for storing the lenght of index/bytenumber



void setup() {

  Serial.begin(57600); //open the serial port
  while (!Serial) {
    ;
  }

  mySerial.begin(9600); //open software serial port
}

void receive() { //function for receiving data
  byte index = 0;
  byte endflag = 255; // 255 indicates end of data
  byte endmarker = 0;
  byte endmarkercount = 3;


  // while reciveing
  while (mySerial.available() > 0 && message == false) // while we receiving
  {

    byte in = mySerial.read();
    if (in != endflag) { //if incoming byte is not 255 keep storing
      endmarker = 0;
      incomingbyte[index] = in;
      index++;
      if (index >= bytenumber) {
        index = bytenumber - 1;
      } //end if
    } // end if

    else if (in == endflag) { //if incoming byte is 255
      endmarker++;
      Serial.println(endmarker);
      if (endmarker>=endmarkercount){
      message = true;
      incomingbyte[index] = '\0'; //terminate
      bytereceived = index;
      index = 0;
      } //end if
    } // end else if
  } // end while
} // end receive

void printing() {
  if (message == true) {
    for (byte i = 0; i < bytereceived; i++) {
      Serial.println(incomingbyte[i]);
    } //end for
    message = false;
  } //end if

} //end function


void loop() {
  receive();
  printing();

}

VTI_16V:
Hmm sorry, here is the data that comes to arduino when I press a button.

Please post it here. This the 3rd time I have had to ask for the same info.

...R

What? I don't understand what you want? You want data being sent TO arduino. So i posted it, i wrote it down and i posted a picture? What else could I post, i don't understand? If you are going to be mad at me for maybe that i don't understand something or am i missing something? Than you don't have to help me, it is not helping me, it is just making me nervous and i don't understand what is wrong. I am trying to be polite and thankfull but just don't get it what is thing that you want?? When i upload the code from instructtables using string and open the serial monitor and when i press a button on nextion display i get this "101011255255255" at arduino serial monitor. What else can I post???

void receive() { //function for receiving data
  //byte index = 0;
  static byte index = 0;

With the modification hi lighted by cattledog and also making "endmarker" static I think you should start seeing the array contents printed to screen

static byte endmarker =0;

VTI_16V:
What? I don't understand what you want? You want data being sent TO arduino. So i posted it, i wrote it down

I must have missed it. Which of your Replies is it in?

...R

Yes, thank you guys it is working now :)... So reference says "The static keyword is used to create variables that are visible to only one function. However unlike local variables that get created and destroyed every time a function is called, static variables persist beyond the function call, preserving their data between function calls."

So if I understand it correctly it didn't want to work because thoose variables were not available in the printing function, only in the receiving one?

@robin it is in the reply 10, i posted link to picture from serial monitor and wrote it down, but that info had nothing to do with why serial print didn't wanted to print out values in array... I still don't understand how you wanted me to post that info? If it has something to do with forum rules you could just say so, and if I accidantly broke some of the forum rules i apologise, it was not on purpose... I respect your work, you are helping a lot of people on this forum for free and we all appreciate that, but some of us are new at this and belive it or not it is very hard learning all this especially when you don't have any background knowledge in programming like I don't have... More than 50% of people throw away arduino in a few months because of that or they continue to work by copy pasting code without understanding what is not my goal... Forums like this are only places we noobs got so when you start acting weird without no reason you are just pushing people away from electronics and coding... No hard feelings friend, i really respect all of yours guys work and i would at least pay a beer to all of you if you were living close to me :slight_smile:

VTI_16V:
@robin it is in the reply 10, i posted link to picture from serial monitor and wrote it down, but that info had nothing to do with why serial print didn't wanted to print out values in array... I still don't understand how you wanted me to post that info?

I only see part of it in Reply #10.

In order to interpret data it seems to me fundamental to start with the facts - the actual data that is being presented to the Arduino, and all of the actual data.

YMMV

...R

Well i really dont know... that what i wrote is whole data that i get printed to monitor... if something is missing i am sorry but i don't know what and how should i get it. If you are willing to explain or direct me at some link/post/topic whatever i would be happy to read about it.

So if I understand it correctly it didn't want to work because thoose variables were not available in the printing function, only in the receiving one?

It had nothing to do with the printing function

Simple take on "static"

index and endmarker are only used in the "receive" function.

The Arduino loop is so fast that it will go in and out of the receive function several times before it finally reads all of your data.

In the original code each time it loops in and out of receive then index and endmarker are initialized to zero, in other words they are not counting.

By making index and endmarker static they are initialized only once and that is on the first loop through the receive function.

Now that they are static and have been initialized the values will persist, in other words they will now count.

These two static values have nothing to do with the printing function, static values can only be used ,initialized and modified within the function they were created/declared.