Howto convert one string of several bytes to separate bytes?

Hi, don't know how to deal with this problem:

I receive data from a wifly module, one string consisting of several numbers. I want to separate these numbers and use them as individual bytes.
I need to send these numbers as individual bytes through serial.

Example: received string 255 234 1 5 34 216
This must be converted to separate bytes and sending through serial 255 and than 234 and 1 etc...

My programming skills are very basic and I couldn't find a solution yet.
Suggestions appreciated!

P

Example: received string 255 234 1 5 34 216

Is that a string that consists of 18 characters or one of 6 characters?
The exact solution depends on your answer.

you must add separators in the string otherwise the Arduino can not know how to split.

e.g. if the string is 2551356 , does that mean <255><13><56> or <2><55><1><35><6> etc

spaces like in your example can be a good separator:

int val;
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  if (Serial.available() >0)
  {
    byte c = Serial.read();
    if (c == " ")  // space means end of number
    {
      process(val);
      val = 0;
    } 
    else
    {
      val = val * 10 + (c - '0'); // this converts the char c to its integer value.
    }
  }
  // you can do other things here


}

The code above assumes no minus signs and that the numbers fit into an int. If you understand this code you can expand it stepwise.

succes,

Very simple code to collect characters into a string until a certain character is received. You probably could substitute the decimal representation for your space (char(32)) for the , in the below code.

//zoomkat 11-8-11 simple delimited ',' string parce 
//from serial port input (via serial monitor)
//and print result out serial port
// CR/LF could also be a delimiter

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial delimit test 0022"); // so I can keep track of what is loaded
}

void loop() {

  //expect a string like wer,qwe rty,123 456,hyre kjhg,
  //or like hello world,who are you?,bye!,
  while (Serial.available()) {
    delay(1);  //small delay to allow input buffer to fill
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      break; //breaks out of capture loop to print readstring
    }  
    readString += c; //makes the string readString
  }

  if (readString.length() >0) {
    Serial.println(readString); //prints string to serial port out

    readString=""; //clears variable for new input
  }
}

You can also use sscanf and there needs to be spaces between the numbers, just like what you wrote. Here is a tutorial:

Essentially you do sscanf(source,"%d %d %d %d", &num1,&num2,&num3,&num4);

Hello all,

Thanks for your replies. I'll make my question more clear.
Below is the sample code I am working with.
I send one TCP message from MaxMSP to the Wifly shield (through Wifi ) something like 255 133 7 15 44 (separated by spaces). These values stand for 5 separate byte values I want to process further on the arduino.
The code delivered by the SpiSerial is 255(space)133(space)7(space)15(space)44 in one string. In the current situation Serial.print(Str6[1], BYTE); sends out the the full string in once, and I can read it in the terminal. Represented as: 255 133 7 15 44
What I want is to send these 5 numbers out as separate bytes through Serial. First 255, than 133 etc...

Should I be able to listen to the SpiSerial in the same way as you showed the Serial example? Using the spaces as separator.
Or does the SpiSerial deliver these full strings? I don't quite understand the concept?
What is the way to do it?

Anyway just learned this piece of code will help me reconstruct the data: readString += c; //makes the string readString , great...

Can't this be done more efficient? Sending one TCP message like shown above consisting of between 3 to 10 bytes , and putting them out as individual bytes through Serial.
By the way, these messages are coded data to control a string of RGB leds.

Thanks for helping!

/*

SpiUartTerminal - tool to help troubleshoot problems with WiFly shield

This code will initialize and test the SC16IS750 UART-SPI bridge then enable you
to send commands to the WiFly module.

Copyright (c) 2010 SparkFun Electronics. http://sparkfun.com LGPL 3.0

*/

#include "WiFly.h" // We use this for the preinstantiated SpiSerial object.
char Str6[20]= "0";

void setup() {

Serial.begin(9600);
Serial.println("SPI UART on WiFly Shield terminal tool");
Serial.println("--------------------------------------");
Serial.println();
Serial.println("This is a tool to help you troubleshoot problems with the WiFly shield.");
Serial.println("For consistent results unplug & replug power to your Arduino and WiFly shield.");
Serial.println("(Ensure the serial monitor is not open when you remove power.)");
Serial.println();

Serial.println("Attempting to connect to SPI UART...");
SpiSerial.begin();
Serial.println("Connected to SPI UART.");
Serial.println();

Serial.println(" * Use $$$ (with no line ending) to enter WiFly command mode. ("CMD")");
Serial.println(" * Then send each command followed by a carriage return.");
Serial.println();

Serial.println("Waiting for input.");
Serial.println();

}

void loop() {
// Terminal routine

// Always display a response uninterrupted by typing
// but note that this makes the terminal unresponsive
// while a response is being received.
while(SpiSerial.available() > 0) {
Str6[1]=SpiSerial.read();
Serial.print(Str6[1], BYTE);
}

if(Serial.available()) { // Outgoing data
SpiSerial.print(Serial.read(), BYTE);
}
}

Thanks liudr ,

This looks like the problem I am dealing with.
Tomorrow morning I'll take a better look at it.

Pieter

You should have a look at "strtok_r" for breaking up strings into their constituent elements.

You should have a look at "strtok_r" for breaking up strings into their constituent elements.

No, you should not. The strtok_r() version of strtok() is MUCH larger than strtok(), and much more complicated to use. It is the thread0safe version of strtok(). For a single threaded application, why would you recommend the use of a thread-safe function?

