Here is a quick sample sketch describing what I am trying to accomplish.
char signal;
int signalStrength;
void setup(){}
void loop(){
signal='+CSQ: 18,0';//code to be parsed
//extraction code I need help with
signalStrength='18';//pull just the number 18 as an int.
//This number will change and can be a number from 1 - 99. So, either single or dual digit.
}
I am new to arduino so If you could post an example, that would help. Thanks in advance.
Sorry, like I said, I am new at this. Used to PHP. This is just an example code btw. So for this corrected code,
String signal;
int signalStrength = 0;
void setup(){}
void loop(){
signal="+CSQ: 18,0";//code to be parsed
//extraction code I need help with
signalStrength=18;//pull just the number 18 as an int.
//This number will change and can be a number from 1 - 99. So, either single or dual digit.
}
How would I make this function to pull the number from the string to an int?
ironchariot:
Sorry, like I said, I am new at this. Used to PHP. This is just an example code btw. So for this corrected code,
I have a program I wrote for a different purpose, but part of it may help you. I just ripped this out of my code and edited it slightly for your use... may need a touch or two... but the idea is there:
int parse (const char *str)
{
const char *find = "+CSQ: ";
char *ptr;
int x, y;
int length;
length = strlen (find)-1; /* how many chars to find */
ptr = str; /* pointer to string */
y = 0;
/*
* "| |<--- parse to here
* "+CSQ: 18,0 <-- then atoi() the value
*/
for (x = 0; x < count; x++) {
if (str[x] == find[y]) {
if (y == length) {
ptr += x; /* move pointer to start of number */
} else {
y++;
}
} else {
y = 0;
}
}
return atoi (ptr);
}
Krupski:
I have a program I wrote for a different purpose, but part of it may help you. I just ripped this out of my code and edited it slightly for your use... may need a touch or two... but the idea is there:
I may be doing it wrong. I keep getting
error: invalid conversion from 'const char*' to 'char*'
Simple code you can try by sending your string via the serial monitor.
String readString, number;
void setup() {
Serial.begin(9600);
Serial.println("number test"); // so I can keep track of what is loaded
}
void loop() {
while (Serial.available()) {
delay(2);
if (Serial.available() >0) {
char c = Serial.read(); //gets one byte from serial buffer
readString += c; //makes the string readString
}
}
if (readString.length() >0) {
Serial.print("readString is: ");
Serial.println(readString); //see what was received
Serial.println();
// expect a string like +CSQ: 18,0
number = readString.substring(6, 10); //get characters from readString
Serial.print("number String is: ");
Serial.println(number); //see what substrring is
Serial.println();
//int will get numerals until it reaches a non numeral character
int n = (number.toInt());
Serial.print("your number is: ");
Serial.println(n);
readString="";
}
}
Krupski:
I have a program I wrote for a different purpose, but part of it may help you. I just ripped this out of my code and edited it slightly for your use... may need a touch or two... but the idea is there:
I may be doing it wrong. I keep getting
error: invalid conversion from 'const char*' to 'char*'
on
ptr = str; /* pointer to string */
Yeah I goofed. As I said, I pulled it out of another program I had and tried to tie up the loose ends.
The "int parse (const char *str)" thing should be "int parse (char *str)" (take out the "const" part).
Here's the whole demo.... tested too!
void setup (void)
{
Serial.begin (115200);
char *string = "+CSQ: 18,0";
int value;
value = parse (string);
Serial.print ("Parsed ");
Serial.print (value, DEC);
Serial.print (" from ");
Serial.print (string);
Serial.println();
}
void loop (void)
{
}
int parse (char *str)
{
const char *find = "+CSQ: ";
char *ptr;
int x, y;
int length;
int count = strlen (str);
length = strlen (find)-1; /* how many chars to find */
ptr = str; /* pointer to string */
y = 0;
for (x = 0; x < count; x++) {
if (str[x] == find[y]) {
if (y == length) {
ptr += x; /* move pointer to start of number */
} else {
y++;
}
} else {
y = 0;
}
}
return atoi (ptr);
}
Krupski:
I have a program I wrote for a different purpose, but part of it may help you. I just ripped this out of my code and edited it slightly for your use... may need a touch or two... but the idea is there:
I may be doing it wrong. I keep getting
error: invalid conversion from 'const char*' to 'char*'
on
ptr = str; /* pointer to string */
Yeah I goofed. As I said, I pulled it out of another program I had and tried to tie up the loose ends.
The "int parse (const char *str)" thing should be "int parse (char *str)" (take out the "const" part).
Here's the whole demo.... tested too!
void setup (void)
{
Serial.begin (115200);
char *string = "+CSQ: 18,0";
int value;
value = parse (string);
Serial.print ("Parsed ");
Serial.print (value, DEC);
Serial.print (" from ");
Serial.print (string);
Serial.println();
}
void loop (void)
{
}
int parse (char *str)
{
const char *find = "+CSQ: ";
char *ptr;
int x, y;
int length;
int count = strlen (str);
length = strlen (find)-1; /* how many chars to find /
ptr = str; / pointer to string */
y = 0;
for (x = 0; x < count; x++) {
if (str[x] == find[y]) {
if (y == length) {
ptr += x; /* move pointer to start of number */
} else {
y++;
}
} else {
y = 0;
}
}
return atoi (ptr);
}
That did it!!!!! Thank you. I have spent days on this. I need to buy you a beer.
//number parse 12/13/13 zoomkat
String readString, numberString;
void setup() {
Serial.begin(9600);
Serial.println("number test"); // so I can keep track of what is loaded
}
void loop() {
while (Serial.available()) {
delay(2);
if (Serial.available() >0) {
char c = Serial.read(); //gets one byte from serial buffer
readString += c; //makes the string readString
}
}
if (readString.length() >0) {
Serial.print("readString is: ");
Serial.println(readString); //see what was received
// expect a string like AT+CSQn\n\n+CSQ: 18,0
int pos = readString.indexOf(' ');
numberString = readString.substring(pos+1); //get characters from readString
Serial.print("number String is: ");
Serial.println(numberString); //see what substrring is
//int will get numerals until it reaches a non numeral character
int n = (numberString.toInt());
Serial.print("your number is: ");
Serial.println(n);
Serial.println();
readString="";
numberString="";
}
}
ironchariot,
it is worth spending some time reading over the documenation and getting familiar with these types of libC functions.
My choice is to use the 40+ year old functions that were created to make life easier whenever possible, rather
than write custom string parsing since it often is not necessary.
(But then I've been using unix platforms for more than 30 years)
Once you start to get familiar with them you will find that they tend to be very consistent.
Another good thing is that versions of these functions tend to available across many languages.
A few things:
A newline is not /n a newline is \n
Keep in mind that a newline is considered white space and not a normal character when parsing the line for input.
There is information about the parsing of white space if you read the man page
for sscanf()
If all you want to do is throw away the first 2 strings before a number, then that would be:
int parse(char *str)
{
int count = 0;
sscanf(str, "%*s%*s%d", &count);
return(count);
}
If you want an EXACT match, then use this:
int parse(char *str)
{
int count = 0;
sscanf(str, "AT+CSQ\n\n+CSQ:%d", &count);
return(count);
}
If you just want the integer just after a colon you could use:
#include <string.h>
int parse(char *str)
{
char *p;
int count = 0;
p = strrchr(str, ':'); // find last colon
if(p)
{
p++; // skip over colon
count = atoi(p);
}
return(count);
}
And like I said before the nice thing about sscanf() is that you could also use it to extract
whatever you want/need into other variables
in case you want/need other information from the string besides this single number.
i.e. you might want to look at the various other strings returned.