Ethernet Shield String vs Char

Greetings

I am working on a web mail notifier. The ethernet shield connects to my server then uses "GET" to grab data. The data is then displayed on a small Nokia LCD. Currently the ethernet shield is able to accomplish this, however it outputs each character individually. Is there a way I can get all characters into a string so that they are displayed all at once?

The code im working with now:

/*
  Web client
 
 This sketch connects to a website (http://www.google.com)
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 
 created 18 Dec 2009
 by David A. Mellis
 
 *///BEGIN NOKIA SCREEN SETTINGS
#include "PCD8544.h"
PCD8544 nokia = PCD8544(7, 6, 5, 4, 3);



//END NOKIA SCREEN SETUP
#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1,185 };
byte server[] = { 192,168,1,23}; // Google
byte gateway[] = {192,168,1,1};
byte dns[] = {192,168,0,1};

// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
Client client(server, 80);


void setup() {

  //NOKIA
  
  
   nokia.init();
  // you can change the contrast around to adapt the display
  // for the best viewing!
  nokia.setContrast(55);
  // turn all the pixels on (a handy test)
  nokia.command(PCD8544_DISPLAYCONTROL | PCD8544_DISPLAYALLON);
  delay(500);
  // back to normal
  nokia.command(PCD8544_DISPLAYCONTROL | PCD8544_DISPLAYNORMAL);

  // show splashscreen
  nokia.display();
  //delay(2000);
  nokia.clear();
  
  //END NOKIA
  
  
  
  
  
  
  // start the Ethernet connection:
  Ethernet.begin(mac, ip);
  // start the serial library:
  Serial.begin(9600);
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect()) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /alertbox.php?name=mc");
    client.println();
    

  
} 
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop()
{
  // if there are incoming bytes available 
  // from the server, read them and print them:

  if (client.available()) {
   char c = client.read()     

    
   //Serial.println(c,BIN);
       
       //DISPLAY ON NOKIA - I WANT ALL CHARACTERS TO BE DISPLAYED ON THE NOKIA NOT JUST ONE AT A TIME.
       
       
       
    // draw a string at location (0,0)
  nokia.setCursor(0, 0);
  nokia.print(c);
  nokia.display();
  delay(100);
  //nokia.clear();     
       
       
       //END DISPLAY ON NOKIA
       
  
}



  // if the server's disconnected, stop the client:
  if (!client.connected()) {
  nokia.setCursor(0, 0);
  nokia.print("Connection Has Failed!");
  nokia.display();
  delay(100);
  nokia.clear();     
       
    client.stop();

    // do nothing forevermore:
    for(;;)
      ;
  }
}

Any help is greatly appreciated.

Is there a way I can get all characters into a string so that they are displayed all at once?

Yes. Create a char array, and store the characters in the array, instead of writing them to the Nokia screen. When the array is full, or all the data is received, show it on the screen.

That makes sense... I understand exactly what you mean. I took a look at http://www.arduino.cc/en/Reference/String the string reference. I will be honest, im not sure how to take

char c = client.read()

and enter it into an array and ultimately display them on the screen. Can you (or anyone else on the forums) explain how I might go about doing this? Thanks again.

char array[16]; // Hold up to 16 characters
byte index = 0;

while(client.available())
{
   char c = client.read();
   if(index < 15)
   {
      array[index] = c;
      index++;
      array[index] = '\0';
   }
   else
      break;
}
// array is full, or there is no more data

I tried it, but when the ethernet shield connects it returns a *... and thats it. Do you know why its doing this?

I tried it

Not that I doubt you, but, we need to see your code.

You have a point.

/*
  Web client
 
 This sketch connects to a website (http://www.google.com)
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 
 created 18 Dec 2009
 by David A. Mellis
 
 *///BEGIN NOKIA SCREEN SETTINGS
#include "PCD8544.h"
PCD8544 nokia = PCD8544(7, 6, 5, 4, 3);



//END NOKIA SCREEN SETUP
#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1,160};
byte server[] = { 192,168,1,23}; // My Server
byte gateway[] = {192,168,1,1};
byte dns[] = {192,168,0,1};

// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
Client client(server, 80);


