in arduino, separating elements in a string

Hello ! i wish to read on my arduino a string like "0 1 1 0 0 1 " and wish to get every element separated so i can send them to the digital in/out-puts . How can i do so ? (i.e. I need something like in c# String [] StringVector=StringName.Split(" ") ) . Thanks !

i wish to read on my arduino a string like "0 1 1 0 0 1 "

Read it from where?

If you are reading this collection of characters from a serial port, how will you know when you have received a complete packet?

There are a number of ways that you could get the individual tokens from the string. If the characters are in a char array, and properly NULL terminated, then you could use the strtok() function to get each token.

If the characters are appended to a String, then you could use the indexOf() and substring() methods to extract the tokens.

There is no ready made "make me a dynamically defined array of strings" function on the Arduino, though.

You can evaluate each character as it is received, or you can collect the characters into a string, then evaluate what is in the string. Below are the string handling functions included in IDE 0021.

@PaulS a recieve a line with 12 fixed values

a recieve a line with 12 fixed values

Sending a string with 12 fixed values and receiving a string with 12 fixed values are not the same thing.

Serial data transmission is not guaranteed. It's more like the USPS where they guarantee to try to get it there.

Losses can, and do, occur. If you are relying on 100% success rate on delivery, you are going to be disappointed, sooner or later.

Let me detail the problem : i have a arduino connected to a client in a location. The Client connects to a server . The server can send data to the client such as "close the light in sector A" . The client recieves that info and must send through a serialPort to arduino "1 0 0 0 0 0 0 0 0 0 0 0" (where 1 at that certain position represents 'close the light at sector A') . Arduino grabs that info and sends to PIN1 the value 1 that shuts the light off .(digitatWrite(i) i think is the function to write to a INPUT/OUTPUT i ) . What do you mean there are data losses ? what is a safe and 100% correct-send way ?

i have a arduino connected to a client in a location.

What is this “client”? Arduinos connect to hardware.

The Client connects to a server .

How?

The server can send data to the client such as "close the light in sector A" . The client recieves that info and must send through a serialPort to arduino "1 0 0 0 0 0 0 0 0 0 0 0"

It is this serial transmission that is not guaranteed.

There is no way to make it 100% foolproof, but there are things that can be done to validate the integrity of the data received.

The first thing that needs to be done is to define start and end of packet markers. While a packet is supposed to contain 23 characters, there is no guarantee that it will. By adding a start and end marker (so the packet looks something like this “<1 0 0 0 0 0 0 0 0 0 0 0>”), you can tell is the first or last character in the packet is missing. These are the most often lost bytes.

When both a start and end marker have been received, in that order, then test the length of the string in between. If it is 23, then the packet is complete. If not, you can either ignore it, or return a message to the server that the packet was not complete.

The server could then attempt to re-send the packet.

This is how browsers work. Each TCP packet sent has start and end markers and size data, as well as checksum data, so the receiver can verify that the packet is complete and correct. If not, the packet is discarded, and the server is asked to send that packet again.

The digitalWrite() function is the correct function to use, but it takes two arguments - the pin number to write to, and the value (HIGH or LOW) to write to the pin.

Just to side step the misunderstanding churn, below is some code you can experiment with. Be aware that the client that interfaces with the arduino may experience issues with the arduino if the client opens/closes the serial port on each communication. If the server/ client setup uses a tcp/ip based network connection, you may want to use an ethernet shield on the arduino for a more direct connection.

// zoomkat 10-29-10 simple delimited ',' string parce 
// from serial port input (via serial monitor)
// and print result out serial port
// CR/LF could also be a delimiter
// for IDE 0019 and later

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial-delimit-21"); // 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(10);  //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
  }
}

@paulS arduino is connected to a pc that has a program(client) that connects to another pc(server) . The client connects to the server through a tcpclient provided by .NET platform

@zoomkat what does Serial.available() return ? if the connection is still on or if there is something to read from the serial ?

@badescuga
You need to become familiar with this page:

Thanks!

Another thing : i uploaded to the arduino this code :

int digital[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};// vector pentru memorat starea curenta a in/out digitale
int analog[] = {0,0,0,0,0,0};// vector pentru memorat starea curenta a in analogice

void setup() {
  pinMode(2, INPUT);    
  pinMode(3, INPUT);    
  pinMode(4, INPUT);    
  pinMode(5, INPUT);
  pinMode(6, INPUT);    
  pinMode(7, INPUT);    
  pinMode(8, INPUT);
  pinMode(9, OUTPUT);      
  pinMode(10, OUTPUT);      
  pinMode(11, OUTPUT);      
  pinMode(12, OUTPUT);      
  pinMode(13, OUTPUT); 
  Serial.begin(9600);   
}
String b="";
String temp;
void loop(){ 
  for (int i = 2; i <= 13; i++) {
    digital[i] = digitalRead(i);
    Serial.print (digital[i]);
      Serial.print (" ");
  }
  for (int j = 0; j <= 5; j++) {
    analog[j] = analogRead(j);
    Serial.print (analog[j]);
      if(j!=5)
    Serial.print (" "); 
  }
  Serial.println("");

  //read from program
  while(Serial.available())
 { temp=Serial.read();
 
if(temp=='<') b=""; else
if(temp=='>')
  { if(b.length()==23)
  { 
  if(b[0]=='0') digitalWrite(2,LOW);
  if(b[0]=='1') digitalWrite(2,HIGH);
  
  if(b[2]=='0') digitalWrite(3,LOW);
  if(b[2]=='1') digitalWrite(3,HIGH);
  
  if(b[4]=='0') digitalWrite(4,LOW);
  if(b[4]=='1') digitalWrite(4,HIGH);
  
  if(b[6]=='0') digitalWrite(5,LOW);
  if(b[6]=='1') digitalWrite(5,HIGH);
  
  if(b[8]=='0') digitalWrite(6,LOW);
  if(b[8]=='1') digitalWrite(6,HIGH);
  
  if(b[10]=='0') digitalWrite(7,LOW);
  if(b[10]=='1') digitalWrite(7,HIGH);
  
  if(b[12]=='0') digitalWrite(8,LOW);
  if(b[12]=='1') digitalWrite(8,HIGH);
  
   if(b[14]=='0') digitalWrite(9,LOW);
  if(b[14]=='1') digitalWrite(9,HIGH);
  
  if(b[16]=='0') digitalWrite(10,LOW);
  if(b[16]=='1') digitalWrite(10,HIGH);
  
   if(b[18]=='0') digitalWrite(11,LOW);
  if(b[18]=='1') digitalWrite(11,HIGH);
  
  if(b[20]=='0') digitalWrite(12,LOW);
  if(b[20]=='1') digitalWrite(12,HIGH);
  
  if(b[22]=='0') digitalWrite(13,LOW);
  if(b[22]=='1') digitalWrite(13,HIGH);
  Serial.println("am scris");
  }
  }
  else b+=temp;
 }
Serial.println("i've got : "+b);

and i send from my program the line “<1 1 1 1 1 1 1 1 1 1 1 1>” ( without the " ") … The controller prints on the screen something like “32493249324932493249324962” . Why ?

Nevermind, i've fixed it . i declared temp as a String instead of char. Thanks anyway

You can shorten your code considerably. HIGH is a #define name with a value of 1. LOW is a #define name with a value of 0.

Instead of

  if(b[0]=='0') digitalWrite(2,LOW);
  if(b[0]=='1') digitalWrite(2,HIGH);

you can have

  digitalWrite(2,b[0]);

If you do that for all 12 pins, you’d have this:

  digitalWrite(2,b[0]);
  digitalWrite(2,b[0]);
  digitalWrite(3,b[2]);
  digitalWrite(4,b[4]);
  digitalWrite(5,b[6]);
  digitalWrite(6,b[8]);
  digitalWrite(7,b[10]);
.
.
.

Perhaps you see a pattern here. The array index is 2 * (pin number - 2).

for(int i=2; i<=13; i++)
{
   digitalWrite(i, b[(i-2)*2]);
}

4 lines of code to do what you are now using 32 lines to do.

i didn't know LOW and HIGH are global variables corresponding to '0' and '1'. As for your code, you don't test if a variable is '0' or '1' .. and as you pointed out, the transfer isn't 100% efficient, i thought i should verify.

you don’t test if a variable is ‘0’ or ‘1’

Good point. I also forgot to remove the ‘0’ offset. Fixed:

for(int i=2; i<=13; i++)
{
   if(b[(i-2)*2] == '0' || b[(i-2)*2] == '1')
     digitalWrite(i, b[(i-2)*2]-'0');
}