I have tried to use strtok() in the past but it has not compiled. Therefore, like others, I have used strtok_r() instead (See links below). I have not checked to see if strtok() has " come back again" in recent Arduino versions. I will give it a try.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1271905780

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1231961642

lemming:
I have tried to use strtok() in the past but it has not compiled. Therefore, like others, I have used strtok_r() instead (See links below). I have not checked to see if strtok() has " come back again" in recent Arduino versions. I will give it a try.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1271905780

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1231961642

Why resisting the power of sscanf? ]:smiley:

sscanf is for sissies, sooks, and wimps.

Real men use strtok.

It also compiles to take up more space.

Hi all, thanks for the suggestions.

I am experimenting with this strtok. (or strtok_r, but this indeed gives protest in compiling...?).
Using this example below as a starting point.
The example works...but I really don't understand what is happening. You put something in the setup, and thanks to the stuff in the main-loop you get the right results?? I am missing this concept. I thought that a setup runs first and initiates the data for the next part. But this contradicts that concept.
The use of the asterisk is also intriguing, like in *record1. I am looking for some info/theory about this because this is new to me.

I tried several ways to put everything inside the void loop and create a function, but did not manage to do it.
Also, in my situation my strings are of different length, but I can easily put separators or delimiters in the incoming message if necessary. By example an incoming string like: 255^133^24^150^!

But how to use this strtok?

tnx...

/* strtok teststrtok test

output:

Split record1:
one
two
three
Split record2:
Hello
there
friend

*/

#include <string.h>

#define MAX_STRING_LEN 20

char *record1 = "one two three";
char *record2 = "Hello there friend";
char *p, *i;

void setup() {

Serial.begin(9600);
Serial.println("loaded file test_strtok_10.ino");
Serial.println("");
Serial.println("Split record1: ");
Serial.println(subStr(record1, " ", 1));
Serial.println(subStr(record1, " ", 2));
Serial.println(subStr(record1, " ", 3));

Serial.println("Split record2: ");
Serial.println(subStr(record2, " ", 1));
Serial.println(subStr(record2, " ", 2));
Serial.println(subStr(record2, " ", 3));
}

void loop () {
}

// Function to return a substring defined by a delimiter at an index
char* subStr (char* str, char *delim, int index) {
char *act, *sub, *ptr;
static char copy[MAX_STRING_LEN];
int i;

// Since strtok consumes the first arg, make a copy
strcpy(copy, str);

for (i = 1, act = copy; i <= index; i++, act = NULL) {
//Serial.print(".");
sub = strtok_r(act, delim, &ptr);
if (sub == NULL) break;
}
return sub;

}

lemming:
sscanf is for sissies, sooks, and wimps.

Real men use strtok.

It also compiles to take up more space.

Here goes another mind that thinks all programmers should be men and also not knowing better is a logical basis of self-acclaimed superiority. 8)

But how to use this strtok?

This code does not illustrate how to use (or not) strtok(). The strtok() function is completely missing from that code!

@liudr

Sorry, I was being facetious and over-the-top with those comments.

I'm serious with the last line though. It saves a few bytes using strtok. Also I like having the staged deconstruction of the string so that if it is corrupted or isn't complete you can tell which parameter is affected (I use it for passing parameter strings wirelessly). Passing the whole string to a function and just getting a fail out the other end without knowing where it went wrong means that you have to backtrack to find where it went wrong.

@Pauls,

You're right. Its uses the trtok_r() function. I mixed them up.
But this example does the right analyses I need. I found also some other examples I am testing right now.
Sorry for my noobiniss, but this stuff is so hard to understand.
The arduino provides a nice introduction, but then the hard part starts...

I am glad with all suggestions and ready to do my learning.
The discussion for me at the moment is not trtok_r or trtok... thats again the advanced part.

trtok(_r) looks a promising way for me. I'd love to have some clever hints how to integrate this as a functional piece of code to solve my problem :smiley:

lemming:
@liudr

Sorry, I was being facetious and over-the-top with those comments.

I'm serious with the last line though. It saves a few bytes using strtok. Also I like having the staged deconstruction of the string so that if it is corrupted or isn't complete you can tell which parameter is affected (I use it for passing parameter strings wirelessly). Passing the whole string to a function and just getting a fail out the other end without knowing where it went wrong means that you have to backtrack to find where it went wrong.

I'll look into it. Since sscanf has been successful in my projects and long before that in C language, I'm not inclined to learn anything more. It's too time consuming. There is no passing strings involved in sscanf, just old-C pointers. I especially dislike String class because of the dynamic memory allocation and it's trouble with the 2K total SRAM so I don't do dynamic and be prepared so my project's memory usage doesn't fluctuate as much when a function is called, which is a problem with no debug tools on arduino. There is no problem with sscanf understanding strings passed wirelessly or not but I'll look into FLASH saved with strtok.

OP, I'm glad you found your way to interpret strings. It's a major step to write complex programs that can run on parameters received at run time. I also suggest you look into user interface you can implement on arduino, like an LCD and keypad, so you can free some projects from the PC/Mac. May not be useful for this particular project but could be useful to the next.

Thanks guys,

I am still studying this trtok_r() functions. Not the right results yet. But they'll come, i've got an idea of the possibilities. Main reason for my shift of attention is that the project got a slight change because I noticed I can control it by TouchOSC from an Ipad and Android device. This works flawless if I use my Mac as an interface. But now i need it straight to the Wifly-shield and the arduino... Handling their OSC messages is my current challenge.

Pieter

I am still studying this trtok_r() functions.

Why??? You have been told why to use strtok() instead of the much more complicated, memory intensive strtok_r() function.