Categories

A sample text widget

Etiam pulvinar consectetur dolor sed malesuada. Ut convallis euismod dolor nec pretium. Nunc ut tristique massa.

Nam sodales mi vitae dolor ullamcorper et vulputate enim accumsan. Morbi orci magna, tincidunt vitae molestie nec, molestie at mi. Nulla nulla lorem, suscipit in posuere in, interdum non magna.

Arduino reading a CSV pachube feed with the ENC28J60

The question of how to do GET requests with the ENC28J60 arose recently so here is an example.
This is using the etherShield from Nuelectronics and @andrewdlindsay‘s etherShield library.

The code assumes some familiarity with the ethershield examples.

#include <etherShield.h>

static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x28};
static uint8_t myip[4] = {192,168,1,25};
// Default gateway. The ip address of your DSL router. It can be set to the same as
// websrvip the case where there is no default GW to access the
// web server (=web server is on the same lan as this host)
static uint8_t gwip[4] = {192,168,1,1};

//============================================================================================================
// Pachube declarations
//============================================================================================================
#define PORT 80                   // HTTP

// the etherShield library does not really support sending additional info in a get request
// here we fudge it in the host field to add the API key
// Http header is
// Host: <HOSTNAME>
// X-PachubeApiKey: xxxxxxxx
// User-Agent: Arduino/1.0
// Accept: text/html
#define HOSTNAME "www.pachube.com\r\nX-PachubeApiKey: xxxxxxxxxxxxxxxxxxxxxxxxxxx"          // my API key
static uint8_t websrvip[4] = {173,203,98,29};  // www.pachube.com
#define HTTPPATH "/api/9999.csv"      // The feed

EtherShield es=EtherShield();

#define BUFFER_SIZE 500
static uint8_t buf[BUFFER_SIZE+1];

void browserresult_callback(uint8_t statuscode,uint16_t datapos){
 Serial.print("Received data, status:"); Serial.println(statuscode,DEC);
 if (datapos != 0)
 {
  Serial.println((char*)&buf[datapos]);
  // now search for the csv data - it follows the first blank line
  // I'm sure that there is an easier way to search for a blank line - but I threw this together quickly
  // and it works for me.
  uint16_t pos = datapos;
  while (buf[pos])    // loop until end of buffer (or we break out having found what we wanted)
  {
   while (buf[pos]) if (buf[pos++] == '\n') break;   // find the first line feed
   if (buf[pos] == 0) break; // run out of buffer
   if (buf[pos++] == '\r') break; // if it is followed by a carriage return then it is a blank line (\r\n\r\n)
  }
  if (buf[pos])  // we didn't run out of buffer
  {
   pos++;  //skip over the '\n' remaining
   Serial.print("CSV line is:");
   Serial.println((char*)&buf[pos]);
  }
 }
}

void setup(){
 Serial.begin(9600);
 Serial.println("Ethershield Get example");

 /*initialize enc28j60*/
 es.ES_enc28j60Init(mymac);

 //init the ethernet/ip layer:
 es.ES_init_ip_arp_udp_tcp(mymac, myip, PORT);

 // init the web client:
 es.ES_client_set_gwip(gwip);  // e.g internal IP of dsl router

 es.ES_client_set_wwwip(websrvip);  // target web server

}

void loop()
{
 static uint32_t timetosend;
 uint16_t dat_p;
 while(1){
  // handle ping and wait for a tcp packet - calling this routine powers the sending and receiving of data
  dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf));
  if (dat_p == 0)
  {
   if (millis() - timetosend > 10000)  // every 10 seconds
   {
    timetosend = millis();
    Serial.println("Sending request");
    // note the use of PSTR - this puts the string into code space and is compulsory in this call
    // second parameter is a variable string to append to HTTPPATH, this string is NOT a PSTR
    es.ES_client_browse_url(PSTR(HTTPPATH), NULL, PSTR(HOSTNAME), &browserresult_callback);
   }
  }
 }
}

1 comment to Arduino reading a CSV pachube feed with the ENC28J60