Convert char to const char error?

Ok,

This is doing my head in - am trying to read a webpage off the server with CSV file and use it to change colours on an LED strip.

  • Connection to wifi works
  • Logs into server fine
  • extracts the page content fine
  • returns it to the Arduino as variable 'c'
  • then it borks when I try to convert this webpage text into a String that can be read.

Anyone offer any tips on why I'm getting the below error? I know the code is pretty cruddy, so any help appreciated - I'm just trying to understand Arduino as it's awesomely powerful!

char c = client.read();    
    String webLedFeed =  c;

Error:
HomeServer.ino: In function 'void loop()':
HomeServer:71: error: invalid conversion from 'char' to 'const char*'
HomeServer:71: error: initializing argument 1 of 'String::String(const char*)'

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

char ssid[] = "*****";      //  your network SSID (name) 
char pass[] = "****";   // your network password
int keyIndex = 0;            // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS;

// Initialize the Wifi client library
WiFiClient client;

// server address:
char server[] = "192.168.0.102";

unsigned long lastConnectionTime = 0;           // last time you connected to the server, in milliseconds
boolean lastConnected = false;                  // state of the connection last time through the main loop
const unsigned long postingInterval = 10*1000;  // delay between updates, in milliseconds

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600); 
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present"); 
    // don't continue:
    while(true);
  } 
  
  // 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(3000);
  } 
  // you're connected now, so print out the status:
  printWifiStatus();
}

void loop() {
  // if there's incoming data from the net connection.
  // send it out the serial port.  This is for debugging
  // purposes only:
  while (client.available()) {
    char c = client.read();    
    String webLedFeed =  c;
   // Serial.write(webLedFeed);
    // PARSE CSV -START


uint8_t redLed, greenLed, blueLed;
int timeLit;


if (sscanf(webLedFeed.c_str(), "!!!!!%hhu,%hhu,%hhu,%d!!!!!", &redLed, &greenLed, &blueLed, &timeLit) == 4)
{
Serial.println("redLED= ");
Serial.println(redLed);
Serial.println("greenLED= ");
Serial.println(greenLed);
Serial.println("blueLED= ");
Serial.println(blueLed);
Serial.println("Time= ");
Serial.println(timeLit);
}
else
{
  Serial.println("No data received");
}



// PARSE CSV - END
    
    
    
    
    
  }
  
  

  // if there's no net connection, but there was one last time
  // through the loop, then stop the client:
  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }

  // if you're not connected, and ten seconds have passed since
  // your last connection, then connect again and send data:
  if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    httpRequest();
  }
  // store the state of the connection for next time through
  // the loop:
  lastConnected = client.connected();
}

// this method makes a HTTP connection to the server:
void httpRequest() {
  // if there's a successful connection:
  if (client.connect(server, 80)) {
    Serial.println("connecting...");
    // send the HTTP PUT request:
    client.println("GET /homeserver/latest.txt HTTP/1.1");
    client.println("Host: 192.168.0.102");
    client.println("User-Agent: arduino-ethernet");
    client.println("Connection: close");
    client.println();





    // note the time that the connection was made:
    lastConnectionTime = millis();
  } 
  else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
    Serial.println("disconnecting.");
    client.stop();
  }
}


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");
}
String webLedFeed(c);

instead

String webLedFeed=c;

Thank you! This works a treat, although I think it's uncovered a bug in my code - I'm so close it's annoying me now!! :grin:

In short, trying to control LED strips based on file saved on web server, the remote server sends the below to the Arduino Uno through wifi shield.

What the remote server returns to the serial.read while loop:

HTTP/1.1 200 OK
Date: Sat, 11 Jan 2014 20:12:58 GMT
Server: Apache/2.2.23 (Unix)
Last-Modified: Sat, 11 Jan 2014 17:03:01 GMT
ETag: "dcc006-14-4efb4d0ad1b40"
Accept-Ranges: bytes
Content-Length: 20
Vary: Accept-Encoding
Connection: close
Content-Type: text/plain

!!!!!255,0,0,10!!!!!

Now my code is meant to be looking out for the variables at the bottom, ie:
!!!!!255,0,0,10!!!!!

And then capturing them as individual variables using:
if (sscanf(webLedFeed.c_str(), "!!!!!%hhu,%hhu,%hhu,%d!!!!!", &redLed, &greenLed, &blueLed, &timeLit) == 4)

However I figured the problem is that the script seems to be sending the above character by character, thus I need to feed it into a variable to create a full string to parse, figured this'd be something like:

char c = c + client.read();

but this produces ascii nonsense, so I'm obviously screwing something up!

/*
  Repeating Wifi Web client
 
 This sketch connects to a a web server and makes a request
 using an Arduino Wifi shield.
 
 Circuit:
 * Wifi shield attached to pins 10, 11, 12, 13
 
 created 23 April 2012
 modifide 31 May 2012
 by Tom Igoe
 
 http://arduino.cc/en/Tutorial/WifiWebClientRepeating
 This code is in the public domain.
 */

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

char ssid[] = "xxx";      //  your network SSID (name) 
char pass[] = "xxx";   // your network password
int keyIndex = 0;            // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS;

// Initialize the Wifi client library
WiFiClient client;

// server address:
char server[] = "192.168.0.102";

unsigned long lastConnectionTime = 0;           // last time you connected to the server, in milliseconds
boolean lastConnected = false;                  // state of the connection last time through the main loop
const unsigned long postingInterval = 10*1000;  // delay between updates, in milliseconds



