Arduino – Ethercard

Arduino – Ethercard – Multiple browser request example

posted in: Arduino | 1

I’ve recently been looking at the Ethercard library that allows the use of low cost enc28j60 based Ethernet modules with the Arduino.

I noticed on the jeelabs forum that there was some confusion about the asynchronous nature of the callback operation of the browseUrl function, so I’ve written an example of how to make multiple browseUrl calls, using a finite state machine to manage the overall flow of the program.

I’ve attached a zipped copy of the sketch file (for Arduino 1.0), and I’ve also posted the code below.

Please note. The Ethercard library is not extremely robust at the time of posting, and its possible that even with the timeouts that I’ve included in this code that it may fail to operate after days or weeks of continuous use.

// Demo of multiple browseUrl requests
// By Roger Clark. 
// www.rogerclark.net
// 2012/11/10
// http://opensource.org/licenses/mit-license.php
//
// This demo retrieves two different pages on the same website


#include "EtherCard.h"


// ethernet interface mac address, must be unique on the LAN
static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
char website[] PROGMEM = "www.rogerclark.net";
byte Ethernet::buffer[700];
static uint32_t timer;
int state;

#define TIMEOUT_MS 5000

// Called for each packet of returned data from the call to browseUrl (as persistent mode is set just before the call to browseUrl)
static void browseUrlCallback1 (byte status, word off, word len) 
{
   Ethernet::buffer[off+len] = 0;// set the byte after the end of the buffer to zero to act as an end marker (also handy for displaying the buffer as a string)
   
   Serial.println("Callback 1");
   Serial.println((char *)(Ethernet::buffer+off));
   state=3;// Move to state that causes next browseUrl
 }
 
 static void browseUrlCallback2 (byte status, word off, word len) 
{
   Ethernet::buffer[off+len] = 0;// set the byte after the end of the buffer to zero to act as an end marker (also handy for displaying the buffer as a string)

   Serial.println("Callback 2");
   Serial.println((char *)(Ethernet::buffer+off));

   state=5;// go back to waiting state
 }

void setup () 
{
  Serial.begin(115200);
  Serial.println("\n[Multiple browseUrl request example");

  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) 
  {
    Serial.println( "Error:Ethercard.begin");
    while(true);
  }

  if (!ether.dhcpSetup())
  {
    Serial.println("DHCP failed");
    while(true);
  }
  
  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);  
  ether.printIp("DNS: ", ether.dnsip); 

#if 0
  // Wait for link to become up - this speeds up the dnsLoopup in the current version of the Ethercard library
  while (!ether.isLinkUp())
  {
      ether.packetLoop(ether.packetReceive());
  }
#endif
long t=millis();
  if (!ether.dnsLookup(website,false))
  {
    Serial.println("DNS failed. Unable to continue.");
    while (true);
  }
  Serial.println(millis()-t);
  ether.printIp("SRV: ", ether.hisip);
  
  state=0;
}

void loop () 
{
  byte len;
  //ether.packetLoop(ether.packetReceive());
  switch (state)
  {
    case 0:
    if (millis() > timer) 
    {
    timer = millis() + 15000;// every 30 secs
    state=1;
    }

    break;
     case 1:
      while(ether.packetLoop(ether.packetReceive()));

      Serial.println("\nSending request for page /webservices/dateUTC.php");

      ether.browseUrl(PSTR("/webservices/dateUTC.php"), "", website, browseUrlCallback1);
      state=2;// Go to state to wait for response from browseURL

     timer = millis() + TIMEOUT_MS;// 5 second timeout
     break;
     case 2:
       if (millis() > timer)
       {
         // timeout waiting for response
         state=1;
         Serial.println("TIMOEOUT");
       }
       // waiting for response from previois calback
       ether.packetLoop(ether.packetReceive());
       break;
     case 3:
    
        while( ether.packetLoop(ether.packetReceive()));
         
        Serial.println("\nSending request for page /webservices/timeUTC.php");
        ether.browseUrl(PSTR("/webservices/timeUTC.php"), "", website, browseUrlCallback2);
        state = 4;
        timer = millis() + TIMEOUT_MS;// 5 second timeout
     break;
     case 4:
       if (millis() > timer)
       {
 
         // timeout waiting for response
         state=3;
         Serial.println("TIMOEOUT");
       }
       // waiting for response from previois calback
       ether.packetLoop(ether.packetReceive());
       break;
      case 5:
       // waiting for response from previois calback
        while( ether.packetLoop(ether.packetReceive()));
        state=0;
       break;
    default:
    break;
  }
}

  1. Ignacas
    |

    Roger,
    You are genius:) World lacks this kind of person.
    Cheers!