split udp array

I can read my wifi array sucessfuly as 1:2000,2:1463,3:1000,4:1000,5:-1,6:-1,7:-1,8:-1 this is stored in packetBuffer array.
I need to split it up into 8 channels. I need to read each number following the semi-colon and end with the comma.
so I end up with this.
ch1=2000
ch2=1463
ch3=1000
ch4=1000
ch5=-1
ch6=-1
ch7=-1
ch8=-1
how to I do this? I have tried several methods found on the net, strrok, etc. but I cant make it work. But the udp packet will always be the same pattern i.e 1:xxxx,2:xxxx etc the numbers will change depending on position. please help.

how to I do this?

Using strtok() and atoi().

I have tried several methods found on the net, strrok, etc. but I cant make it work.

Nor, apparently, can you post your code. Or explain what the code did that you didn't want, or didn't do that you did want.

please help.

You first. I'm willing to bet you can figure out what you need to do.

ok here is my code I commented out under packetBuffer and deleted all my other attempts but the int=ch1,2,3,4,5,6,7,8 are what i want to end up with only numbers. here is the code…

#include <SPI.h>
#include <WiFi.h>
#include <WiFiUdp.h>

int status = WL_IDLE_STATUS;
char ssid[] = "myssid"; // your network SSID (name) Your network name here, case sensitive!
char pass[] = "mypassword";  // if your network doesn't use WPA or WEP, change the line below that says "status = WiFi.begin(ssid, pass);"
unsigned int localPort = 1234; // local port to listen on
int ch1=0;
int ch2=0;
int ch3=0;
int ch4=0;
int ch5=0;
int ch6=0;
int ch7=0;
int ch8=0;
char packetBuffer[255]; //buffer to hold incoming packet
char  ReplyBuffer[] = "acknowledged"; // a string to send back

WiFiUDP Udp;
int counter = 0;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600); 
  Serial.println("WifiUdpSendReceiveString");

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present"); 
    // don't continue:
    while(true);
  } 
  Serial.println("Wifi Shield present");

  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) { 
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:    
    status = WiFi.begin(ssid, pass); 

    // wait 10 seconds for connection:
    delay(10000);
  } 
  Serial.println("Connected to wifi");
  printWifiStatus();

  Serial.println("\nStarting connection to server...");
  Udp.begin(localPort);  
}

void loop() {

  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if(packetSize)
  {   
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remoteIp = Udp.remoteIP();
    Serial.print(remoteIp);
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer,255);
    if (len >0) packetBuffer[len]=0;
    Serial.println("Contents:");
    Serial.println(packetBuffer);
   // ch1=strchr(packetBuffer, '1:');

    // send a reply, to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }
  else{
// this will show you that the sketch is actually running and not crashing
// remove this, it's useless.
    counter ++;
    if(counter%2000 == 0){
      Serial.println("no packet"); 
    }
  }
}


void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}
// ch1=strchr(packetBuffer, '1:');

Which ONE key did you press to get the character in the single quotes? If you pressed more than one key, then the single quotes are inappropriate.

The strchr() function looks for a character in a string. packetBuffer is a string, but '1:' is not a character that will ever appear in that string.

and deleted all my other attempts

I deleted all my attempts to help you.

the iphone is generating the string. and I can use another iphone to see the string and it is exactly the same on the Serial monitor.but I have to split all that up into 8 channels so I can use my program for my outputs.

the iphone is generating the string. and I can use another iphone to see the string and it is exactly the same on the Serial monitor.but I have to split all that up into 8 channels so I can use my program for my outputs.

Yeah? So? Where is your code that tries to tokenize the string and do something useful with the tokens?

I started with this

// split the input string at the commas
// and convert the sections into integers: 
int sensors[] = int(split(inputString, ','));
// add the values to the result string:
for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
resultString += "Sensor " + sensorNum + ": ";
resultString += sensors[sensorNum] + "\t";

that did not work so I tried this,

String split = "hi this is a split test";
String word3 = getValue(split, ' ', 2);
Serial.println(word3);

I changed getValue to packetBuffer, then I changed split to packet buffer then I got frustrated and deleted it all.

notfet:
ok here is my code ...

Code tags, please.

Read this before posting a programming question

How to use this forum

sorry I will use the code tag next time Im new at this.