void setup() {

  //NOKIA
  
  
   nokia.init();
  // you can change the contrast around to adapt the display
  // for the best viewing!
  nokia.setContrast(55);
  // turn all the pixels on (a handy test)
  nokia.command(PCD8544_DISPLAYCONTROL | PCD8544_DISPLAYALLON);
  delay(500);
  // back to normal
  nokia.command(PCD8544_DISPLAYCONTROL | PCD8544_DISPLAYNORMAL);

  // show splashscreen
  nokia.display();
  //delay(2000);
  nokia.clear();
  
  //END NOKIA
  
  
      // draw a string at location (0,0)
  nokia.setCursor(0, 0);
  nokia.print("Alert Box-DIAS");
  nokia.setCursor(0, 30);
    nokia.print("Boot up...");
  nokia.display();
  delay(2000);
  nokia.clear();  
  
 
  
  // start the Ethernet connection:
  Ethernet.begin(mac, ip);
  // start the serial library:
  Serial.begin(9600);
  // give the Ethernet shield a second to initialize:
  delay(1000);

  
  
    nokia.setCursor(0, 0);
  nokia.print("Connecting...");

    nokia.setCursor(0, 30);
    nokia.print("Please Wait.");
  nokia.display();  
 nokia.clear(); 
  
  

  // if you get a connection, report back via serial:
  if (client.connect()) {
    Serial.println("connected");
  
    // Make a HTTP request:
    client.println("GET /somepage?data=something");
    client.println();
    

  
} 
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop()
{
  // if there are incoming bytes available 
  // from the server, read them and print them:

  if (client.available()) {
     

char array[16]; // Hold up to 16 characters 
byte index = 0;

while(client.available())
{
   char c = client.read();
   if(index < 15)
   {
      array[index] = c;
      index++;
      array[index] = '\0';
   }
   else
      break;
}
// array is full, or there is no more data

  if (!client.connected()) {
  nokia.setCursor(0, 0);
  nokia.print(index);
  nokia.display();
  delay(5000);
  nokia.clear();  




  // if the server's disconnected, stop the client:
  if (!client.connected()) {
  nokia.setCursor(0, 0);
  nokia.print("Connection Has Failed!");
  nokia.display();
  delay(100);
  nokia.clear();     
       
    client.stop();

    // do nothing forevermore:
    for(;;)
      ;
  }
}
  nokia.print(index);

The variable index contains the number of characters in the array. The variable array contains the data. Perhaps you meant to print array.

How much data are you expecting back? How much can you display on the Nokia? The array is sized for 16 characters. Is that a reasonable value?

I may be receiving up to 280 characters. I believe that I can auto scroll the lcd, unless you know otherwise? If nokia.print(index) is incorrect, how do I print the characters rather than a number or symbol in my case? Could it be that I am receiving more data than the array can handle, thus the reason for the unexpected characters?

how do I print the characters rather than a number or symbol in my case?

I told you:

nokia.print(array);

I may be receiving up to 280 characters.

Then a size of 16 is not reasonable, is it? Make the array larger, as well as the limit before breaking out of the while loop.

Could it be that I am receiving more data than the array can handle, thus the reason for the unexpected characters?

No. You stop reading, on one pass through loop, when the array is full. The "unexpected characters" are because you are printing the wrong thing.

Some test code that downloads a lot of data from a NOAA site and extracts what is desired using some string functions. You could test to see if all of your data can be held in a string.

//zoomkat 12-22-10
//simple ethernet client test code
//for use with IDE 0021 and W5100 ethernet shield
//modify the arduino lan ip address as needed
//open serial monitor to see what the arduino receives
//push the shield reset button to run client again

#include <SPI.h>
#include <Ethernet.h>
String readString, readString1;
int x=0;
char lf=10;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 102 };
byte server[] = { 140, 90, 238, 27 }; // NOAA

Client client(server, 80);

void setup()
{
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
  Serial.println("starting simple arduino client test");
  Serial.println();
  Serial.println("connecting...");

  if (client.connect()) {
    Serial.println("connected");
    client.println("GET /data/5day2/44013_5day.txt HTTP/1.0");
    client.println();
  } else {
    Serial.println("connection failed");
  }
}

void loop()
{
  if (client.available()) {
    char c = client.read();
    //Serial.print(c);  // uncomment to see raw feed
    if (c==lf) x=(x+1);
    if (x==14) readString += c;
    //readString += c;
  }

  if (!client.connected()) {
     client.stop();

    Serial.println("Current data row:" );
    Serial.print(readString);
    Serial.println();
    readString1 = (readString.substring(41,43));
    Serial.println();
    Serial.print("DPD sec: ");
    Serial.println(readString1);
    Serial.println("done");

    for(;;);

    }
 }

Great, that seems to be working. It still types it out one character at a time, but it accumulates, so you can read the whole thing. After it reads all the data from the server, it disconnects. I would like it to continue to check for new messages, rather than disconnect. In other words the client should ALWAYS be connected. Do I just move the void loop up?

Code:

/*
  Web client
 
 This sketch connects to a website (http://www.google.com)
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 
 created 18 Dec 2009
 by David A. Mellis
 
 *///BEGIN NOKIA SCREEN SETTINGS
#include "PCD8544.h"
PCD8544 nokia = PCD8544(7, 6, 5, 4, 3);



//END NOKIA SCREEN SETUP
#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,1,182};
byte server[] = { 192,168,1,23}; // Google
byte gateway[] = {192,168,1,1};
byte dns[] = {192,168,0,1};

// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
Client client(server, 80);


void setup() {

  //NOKIA
  
  
   nokia.init();
  // you can change the contrast around to adapt the display
  // for the best viewing!
  nokia.setContrast(55);
  // turn all the pixels on (a handy test)
  nokia.command(PCD8544_DISPLAYCONTROL | PCD8544_DISPLAYALLON);
  delay(500);
  // back to normal
  nokia.command(PCD8544_DISPLAYCONTROL | PCD8544_DISPLAYNORMAL);

  // show splashscreen
  nokia.display();
  //delay(2000);
  nokia.clear();
  
  //END NOKIA
  
  
      // draw a string at location (0,0)
  nokia.setCursor(0, 0);
  nokia.print("Alert Box-DIAS");
  nokia.setCursor(0, 30);
    nokia.print("Boot up...");
     
  nokia.display();
  delay(2000);
  nokia.clear();  
  

  
  
    nokia.setCursor(0, 0);
  nokia.print("DIAS ID:");
  nokia.setCursor(0, 30);
    nokia.print("SOMEID");
     
  nokia.display();
  delay(5000);
  nokia.clear();  
  

 
  
  // start the Ethernet connection:
  Ethernet.begin(mac, ip);
  // start the serial library:
  Serial.begin(9600);
  // give the Ethernet shield a second to initialize:
  //delay(1000);

  
  
    nokia.setCursor(0, 0);
  nokia.print("Connecting...");

    nokia.setCursor(0, 30);
    nokia.print("Please Wait.");
  nokia.display();  
 nokia.clear(); 
  
  

  // if you get a connection, report back via serial:
  if (client.connect()) {
    Serial.println("connected");
  
  
      nokia.setCursor(0, 0);
  nokia.print("SERVER:");
 nokia.print("http://MYSITE");
  nokia.print("Status: Success");
 delay(1000);
  nokia.display();  
 nokia.clear(); 
  
  
    // Make a HTTP request:
    client.println("GET /SOMEPAGE.php");
    client.println();
    

  
} 
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
    
        nokia.setCursor(0, 0);
  nokia.print("Connection Err");
        nokia.setCursor(0, 20);
        nokia.print("Are you");
        nokia.print(" connected");
        nokia.print(" to the");
        nokia.print(" internet?");

  nokia.display();  
 nokia.clear(); 
 
 
  }
}

void loop()
{

  // if there are incoming bytes available 
  // from the server, read them and print them:

  if (client.available()) {
     
// array is full, or there is no more data

  if (client.connected()) {
    

 
char array[26]; // Hold up to 16 characters 
byte index = 0; 
    char c = client.read();   
   
   while(client.available())
{
   char c = client.read();
   if(index < 25)
   {
      array[index] = c;
      index++;
      array[index] = '\0';



    nokia.setCursor(0, 0);
  nokia.print(array);
  nokia.display();
 //delay(500);
  nokia.clear();  


 
   }
   else
      break;
}
   

    
    

  


}

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
  nokia.setCursor(0, 0);
  nokia.print("Connection Has Failed!");
  nokia.display();
  delay(100);
  nokia.clear();     
       
    client.stop();

    // do nothing forevermore:
    for(;;)
      ;
  }
}
}

