I'm reading a series of char[20] and converting that into a string "Data" so that I can use the #include <string.h> substring . as you can see in the code i'm always going to be parsing 3 digit (positive) numbers to store then in the EEPROM. I've attached the snipped of code where my problem is with and example string. My problem seams to be when i use the atoi function. Any help?
#include <String.h>
#include <EEPROM.h>
char incomingSerialDataString[20] = "IP 192.168.001.011";
String Data = incomingSerialDataString;
if(Data.startsWith("IP"))
{
String FirstIP = Data.substring(3,6);
String SecondIP = Data.substring(7,10);
String ThirdIP = Data.substring(11,14);
String ForthIP = Data.substring(15,18);
Serial.println(FirstIP);
Serial.println(SecondIP);
Serial.println(ThirdIP);
Serial.println(ForthIP);
int First = atoi(FirstIP);
int Second = atoi(SecondIP);
int Third = atoi(ThirdIP);
int Forth = atoi(ForthIP);
EEPROM.write(0, First);
EEPROM.write(1, Second);
EEPROM.write(2, Third);
EEPROM.write(3, Forth);
}
I'm not near an Arduino right now, and I can't find the source in the Arduino package, but I would have to assume since this compiles in the first place that the library handles it intelligently.
from version 22 the string class contains a toInt() member function. See - C:\Program Files (x86)\arduino-0022\hardware\arduino\cores\arduino\Wstring.h - (Win 7)
So you could place the substring in a separate string XXX and call x = XXX.toInt();
Alternatively, get rid of the String object altogether. Everything you are doing with String::substring can be done with strtok() instead. The output from the strtok() function is a NULL-terminated array of characters, which is exactly what atoi() wants.
Getting rid of the String object will greatly reduce the size of your code. In addition, the strtok() function does not care how long the substring is. You can then parse the more normal "IP 192.168.1.11".
Somewhat klunky, but another way of changing a string to an integer.
Serial.println(readstring); //so you can see the captured string
char carray[readstring.length() + 1]; //determine size of the array
readstring.toCharArray(carray, sizeof(carray)); //put readstring into an array
int n = atoi(carray); //convert the array into an Integer
char incomingSerialDataString[20] = "IP 192.168.1.11";
char *token;
byte addr[4];
byte index;
void setup()
{
token = strtok(incomingSerialDataString, " "); // Couldn't you have used a longer name?
// token will be "IP", and the space will be skipped.
index = 0;
token = strtok(NULL, ","); // token will be "192"
while(token)
{
if(index < 4)
addr[index++] = atoi(token); // addr[0] will be 192...
token = strtok(NULL, ","); // token will be "168", "1", "11", and NULL
}
}
void loop()
{
}
Thanks PaulS! I replaced the "," with "." and your example code helped a LOT. It didn't save much room on the Arduino but it was a lot clearer looking then the alternatives out there and saved me an #include.
Thanks everyone for the input.
PS I like using very descriptive variable names so when i look at the code a year or 2 from now it will make sense faster and copy and paste are a great thing.
It works perfect in the example, I just don't understand where the 20 comes from...
I tried adapting the code to my needs:
char recieveDate[20] = "setDate 2017.12.31.6.14.51.11";
// Year.Month.Day of month.Day of week (1-7).Hour.Minute.Second
Since I have 7 fields (tokens?) (0-6) I thought I would change byte addr[7];
and if(index < 7)
I increased the [20] to [30] and the output I receive is:
225
12
31
6
14
51
11
I am sure this is very basic for most people here but I have a hard time finding the information on google, probably because I am searching with the wrong questions
I don't understand why it would output 255 instead of 2017
Could someone shine some light on what this number [20] means and how to calculate the correct number?
Thanks in advance!
char recieveDate[30] = "setDate 2017.12.31.6.14.51.11"; // Year.Month.Day of month.Day of week (1-7).Hour.Minute.Second
// char myStr[] = "setDate 2017.12.31.6.14.51.11"; // Year.Month.Day of month.Day of week (1-7).Hour.Minute.Second
char *token;
byte addr[7];
byte index;
void setup()
{
Serial.begin(9600); // serial communication to check the data on serial monitor
token = strtok(recieveDate, " "); // Couldn't you have used a longer name?
// token will be "IP", and the space will be skipped.
index = 0;
token = strtok(NULL, "."); // token will be "192"
while(token)
{
if(index < 7)
addr[index++] = atoi(token); // Assign addr[x] to the tokens (x = 0-6)
token = strtok(NULL, ".");
}
}
void loop()
{
Serial.println(addr[0]);
Serial.println(addr[1]);
Serial.println(addr[2]);
Serial.println(addr[3]);
Serial.println(addr[4]);
Serial.println(addr[5]);
Serial.println(addr[6]);
Serial.println(" ");
// Serial.println(sizeof(myStr));
Serial.println(" ");
delay(10000);
}
I solved my problem for many years to come so it's no longer an issue for me
And I found out that I will have to read up on allocated memory.
char recieveDate[] = "setDate 17.12.31.6.14.51.11"; // Year.Month.Day of month.Day of week (1-7).Hour.Minute.Second
char* strDays[]={"SUNDAY", "MONDAY", "TUESDAY","WEDNESDAY", "THURSDAY","FRIDAY", "SATURDAY"};
char *token;
byte addr[7];
byte index;
void setup()
{
Serial.begin(9600); // serial communication to check the data on serial monitor
token = strtok(recieveDate, " "); // Couldn't you have used a longer name?
// token will be "IP", and the space will be skipped.
index = 0;
token = strtok(NULL, "."); // token will be "192"
while(token)
{
if(index < 7)
addr[index++] = atoi(token); // Assign addr[x] to the tokens (x = 0-6)
token = strtok(NULL, ".");
}
}
void loop()
{
Serial.println(addr[0]+2000);
Serial.println(addr[1]);
Serial.println(addr[2]);
Serial.println(strDays[addr[3]]);
Serial.println(addr[4]);
Serial.println(addr[5]);
Serial.println(addr[6]);
Serial.println(" ");
Serial.println(" ");
delay(15000);
}