I started with this
// split the input string at the commas
// and convert the sections into integers:
int sensors[] = int(split(inputString, ','));
// add the values to the result string:
for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
resultString += "Sensor " + sensorNum + ": ";
resultString += sensors[sensorNum] + "\t";

that did not work

split() is not a built in function in C++. Nothing in C++ returns an array. So, it’s not surprising that the C# code didn’t “work” (for some definition of work).

so I tried this,

String split = “hi this is a split test”;
String word3 = getValue(split, ’ ', 2);
Serial.println(word3);
I changed getValue to packetBuffer, then I changed split to packet buffer then I got frustrated and deleted it all.

Since getValue() is a function, replacing that function call with an array is not something I’d expect to work, for any definition of work.

Try something like this:

char *token = strtok(packetBuffer, ":"); // tokenize the string using colons as the delimiters
while(token)
{
   int varNum = atoi(token);
   token = strtok(NULL, ",");
   int varVal = 0;
   if(token)
      varVal = atoi(token);

   // Use varNum to determine where to store varVal

   token = strtok(NULL, ":");
}

I just checked that out and It works YEA Im so happy now thank you.

You can also use sscanf.

char packetBuffer[64] = "1:2000,2:1463,3:1000,4:1000,5:-1,6:-1,7:-1,8:-1";

void setup() {
  Serial.begin(9600);
  int pVal[8];
  
  Serial.println("Starting");
  if(sscanf(packetBuffer,"1:%d,2:%d,3:%d,4:%d,5:%d,6:%d,7:%d,8:%d",&pVal[0],&pVal[1],&pVal[2],&pVal[3],&pVal[4],&pVal[5],&pVal[6],&pVal[7]) == 8) {
    Serial.println("Count correct");
    for( int i = 0;i<8; i++) Serial.println(pVal[i]);  
  }
  else Serial.println("Count bad");
 
}

void loop()  {
}

Surfertim, while that also worked it only read the variables one time. it was a lot faster though.I moved the script to the void loop() section and still the same thing a one time reading. I am quite happy with Pauls response and writing the pwm outputs the servos are flawless thru all 8 channels. I think i am going to try a NANO arduino out next on a R/C quad heli.

I have had problems with my Wi-Fi adapter and bandwidth because I added a Camera so I abandoned the UDP code even though it was working. I am now using a x-bee and Esplora to handle my remote. I can receive thru my serial monitor with another Arduino Uno all the movements from the Esplora as expected. I am having a hard time understanding strtok. Trying to use the code in the previous posts results in a cannot convert char to char or char to const char errors. I found some code that does compile but I can only get the first two bytes from the Esplora. I am using a SOP < for the beginning a EOP> as the ending and a comma as the delimiters. so the serial monitor varies with joystick movements but looks like this, <255,0,255,0,123,0,0,1,> I can post the Esplora code if needed but is large. the receiving code is as follows, By the way this part is borrowed and because im a newbie I have probably messed it up bad so forgive me in advance. I just want to understand how strtok works.

#define SOP '<'
#define EOP '>'
boolean started = false;
boolean ended = false;
char inData[80];
byte index;
    char *temp, *re ;
    int temp1[8]; 
    int re1[8];
void setup() {    
  Serial.begin(9600); 
}
void loop() {  
   // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
    }
  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
        for(int marker=0; marker <7; marker++){
        temp = strtok(inData,",");
        re = strtok(NULL,",");
        temp1[marker] = atoi(temp);
        Serial.print(temp1[marker]);
        Serial.print("___");
        re1[marker] = atoi(re);
        Serial.print(re1[marker]);
        Serial.print("=-=");
    }
    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}
        for(int marker=0; marker <7; marker++){
        temp = strtok(inData,",");
        re = strtok(NULL,",");

Every time through this loop, you start parsing from the beginning of inData again. Probably not what you want to do. There are other looping constructs you can use, like while, that also allow you to determine that the pointers are valid before you dereference them.

<255,0,255,0,123,0,0,1,>

This does not contain 14 tokens so it isn’t clear why you are looping 7 times, getting two tokens per pass.

I was not aware while was a loop statement. I was under the impression that while made the code stop until true. until I just read it . the 0-7 part is for a total of 8, which is my ultimate goal the signals split into 8 parts as per the first post. I am guessing that I will have (re) do nothing and change the comma to look for the end of marker '>' so the loop will make 8 passes until true. give me a minute and i will test this.

On each pass. you are trying to get two tokens. In your mind, what do those two tokens represent?

It looks like you want to move the first call to strtok() outside of the for loop, and just read 7 tokens in the loop, after reading one token outside the loop.

I was not aware while was a loop statement. I was under the impression that while made the code stop until true.

It depends on what the condition is, and what happens in the body.

I know my code is wrong that is why it looks like I am trying to read 2 points from strtok I was just trying to see what strtok was storing my goal is just to read from the buffer into one array then use strtok to store it into an array that splits it after each comma for examplevar[marker]=(stuff stored after each comma)

I know my code is wrong that is why it looks like I am trying to read 2 points from strtok I was just trying to see what strtok was storing my goal is just to read from the buffer into one array then use strtok to store it into an array that splits it after each comma for example

Your problems are deeper than just not knowing how to use strtok(). You don’t even use proper terminology. You can read into an array. That would be like trying to write from an array. Neither makes sense. You can read from a buffer. You can write to a buffer or array.

There are 8 tokens in your string. Get the first one, convert it to an int, and store it.

Then, get the other 7, converting and storing each one.

        temp = strtok(inData,",");
        temp1[0] = atoi(temp);
        Serial.print(temp1[0]);
        Serial.print("___");

        for(int marker=0; marker <7; marker++)
        {
           re = strtok(NULL, ",");
           re1[marker] = atoi(re);
           Serial.print(re1[marker]);
           Serial.print("=-=");
        }

you are right i am learning the terminology. I know what I am thinking but I cannot speak the lingo. I have been reading and reading and reading and when I’m done with that some more reading. I have cleaned up the code and double checked it. And while I have 8 channels the results vary. I will include what I am seeing on the serial monitor and the tx and rx code. Can you check for me? Note there are Serial.prints everywhere, I am using them for debugging purposes. But when I remove some of them the Arduino locks up like there are memory leaks. There might also be a timing issue because it seems that the faster I speed things up the more it locks up. Here is the transmitter code

//#include <SPI.h>
// pin 7 is d0 or recieve
// pin 8 is d1 or transmit
#include <Esplora.h>

String sop="$";
String eop=":";
String comma=",";
String final;
int potx=0;
int poty=0;
int x=0;
int y=0;
int xr=0;
int yr=0;
int leftfwd=0;
int leftrev=0;
int rightfwd=0;
int rightrev=0;
int potz=0;
int z=0;
int jbutton=1;
int ubutton=1;
int dbutton=1;
int lbutton=1;
int rbutton=1;
void setup(){ 
 Serial1.begin(9600);}
 
  void loop(){
  potx=Esplora.readJoystickX();
  poty=Esplora.readJoystickY();
  potz=Esplora.readSlider();
  jbutton=Esplora.readJoystickButton();
  ubutton=Esplora.readButton(SWITCH_UP);
  dbutton=Esplora.readButton(SWITCH_DOWN);
  lbutton=Esplora.readButton(SWITCH_LEFT);
  rbutton=Esplora.readButton(SWITCH_RIGHT);
  potx=potx+7;
  poty=poty-8;
  x=map(potx,-512,512,-250,250);
  y=map(poty,-512,512,-250,250);
  z=map(potz,0,1023,0,250);
  if(x<=0){
    xr=x*-1;
  x=0;}
    if(y<=0){
    yr=y*-1;
  y=0;}
  if(yr>=1){
    leftfwd=yr;
    rightfwd=yr;
    leftrev=0;
    rightrev=0;}
   if(y>=1){
     leftfwd=0;
     rightfwd=0;
     leftrev=y;
     rightrev=y;}
    if(x>=1 && leftfwd>=1){
      leftfwd=leftfwd-x;
      if(leftfwd<=0){
        leftfwd=0;}}
    if(xr>=1 && rightfwd>1){
     rightfwd=rightfwd-xr;
     if(rightfwd<=0){
     rightfwd=0;}}     
    if(x>=1 && leftrev>=1){
  leftrev=leftrev-x;
    if(leftrev<=0){
    leftrev=0;}}
  if(xr>=1 && rightrev>=1){
  rightrev=rightrev-xr;
  if(rightrev<=0){
   rightrev=0;}} 
    if(x==0 && y==0 && yr==0 && xr==0){
    leftfwd=0;
    leftrev=0;
    rightfwd=0;
    rightrev=0;}
    String final=sop+leftfwd+comma+leftrev+comma+rightfwd+comma+rightrev+comma+z+comma+jbutton+comma+ubutton+comma+dbutton+eop;
  
    Serial1.print(final);
    //Serial.println();
    
    
    delay(150);
  }

And the receiver

#define SOP '

Also is there a way to make that one pass thru Strtok? I know the first is for the delimiters what is NULL for as I dont have any spaces? here is the serial monitor…

0   0   0   0   0   1   0   0   0
0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0
133,0,133,0,195,1,1,1:$193,0,193,0,196,1,1,1:133   0   11312   14641   11315   11312   14641   11318   11313
133   0   133   14641   11315   11312   14641   11318   11313
133   0   133   0   11315   11312   14641   11318   11313
133   0   133   0   195   11312   14641   11318   11313
133   0   133   0   195   1   14641   11318   11313
133   0   133   0   195   1   1   11318   11313
193,0,193,0,195,1,1,1:$189,0,191,0,195,1,1,1,1,1,ÿÿÿÿÿÿÿÿÿÿÿÿÿ1,1,1,1,1,1,1,1,1,1,1,1ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0
0   0   0   0   0   0   0   0   0
209,0,209,0,195,1,1,1:ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$209,0,209,0,195,1,1,1:ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ$213,0,213,0,195,1,1,1:0   0   11312   14641   11317   11313   11313   14897   0
0   0   21   14641   11317   11313   11313   14897   0
0   0   21   0   11317   11313   11313   14897   0
0   0   21   0   0   11313   11313   14897   0
0   0   21   0   0   0   11313   14897   0
0   0   21   0   0   0   0   14897   0
217,0,217,0,195,1,1,1:$217,0,217,0,195,1,1,1:217   0   21   11264   11312   12594   11319   11312   14641
217   0   217   11264   11312   12594   11319   11312   14641
217   0   217   0   11312   12594   11319   11312   14641
217   0   217   0   195   12594   11319   11312   14641
217   0   217   0   195   1   11319   11312   14641
217   0   217   0   195   1   1   11312   14641
216,0,216,0,195,1,1,1:$217,0,217,0,195,1,1,1:217,0,217,0,195,ÿÿÿÿÿÿÿÿÿ£,1:ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ£,1:ÿÿÿÿÿ

there should’nt be anything over 3 digits. and when I made marker 0 to 7 it behaved erratically thanks for your help.
#define EOP ‘:’
char inData[25];
byte index;
char inChar;
    char *temp, *re ;
    int temp1[10];
    int re1[10];
void setup() {   
  Serial.begin(9600);
}
void loop() { 
 
  while(Serial.available() > 0)
  {
    while(inChar != SOP){
     Serial.flush();
    //Serial.println(“waiting to start”);
     inChar = Serial.read();
    }
    //Serial.read();
    while(inChar!=EOP|| index<25){
      inChar= Serial.read();
    //Serial.print(“counting “);
        inData[index] = inChar;
        Serial.print(inData[index]);
        index++;}     
  }
       //Serial.print(“count ended”);   
       temp = strtok(inData,”,”);
        temp1[0] = atoi(temp);
        //Serial.print(temp1[0]);
        //Serial.print("___");

for(int marker=0; marker <6; marker++)
        {
           re = strtok(NULL, “,”);
           re1[marker] = atoi(re);
           //Serial.print(re1[marker]);
           //Serial.print(“marker”);
           //Serial.print(marker);
           //Serial.println();
       
    // Reset for the next packet
    Serial.print(temp1[0]);
     Serial.print("   “);
    Serial.print(re1[0]);
    Serial.print(”   “);
     Serial.print(re1[1]);
     Serial.print(”   “);
     Serial.print(re1[2]);
     Serial.print(”   “);
     Serial.print(re1[3]);
     Serial.print(”   “);
     Serial.print(re1[4]);
     Serial.print(”   “);
     Serial.print(re1[5]);
     Serial.print(”   “);
     Serial.print(re1[6]);
      Serial.print(”   ");
     Serial.print(re1[7]);
      Serial.println();
    index = 0;
    inData[index] = ‘\0’;
  }
}


Also is there a way to make that one pass thru Strtok? I know the first is for the delimiters what is NULL for as I dont have any spaces? here is the serial monitor...

§DISCOURSE_HOISTED_CODE_2§


there should'nt be anything over 3 digits. and when I made marker 0 to 7 it behaved erratically thanks for your help.