Hi Guys, Im new to the forum so i hope i will fit in properly. My question is that i successfully set up my arduino wifi shield to accept serial data from external program (Putty) through wifi. The problem lies on the data collected and how its being collected. First i put the data into a string until the break command, then i tried to parse the string into 4 parts of integers (the command is a PS3 controller that sends data like 255 255 255 255 to arduino). I was able to parse the first two integers, wether they are 2 digits or 3. But the last two integers i couldnt get them with my code below so i really need some help getting them, no matter if they are 1 2 or 3 digits (3 maximum) each. Thank you in advance.
You should find what you want in the demos here and here
The Arduino code in the first demo works fine with the serial monitor. Note how it uses a < before and a > after the data to tell the Arduino where the data begins and ends.
parse.substring(parse.indexOf(" ") + 1, parse.indexOf(" "));
is position and length
If you are sure that your third number has the same number of characters are your first number.
If parse is "123 190 42 175", what will a, b, c, and p be?
The way I see it, a will be "123", since it is the portion of parse up to the first space.
Then, b will be "190 42 175", since it is the portion of parse from just beyond the first space to the end of the String. Converting this to an int doesn't make sense.
Then, c will be "", since the range of the substring is from 4 to 3. I can't imagine that this is what you want.
Then, p will be "42 175", since it is the portion of b from just after the space to the end of b. Again, converting this to an int does not make sense.
I think that you should first locate the positions of all three spaces in parse, and then creating the substrings.
Well, actually, I don't think you should be using the String class at all. What you want to do is trivial using strtok() and atoi() on a NULL terminated array of chars.
Its a great script, i just read and used the attached arduino sketch but honestly it doesnt really do what i want. You see, the program im using to send the command externally is like a DOS terminal that has completely restricted boundaries as to how you can configure it to do its job. The data sent to arduino is restricted to be only in this form:
255 255 255 255
what separates the integers is a space. I just simply want a code that, when i send this command in DOS, arduino shows me in the serial monitor as it is, ofcourse generated by an integer printing.Im pretty sure there is a simple code that does that in arduino..probably as simple as the blink code but im just not being smart enough to get it (atleast i got half...lol). Again thanx !
Yes, strtok and atoi are better way i suppose. what about this code. The output was good for first integers but the last two integers,instead of the number i got 0 0.
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);
The data sent to arduino is restricted to be only in this form:
Well, what you need to determine is if the "255 255 255 255" character string is actually terminated in some way, such as a carriage return/line feed characters. If so, then capturing the string and parsing it with the string functions should be fairly simple. The below test code shows operations somewhat similar to what you seem to want to do.
//zoomkat 11-12-13 String capture and parsing
//from serial port input (via serial monitor)
//and print result out serial port
//copy test strings and use ctrl/v to paste in
//serial monitor if desired
// * is used as the data string delimiter
// , is used to delimit individual data
String readString; //main captured String
String angle; //data String
String fuel;
String speed1;
String altidude;
int ind1; // , locations
int ind2;
int ind3;
int ind4;
void setup() {
Serial.begin(9600);
Serial.println("serial delimit test 11-12-13"); // so I can keep track of what is loaded
}
void loop() {
//expect a string like 90,low,15.6,125*
//or 130,hi,7.2,389*
if (Serial.available()) {
char c = Serial.read(); //gets one byte from serial buffer
if (c == '*') {
//do stuff
Serial.println();
Serial.print("captured String is : ");
Serial.println(readString); //prints string to serial port out
ind1 = readString.indexOf(','); //finds location of first ,
angle = readString.substring(0, ind1); //captures first data String
ind2 = readString.indexOf(',', ind1+1 ); //finds location of second ,
fuel = readString.substring(ind1+1, ind2+1); //captures second data String
ind3 = readString.indexOf(',', ind2+1 );
speed1 = readString.substring(ind2+1, ind3+1);
ind4 = readString.indexOf(',', ind3+1 );
altidude = readString.substring(ind3+1); //captures remain part of data after last ,
Serial.print("angle = ");
Serial.println(angle);
Serial.print("fuel = ");
Serial.println(fuel);
Serial.print("speed = ");
Serial.println(speed1);
Serial.print("altidude = ");
Serial.println(altidude);
Serial.println();
Serial.println();
readString=""; //clears variable for new input
angle="";
fuel="";
speed1="";
altidude="";
}
else {
readString += c; //makes the string readString
}
}
}
PaulS:
Your proof? You need to post some code, and the output proving what the input to the function is, and what each of the tokens are.
char *ipaddress = "192 128 1 50";
char *token = strtok(ipaddress, " ");
// token should be 192
if(token)
partOne = atoi(token);
token = strtok(NULL, " ");
// token should be 128
if(token)
partTwo = atoi(token);
token = strtok(NULL, " ");
// token should be 1
if(token)
partThree = atoi(token);
token = strtok(NULL, " ");
// token should be 50
if(token)
partFour = atoi(token);
You kinda used the same technique i used to parse the header into the next " " and i dont know why u asked for my proof. I posted my whole code or atleast the one that i need help in.
for(int i = 0; i < 4; i++)
{
if(i == 0) lX = atoi(pch); // only assigned when i is 0 and is OFF in any other cases
if(i == 1) lY = atoi(pch); // when i is 1
if(i == 2) rX = atoi(pch); // when i is 2
if(i == 3) rY = atoi(pch); // when i is 3
pch = strtok (NULL," "); // in every loop at this line, the value in pch passes one " "
}
so to answer your question, pch points to the next " " everytime strtok is called, in which i, on the other side is incremented by one and it will affect only one value from lX lY rX rY. for example if lets say the serial that comes is 123 423 853 419 then first the loop process will begin,i is 0 which will affect lX and atoi will assign 123 to lX. on the last line of every loop strtok (NULL," ") will move the pointer to the next " " in pch value. so next round i will be 1 and it will affect lY which atoi will assign 423 to lY because pch pointer is already pointing to start from 423 from last line of the previous loop round. Same goes to the rest. But why am i getting 0 0 values on 3rd and 4th integers? and more importantly ( as you are asking for proof) why,if im wrong with the code, am i getting right values for 1st and 2nd integers that are lX and lY?
HERE I NEED TO CONVERT MY inData STRING INTO CHAR * TOKEN SO THAT MY NEXT LINES WILL WORK !!
No, you don't. You should NOT being using the String class. At all.
Learn to use NULL terminated arrays of chars.
You are expecting 4 tokens with up to 3 characters per token plus 3 separators. Add one for the terminating NULL, and a 20 element array is plenty. No need to fragment memory using the String class when a static 20 element array uses less than 1% of SRAM.
// Process message when new line character is recieved
if (recieved == '\n')
{
inData.toCharArray(charBuf, 20) ;
char *token = strtok(charBuf, " "); //Serial.print(inData);
// token should be 192
if(token)
partOne = atoi(token);
token = strtok(NULL, " ");
// token should be 128
if(token)
partTwo = atoi(token);
token = strtok(NULL, " ");
// token should be 1
if(token)
partThree = atoi(token);
token = strtok(NULL, " ");
// token should be 50
if(token)
partFour = atoi(token);
Serial.println(partOne);
// You can put some if and else here to process the message juste like that:
Serial.println(partTwo);
Serial.println(partThree);
Serial.println(partFour);
//if(inData == "+++\n"){ // DON'T forget to add "\n" at the end of the string.
// Serial.println("OK. Press h for help.");
//}
inData = ""; // Clear recieved buffer
}
}
}
The biggest lesson i took in this topic is, not the coding knowledge, but the fact that Arduino board is 2 different things when powered externally and powered with just USB. The code above works perfect when you power Arduino from external source. When only powering it with the USB cable, only first 2 parsed integers print, Thus in the code above, partThree and partFour print 0 nomatter whats your input.
Again thanx alot guys,your support directly affects the way we handle Arduino and its beautiful coding system !!!
When only powering it with the USB cable, only first 2 parsed integers print, Thus in the code above, partThree and partFour print 0 nomatter whats your input.
If the USB cable isn't connected, where is the serial data coming from?