extract n byte following tag reception.

Good day, I have to extract n byte of data following the reception of particular tab on the arduino uno serial port. On the serial input there are a lot of data and tags but I am only interested in acquiring few bytes following the reception of particular tags. The byte of my interest are the following : AA=Byte0 byte1 byte2 byte3 BB=byte0 byte1 byte2 I have captured them using a terminal program and they appears like this: AA=240 014 122 008 BB=011 128 205 I need to capture those seven bytes for using in my sketch. Any help please ? Thanks in advance iw2fvo

AA=240 014 122 008 BB=011 128 205

If this data is in an array of chars (if not, put in in one) then look at the strtok() function.

Thanks, Could you please attach an example for me ? iw2fvo

Serial input basics

strtok()

Sorry I am not able to apply that to my problem. What is the piece of program capable to extraxct byte0 byte1 byte2 byte3 after receiving "AA=" tag ? Thanks for all iw2fvo

I prefer to do it with sscanf, every man to his taste ;)

char serialInput[] = "AA=240 014 122 008"; // just for this example
uint8_t bytes[4];

if ( sscanf( serialInput, "AA=%hhu %hhu %hhu %hhu", &bytes[0], &bytes[1], &bytes[2], &bytes[3] ) == 4 )
{
    // now bytes[0] = 240, bytes[1] = 14, etc
}

Edit: By the way here is an example using strtok

char serialInput[] = "AA=240 014 122 008"; // just for this example
uint8_t bytes[4];
uint8_t idx = 0;

char *p = strtok( serialInput + 3, " " ); // + 3 to start searching tokens after "AA="

while ( p != NULL )
{
    bytes[idx++] = atoi( p );
    p = strtok( NULL, " " );
}

// now bytes[0] = 240, bytes[1] = 14, etc

The strtok() version is missing a declaration for i. Easily fixed of course.

Fixed :-[

The strtok() version is missing a declaration for i. Easily fixed of course.

That aside, the sscanf() version does not work for the second sample string that the OP posted because of its different number of entries, whereas the strtok() version does and conveniently it counts the number of entries too.

chaque homme à son goût :wink:

Thanks a lot for the great assistance. I am out now. I will check the sketches this afternoon or tomorrow and let you know. Thanks again, All the best iw2fvo

here I am again !

My Arduino has a serial data input from portOne:

portOne.listen(); while (portOne.available()) { ???

How to merge the suggested sscanf or strtok ?

I am very new to Arduino world ! Any help is appreciated Thanks in advance iw2fvo

It is saying portOne is not declared…

What am I doing wrong here ?

Thanks

#include <SoftwareSerial.h>

// software serial #1: TX = digital pin 8, RX = digital pin 9
SoftwareSerial portOne(8,9);

void setup() {

portOne.begin(9600);
Serial.begin(9600);
Serial.println(“Arduino is started …”);
}

void loop() {

portOne.listen();
if (sscanf(portOneInput,“AA=%hhu %hhu %hhu &hhu”, &bytes[0], &bytes[1])==4)
Serial.println(“Pmb=”);
Serial.print(bytes[0]);
Serial.println();
Serial.print(bytes[1]);
Serial.println();
}
}

It is saying portOne is not declared...

Is it really saying that, or could it be reporting 'portOneInput' was not declared in this scope

You need to read the bytes from the serial port as they are received and put them in an array of chars named portOneInput then use one of the techniques in this thread.

This will show you how to read the bytes Serial input basics

The serial stream cyclically repeats and there is no termiation characters as " CR , LF "or other. How could I create an array then ? How could I put into an array the string included between two AA= tags ?

Thanks iw2fvo

FWIW: I tried both the sscanf() and strtok() versions of the code and found that sscanf() takes 4036 bytes while strtok() takes 2384 bytes, both of which include a function to display the results. My experience is that sscanf() is usually an H-bomb-to-kill-an-ant approach. The strtok() version is below:

#define ELEMENTCOUNT(x) (sizeof(x) / sizeof(x[0]))

char serialInput[] = "AA=240 014 122 008"; // just for this example
uint8_t bytes[4];
uint8_t idx = 0;

void setup() {
  Serial.begin(115200);
  // put your setup code here, to run once:

  char *p = strtok( serialInput + 3, " " ); // + 3 to start searching tokens after "AA="

  while ( p != NULL )
  {
      bytes[idx++] = atoi( p );
      p = strtok( NULL, " " );
  }

    ShowSubstrings();

}

void loop() {
  // put your main code here, to run repeatedly:

}

void ShowSubstrings()
{
  int i;
  
  for (i = 0; i < ELEMENTCOUNT(bytes); i++) {
    Serial.println(bytes[i]);
  }
}

Thanks to all in the forum. I would like to pose my problem in a different way from the beginning. My Arduino will receive a serial data stream from an external MCU: the interface is proven OK. Serial stream is cyclically sent and it is composed by TAGS and BYTES . There are about 23 differents tags but I am interested on just few of them. Tags are like this:AA=byte byte, byte.... BB=byte byte byte byte.... The number of byte depends on the TAG : it is fixed for a determined TAG. The sequence is NOT interrupted by commas, CR , LF nor other particular control characters. For example: AA=134 098 199 042 BB=231 234 012 005 065..... AA=134 098 ...etc. The proposed approaches require a string to be examined by sscanf or strtok. ___ the first problem : how to create the array from portOne data stream that has NO control characters?. --- How could I do that ? A piece of code to implement this is appreciated. Please note that English is my second language and I am new to Arduino/C_language. Thanks in advance to help in solving this first problem. regards, iw2fvo

One way: look for a byte at time for the Tag, then act from there when a valid AA or BB is seen:

if (Serial.available() >1){ // 2 bytes received
byte1 = Serial.available();
if (byte1 == 'A' || byte1 == 'B'){
byte2 = Serial.available();
if (byte2 == 'A' || byte2 == 'B'){
// got valid start of sequence
if (byte1 == 'A' && byte2 == 'A'){
byteCount = Abytes;
if (byte1 == 'B' && byte2 == 'B'){
byteCount = Bbytes;
// wait for more bytes
while (Serial.available() <=byteCount){
// hang out
}
// enough bytes received
   for (x=0; x<=byteCount; x=x+1){
   dataArray[x] = Serial.read();
   }
}
}
} // check on # of }s to close out all the if's, jump out to continue sync effort if A or are not received as first 2 bytes

The strtok() version above contains no control characters. The null termination character is really not a control character. I guess I don't understand why the skeleton code above can't serve as a starting point.

W8TEE

Hi,
I am not able to compile my sketch when trying to merge “sscanf or strtok”.
My running sketch is the following:

#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
Adafruit_BMP085 bmp;
#include <SoftwareSerial.h>
SoftwareSerial portOne(8,9);

byte mac = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,0,177);
EthernetServer server(80);

String inputString = “”; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
byte i=0;

void setup() {

portOne.begin(9600);
Serial.begin(9600);
// reserve 200 bytes for the inputString: ??
inputString.reserve(200); //?
Ethernet.begin(mac, ip);
server.begin();
//Serial.print("server is at ");
//Serial.println(Ethernet.localIP());
if (!bmp.begin()) {
Serial.println(“Could not find a valid BMP085 sensor, check wiring!”);
while (1) {}
}
}

void loop() {

portOne.listen();
if (portOne.available()>0) { // one char at the time
char inChar = (char)portOne.read();
inputString += inChar;
i++;
if (i>=250) { // 250 chars string
Serial.println(inputString); // this is OK
inputString="";
i=0;
}
}
}

How to merge the “sscanf or strtok” in this sketch? When Itry to do it I have a lot of error messages…
The above sketch works and give the complete serial received string.

Thanks
iw2fvo

Several things: First, with 33 posts, you need to read the two posts at the top of this Forum by Nick Gammon on the correct way to post code here. Don’t ask any more questions until you have read them. Second, get rid of the String class. strtok() is not designed to work with a String class object. Use a char array instead, as I’ve shown below. Note that String and string are two totally different concepts in programming. Finally, you need to read up on character arrays and string processing, not String class methods. The String class may be easier to use, but it wastes a lot of memory.

#define MESSAGETERMINATOR   '\n'   // Make this the character that ends a received message

char inputString[40];  // I don't know how big it might be??

void setup() {
  // put your setup code here, to run once:
  
}

void loop() {
  int charsRead;
 
 if (portOne.available()>0) {  // one char at the time 
    charsRead = (char)portOne.readBytesUntil(MESSAGETERMINATOR, inputString, 39); 
    inputString[charsRead] = '\0';    // This means you can treat the message as a string...

    // Put the strtok() code here    
 }
}

Dear EconJack, I am sorry for having created problems with the improper way to attach the code. As I told I am new to Arduino and to C language. English is not my first language and I have some difficulties in reading ermetic messages. My serial stream has NO terminating characters as told in some previous messages. Any particular reading on the matter ? I am sorry . thanks iw2fvo