I would like it to continue to check for new messages, rather than disconnect. In other words the client should ALWAYS be connected.

This is not the way client/server communication works. When the client wants data, it opens a connection, requests the data, and closes the connection. The server will ensure that that happens by closing the connection when it has done sending the reply.

Each time you want new data, you need to open a new connection.

So then it would be impossible to continue to make new requests to the server... even with a for or while or some kind of loop?

I don't have any looping client code, but you may be able to make something from the pachube code in the below discussions.

http://www.google.com/search?q=pachube+site%3Ahttp%3A%2F%2Farduino.cc%2Fforum%2Findex.php&hl=en&num=100&lr=&ft=i&cr=&safe=images

Everyone has heard of the famous Gmail Checker or Twitter Feed. Isn't this similar? Except I am retrieving other data? Could I store the server request in a function, then call it again when its done? I checked out the link, ill have to continue to do some research on it. I dint realize that a task thought to be simple would be so difficult to accomplish. Such is the learning process :frowning:

Now feeling quite proud of myself, I have figured out a way to loop the client. Simply store the "WebClient" in a function. When it disconnects place a call to the function... It will loop forever.

Does anyone know how I can display all of the data in the array in one chunk, rather than it typing out character by character?

Code:

  nokia.print(array);

returns something like H E L L O W O R L D character by character rather than Hello World all at once.

So then it would be impossible to continue to make new requests to the server... even with a for or while or some kind of loop?

Concrete questions are much easier to answer than abstract questions. In general, though, it is better to make one request for multiple answers than it is to try to maintain an open connection and make multiple requests of the same server.

That is not how your browser works. That is the model that you should be considering when trying to make the Arduino, as a client, interface with a server.

The server data changes when ever I get a new message. If you are comparing it to a web browser, I would think its just like hitting F5, reload the page, send a new request and get the new data. In regards to my previous question do you know anything about it?

Now feeling quite proud of myself, I have figured out a way to loop the client. Simply store the "WebClient" in a function. When it disconnects place a call to the function... It will loop forever.

Care to share your code? I'd lke to have code that will connect to a server when the arduino detects an event. :slight_smile: