I am sending a two integer , comma separated string (e.g " ,1234,5678,") to a webserver on an esp8266.
I am reading that string onto a second Client ESP and now want to convert the string back into the two integers for processing on the client arduino.
Can anybody suggest the best way to achieve this simple task, I have spent a day trying all solutions but keep coming up against the problem of converting a String to char. What am I missing?
String somestringthing="";
int floppiedoor = 98222;
somestringthing ="44444444";
floppiedoor = (int)somestringthing;
don't work?
Use JSON data. Once you understand the working methode, easy to use.
Sadly not but thanks, fails to compile: " invalid cast from type 'String' to type 'int' "
Did you strip out the ,
before trying to convert it to an int?
void fParseLIDAR_ReceivedSerial ( void * parameters )
{
// distribute received LIDAR info
String sTmp = "";
sTmp.reserve ( 20 );
String sMessage = "";
sMessage.reserve ( StringBufferSize300 );
for ( ;; )
{
EventBits_t xbit = xEventGroupWaitBits (eg, evtParseLIDAR_ReceivedSerial, pdTRUE, pdTRUE, portMAX_DELAY) ;
xQueueReceive ( xQ_LIDAR_Display_INFO, &sMessage, QueueReceiveDelayTime );
// Serial.println ( sMessage );
int commaIndex = sMessage.indexOf(',');
sTmp.concat ( sMessage.substring(0, commaIndex) );
sMessage.remove( 0, (commaIndex + 1) ); // chop off begining of message
// Serial.println ( sTmp );
if ( sTmp == "!" )
{
xSemaphoreGive ( sema_LIDAR_OK );
// Display info from LIDAR
sLIDAR_Display_Info = sMessage;
}
if ( sTmp == "$" )
{
xEventGroupSetBits( eg1, evtResetWatchDogVariables );
}
if ( sTmp == "#")
{
// Serial.println ( "#" );
xSemaphoreTake( sema_LIDAR_Alarm, xSemaphoreTicksToWait );
sLIDAR_Alarm_info = sMessage;
xSemaphoreGive( sema_LIDAR_Alarm );
xEventGroupSetBits( eg, evtfLIDAR_Alarm );
}
// Serial.println ( "parse serial ok" );
sTmp = "";
sMessage = "";
xSemaphoreGive( sema_ParseLIDAR_ReceivedSerial );
// Serial.print( "fParseReceivedSerial " );
// Serial.print(uxTaskGetStackHighWaterMark( NULL ));
// Serial.println();
// Serial.flush();
}
vTaskDelete( NULL );
} // void fParseReceivedSerial ( void * parameters )
If you use C-strings, the functions atoi() and strtok() are all you need.
Example:
// examples of strtok()
char delim[] = " :,"; //substring delimiters
void setup() {
char* pch;
char message[] = "X, 35.3 Y: 44 Z:10.5";
Serial.begin(115200);
Serial.print("message >");
Serial.print(message);
Serial.println("<");
pch = strtok(message, delim);
Serial.print("strtok returns >");
Serial.print(pch);
Serial.println("<");
pch = strtok(NULL, delim);
Serial.print("strtok returns >");
Serial.print(pch);
Serial.println("<");
Serial.print("atoi returns: ");
Serial.println(atoi(pch));
Serial.print("atof returns: ");
Serial.println(atof(pch));
// etc.
}
void loop() {}
Thanks for your suggestion, your example code compiles OK but there was no serial output at all. It also doesn't seem to address the fact that I have a String containing the data and have repeatedly failed to convert this to char. I am well out of my depth on this!
It does not matter. The code returns two separate strings - it al what you need to parse two values. Convert it to integer if you need - it is up to you.
yes, commas removed, your snippet still fails to compile due to "invalid cast from type 'String' to type 'int'
Did you happen to post your latest coding attempt that failed or am I supposed to guess what code you wrote?
100% if the String contains an int and nothing but an int (int)
will convert the String to an int.
Or are you wanting to
?
Which one is it int or char?
AND POST YOUR CODE IN CODE TAGS, all your code.
>
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
ESP8266WiFiMulti WiFiMulti;
int PV, MAINS, OTHER;
char buf;
void setup() {
Serial.begin(115200);
Serial.println();
Serial.println();
Serial.println();
for (uint8_t t = 4; t > 0; t--) {
Serial.printf("[SETUP] WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
WiFi.mode(WIFI_STA);
WiFiMulti.addAP("deleted", "deleted"); //SSID&PASSWORD
payload.toCharArray(buf, 9);
Serial.println(buf);
payload.toCharArray(buf, payload.length());
Serial.println(buf);
int PV, MAINS, OTHER;
}
void loop() {
// wait for WiFi connection
if ((WiFiMulti.run() == WL_CONNECTED)) {
WiFiClient client;
HTTPClient http;
Serial.print("[HTTP] begin...\n");
if (http.begin(client, "http://192.168.1.155")) { // HTTP
Serial.print("[HTTP] GET...\n");
int httpCode = http.GET();// start connection and send HTTP header
if (httpCode > 0) { // httpCode will be negative on error
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) { // file found at server
String payload = http.getString(); //picks up string from local web server
Serial.println(payload); //confirms string collected OK
payload.toCharArray(buf, payload.length()); //fails to compile invalid conversion from 'char' to 'char*' [-fpermissive]
}
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
} else {
Serial.printf("[HTTP} Unable to connect\n");
}
}
if (sscanf(payload, "%d,%d,", &PV, &MAINS) == 2) { // do something with int variables
Serial.print("PV is: ");
Serial.println(PV);
Serial.print("MAINS is: ");
Serial.println(MAINS);
Serial.print("b is: ");
Serial.println(OTHER);
}
delay(10000);
}
/>
Apologies. This code is now a bit of a mess having tried several different ways to achieve a result. The above does not compile, as stated earlier. All I wanted to do was to convert the string "payload" "1234,5678" into two variables. So converting to int would be perfect.
Your buf
is a SINGLE char variable. It can't contains more than ONE SINGLE char.
For string you need a char array with length, enough to store your text + 1 symbol.
For example, for string "1234,5678" you need an array of 10 chars:
char buf[10];
After defining buf
as an array this line should compile fine:
When you fix previous issue with buf
variable - parse the buf with sscanf()
function as shown below:
if (sscanf(buf, "%d,%d", &PV, &MAINS) == 2) { // do something with int variables
Serial.print("PV is: ");
Serial.println(PV);
Serial.print("MAINS is: ");
Serial.println(MAINS);
Serial.print("b is: ");
Serial.println(OTHER);
}
Some good results already from posting your code.
Here is how I receive serial String data.
void fReceiveSerial_LIDAR( void * parameters )
{
char OneChar;
char *str;
str = (char *)ps_calloc(300, sizeof(char) ); // put str buffer into PSRAM
bool BeginSentence = false;
sSerial.reserve ( StringBufferSize300 );
for ( ;; )
{
EventBits_t xbit = xEventGroupWaitBits (eg, evtReceiveSerial_LIDAR, pdTRUE, pdTRUE, portMAX_DELAY);
if ( LIDARSerial.available() >= 1 )
{
while ( LIDARSerial.available() )
{
OneChar = LIDARSerial.read();
if ( BeginSentence )
{
if ( OneChar == ‘>’)
{
if ( xSemaphoreTake( sema_ParseLIDAR_ReceivedSerial, xSemaphoreTicksToWait10 ) == pdTRUE )
{
xQueueOverwrite( xQ_LIDAR_Display_INFO, ( void * ) &sSerial );
xEventGroupSetBits( eg, evtParseLIDAR_ReceivedSerial );
//
}
BeginSentence = false;
break;
}
sSerial.concat ( OneChar );
}
else
{
if ( OneChar == ‘<’ )
{
sSerial = “”; // clear string buffer
BeginSentence = true; // found begining of sentence
}
}
} // while ( LIDARSerial.available() )
} //if ( LIDARSerial.available() >= 1 )
xSemaphoreGive( sema_ReceiveSerial_LIDAR );
}
vTaskDelete( NULL );
} //void fReceiveSerial_LIDAR( void * parameters )
Might or might not help.
This has really helped me, thank you b707. There were several other glitches in my code so I will post the final working version in the hope that it may help the next utterly confused person.
Most likely, you forgot to set the serial monitor to 115200 Baud rate.
Thanks to the several people who responded quickly to my confusion. To remind us of what I was needing to do, I was importing a String containing two values separated by a comma from an ESP8266 webserver. I wanted to convert the String back into the two integers on the client ESP to allow me to use them to call actions according to their numerical value.
This cut down example works and explains itself on the serial monitor, I hope somebody finds it helpful to avoid the bewilderment I felt.
/*CONVERTING A STRING INTO VARIABLES, BASIC WORKING EXAMPLE
A String named "payload" containing values separated by commas
is imported from a webserver and converted to usable variables
*/
#include <Arduino.h>
int PV, MAINS; //The two variables I want to use for comparison
char buf[16]; //The buffer to store the string for conversion, big enough to hold 15 characters and NULL terminator
void setup() {
Serial.begin(115200);
}
void loop() {
//String payload = http.getString(); //picks up string from local web server
String payload = "1234,5678 0"; //inserted for demo only, to simulate values from web, inc 0 as NULL Terminator
Serial.print("String Payload reads as: "); //for debugging only
Serial.println(payload); //confirms string collected OK
payload.toCharArray(buf, payload.length()); //Write the string to the Buffer buf
Serial.print("buffer holds this: "); //for debugging only
Serial.println(buf); //for debugging only
(sscanf(buf, "%d,%d", &PV, &MAINS) == 2); // assign values to PV and MAINS variables, (split by COMMA)
Serial.print("PV is: "); //Debugging to ensure correct working
Serial.println(PV); //Debugging to ensure correct working
Serial.print("MAINS is: "); //Debugging to ensure correct working
Serial.println(MAINS); //Debugging to ensure correct working
delay(2000);
}
Congratulations
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.