void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600); 
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  
  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present"); 
    // don't continue:
    while(true);
  } 
  
  // 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(3000);
  } 
  // you're connected now, so print out the status:
  printWifiStatus();
}

void loop() {
  // if there's incoming data from the net connection.
  // send it out the serial port.  This is for debugging
  // purposes only:
  while (client.available()) {
    char c = client.read();    
    String webLedFeed(c);
   // Serial.write(webLedFeed);
 
    
    // PARSE CSV -START


uint8_t redLed, greenLed, blueLed;
int timeLit;


if (sscanf(webLedFeed.c_str(), "!!!!!%hhu,%hhu,%hhu,%d!!!!!", &redLed, &greenLed, &blueLed, &timeLit) == 4)
{
Serial.println("redLED= ");
Serial.println(redLed);
Serial.println("greenLED= ");
Serial.println(greenLed);
Serial.println("blueLED= ");
Serial.println(blueLed);
Serial.println("Time= ");
Serial.println(timeLit);
}
else
{
  Serial.print(webLedFeed);
  delay(100);
}



// PARSE CSV - END
     
    
  }
  
 
      

  // if there's no net connection, but there was one last time
  // through the loop, then stop the client:
  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  }

  // if you're not connected, and ten seconds have passed since
  // your last connection, then connect again and send data:
  if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    httpRequest();
  }
  // store the state of the connection for next time through
  // the loop:
  lastConnected = client.connected();
}

// this method makes a HTTP connection to the server:
void httpRequest() {
  // if there's a successful connection:
  if (client.connect(server, 80)) {
    Serial.println("connecting...");
    // send the HTTP PUT request:
    client.println("GET /homeserver/latest.txt HTTP/1.1");
    client.println("Host: 192.168.0.102");
    client.println("User-Agent: arduino-ethernet");
    client.println("Connection: close");
    client.println();





    // note the time that the connection was made:
    lastConnectionTime = millis();
  } 
  else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
    Serial.println("disconnecting.");
    client.stop();
  }
}


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");
}

but this produces ascii nonsense, so I'm obviously screwing something up!

Of course it does. A char variable can hold ONE character. An array of chars can hold more than one character, but you don't have an array, AND, the + operator is for ADDing, which makes no sense for characters.

:blush: Hmm, can you tell I'm learning........! :blush:

Ok, so I guess there's two bits then,

  1. How can I make this read as a string or array, rather than single character variable:
    char c = client.read();

Obviously not as simple as: char c[200] = c & client.read(); or something. Do I need to create a for loop that takes the variable and adds to it and an array index based on the loop index or something?

  1. Is there any way I can cut out the junk that's returned from the http get request?

ie, I only need the last line of below code, rest is just server response gumpf and connection header info that's no need.

HTTP/1.1 200 OK
Date: Sat, 11 Jan 2014 20:12:58 GMT
Server: Apache/2.2.23 (Unix)
Last-Modified: Sat, 11 Jan 2014 17:03:01 GMT
ETag: "dcc006-14-4efb4d0ad1b40"
Accept-Ranges: bytes
Content-Length: 20
Vary: Accept-Encoding
Connection: close
Content-Type: text/plain

!!!!!255,0,0,10!!!!!

alphabeta279:
2) Is there any way I can cut out the junk that's returned from the http get request?

ie, I only need the last line of below code, rest is just server response gumpf and connection header info that's no need.

HTTP/1.1 200 OK
Date: Sat, 11 Jan 2014 20:12:58 GMT
Server: Apache/2.2.23 (Unix)
Last-Modified: Sat, 11 Jan 2014 17:03:01 GMT
ETag: "dcc006-14-4efb4d0ad1b40"
Accept-Ranges: bytes
Content-Length: 20
Vary: Accept-Encoding
Connection: close
Content-Type: text/plain

!!!!!255,0,0,10!!!!!

you could do something like:

String HTTPResponse="";
while (client.available())
{
HTTPResponse += (char)client.read();
if(HTTPResponse.indexOf("Content-Type: text/plain") >= 0)
HTTPResponse = "";
}
When the loop is done e:g: client.available() ==0), you will have your last line "!!!!!255,0,0,10!!!!!" stored in HTTPResponse.

I Haven't tried the code, but you may get the idea.

assuming that the last line before your data is always: Content-Type: text/plain
you could also use a HTTPResponse .trim() to get rid of all the whitespaces etc

  1. How can I make this read as a string or array, rather than single character variable:
    char c = client.read();

You can't. The read() method was designed to return one character. Wishful thinking will not change that. There are other methods that return more than one character at a time, or you could store the individual characters in an array, until some end-of-packet or end-of-data marker arrives.

Obviously not as simple as: char c[200] = c & client.read(); or something.

Obviously, but the actual process looks a bit like that - declare an array and read one character are two parts of the actual process.

Do I need to create a for loop that takes the variable and adds to it and an array index based on the loop index or something?

Exactly.

  1. Is there any way I can cut out the junk that's returned from the http get request?

Of course. There is no junk, so there is nothing to cut out.

There may be data that is not of interest to you, but that doesn't make it junk. You still need to collect all the data that makes up a packet, and then parse the packet. You may discover that the whole packet is not of interest, and move on to the next packet.

It all depends on how you define a packet. The complete response would be one way. All the data up to a carriage return/line feed would be another way. In one case, you get one packet that contains the data you want and other stuff. In the other case, you get several packets, only one of which contains the data you want.

If you have control over the server, you can make getting, saving, and parsing the data easy or hard.