Search This Blog

Showing posts with label Ethernet. Show all posts
Showing posts with label Ethernet. Show all posts

Sunday, September 12, 2010

Arduino Ethernet Clock Code


// Code to run an internet enabled digital clock
// gets data off the web and parses it
// Tom Wilson 9/2010
// Hardware is an Arduino D, Ethernet shield, and a big 20x4 LCD

#include <Ethernet.h>
// Borrowed code from a couple blogs....
// DHCP support
// Author: Jordan Terrell - blog.jordanterrell.com
//http://blog.jordanterrell.com/post/Arduino-DHCP-Library-Version-04.aspx
#include "Dhcp.h"

//Code to parse and scrape out the data you want
//http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1231812230

#include <LiquidCrystal.h>

// Include description files for other libraries used (if any)
#include <string.h>

// Define Constants
// Max string length may have to be adjusted depending on data to be extracted
#define MAX_STRING_LEN  21

// Setup vars
char tagStr[MAX_STRING_LEN] = "";
char dataStr[MAX_STRING_LEN] = "";
char tmpStr[MAX_STRING_LEN] = "";
char endTag[3] = {'<', '/', '\0'};
int len;
int line_num = 0;
int j = 0;

// Flags to differentiate XML tags from document elements (ie. data)
boolean tagFlag = false;
boolean dataFlag = false;

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 6 , 5, 4, 3, 2);

boolean ipAcquired = false;
byte mac[] = { 0xDE, 0xAD, 0xDE, 0xED, 0xBE, 0xEF };
//byte ip[] = { 192, 168, 1, 113 }; for non dhcp
//byte server[] = { 72, 14, 204, 99 }; // Google
//byte server[] = { 76, 13, 115, 78 }; // yahooapis
byte server[] = { 199, 211, 133, 239 }; // tycho.usno.navy.mil

Client client(server, 80);

void setup()
{
  Serial.begin(9600);

  lcd.begin(20, 4);
  //backlight on pin 8
  pinMode(8, OUTPUT);
  digitalWrite(8, LOW);

  // some router may require a delay before it will route network packets
  // add a delay if needed:
  Serial.println("delaying...");
  delay(5000);
  Serial.println("getting ip...");
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("getting ip address...");
  int result = Dhcp.beginWithDHCP(mac);

  if(result == 1)
  {
    ipAcquired = true;
    digitalWrite(8, HIGH);
    
    byte buffer[6];
    Serial.println("ip acquired...");
    lcd.clear();

    Dhcp.getMacAddress(buffer);
    Serial.print("mac address: ");
    printArray(&Serial, ":", buffer, 6, 16);
  
    Dhcp.getLocalIp(buffer);
    Serial.print("ip address: ");
    printArray(&Serial, ".", buffer, 4, 10);

    //print the ip address to screen
    lcd.setCursor(0,0);
    lcd.print("IP Address obtained");
    lcd.setCursor(0,1);
    lcd.print(buffer[0],DEC);
    lcd.setCursor(3,1);
    lcd.print(".");
    lcd.setCursor(4,1);
    lcd.print(buffer[1],DEC);
    lcd.setCursor(7,1);
    lcd.print(".");
    lcd.setCursor(8,1);
    lcd.print(buffer[2],DEC);
    lcd.setCursor(11,1);
    lcd.print(".");
    lcd.setCursor(12,1);
    lcd.print(buffer[3],DEC);
  
    Dhcp.getSubnetMask(buffer);
    Serial.print("subnet mask: ");
    printArray(&Serial, ".", buffer, 4, 10);

    //print the ip address to screen
    lcd.setCursor(0,2);
    lcd.print(buffer[0],DEC);
    lcd.setCursor(3,2);
    lcd.print(".");
    lcd.setCursor(4,2);
    lcd.print(buffer[1],DEC);
    lcd.setCursor(7,2);
    lcd.print(".");
    lcd.setCursor(8,2);
    lcd.print(buffer[2],DEC);
    lcd.setCursor(11,2);
    lcd.print(".");
    lcd.setCursor(12,2);
    lcd.print(buffer[3],DEC);
  
    Dhcp.getGatewayIp(buffer);
    Serial.print("gateway ip: ");
    printArray(&Serial, ".", buffer, 4, 10);


    Dhcp.getDhcpServerIp(buffer);
    Serial.print("dhcp server ip: ");
    printArray(&Serial, ".", buffer, 4, 10);
  
    //print the ip address to screen
    lcd.setCursor(0,3);
    lcd.print(buffer[0],DEC);
    lcd.setCursor(3,3);
    lcd.print(".");
    lcd.setCursor(4,3);
    lcd.print(buffer[1],DEC);
    lcd.setCursor(7,3);
    lcd.print(".");
    lcd.setCursor(8,3);
    lcd.print(buffer[2],DEC);
    lcd.setCursor(11,3);
    lcd.print(".");
    lcd.setCursor(12,3);
    lcd.print(buffer[3],DEC);
  
    Dhcp.getDnsServerIp(buffer);
    Serial.print("dns server ip: ");
    printArray(&Serial, ".", buffer, 4, 10);
  
    delay(5000);
    /*
    Serial.println("connecting...");

    if (client.connect()) {
      Serial.println("connected");
      client.println("GET /search?q=arduino HTTP/1.0");
      client.println();
    } else {
      Serial.println("connection failed");
    }
    */
  
  }
  else {
    Serial.println("unable to acquire ip address...");
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("unable to acquire ip address");
  }

  delay(1000);


  Serial.println("connecting...");
  lcd.setCursor(0,0);
  lcd.print("Connecting...     ");


  if (client.connect()) {
    Serial.println("connected");
    digitalWrite(8, HIGH);
    lcd.clear();

    delay(2000);
    client.println("GET  /cgi-bin/timer.pl HTTP/1.0");  //get military time
    client.println();
  
  } else {
    Serial.println("connection failed");
    digitalWrite(8, LOW);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Connection Failed    ");
  }

}

void loop()
{

  line_num = 0;
  delay(1000);

  Serial.println("connecting...");
  
  while (client.available()) {
    serialEvent();
  }

  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    Serial.print("client.status = ");
    Serial.println(client.status(),DEC);

   client.stop();

  Serial.println("connecting...");

  delay(2000);
  if (client.connect()) {
    digitalWrite(8, HIGH);
    Serial.println("connected");
    client.println("GET  /cgi-bin/timer.pl HTTP/1.0");  //get military time
    client.println();
  
  } else {
    digitalWrite(8, LOW);
    Serial.println("connection failed");
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Connection Failed    ");
  }
  }
}

// Process each char from web
void serialEvent() {

   // Read a char
char inChar = client.read();
   //Serial.print(".");

   if (inChar == '<') {
      addChar(inChar, tmpStr);
      tagFlag = true;
      dataFlag = false;

   } else if (inChar == '>') {
      addChar(inChar, tmpStr);

      if (tagFlag) {    
         strncpy(tagStr, tmpStr, strlen(tmpStr)+1);
      }

      // Clear tmp
      clearStr(tmpStr);

      tagFlag = false;
      dataFlag = true;    
    
   } else if (inChar != 10) {
      if (tagFlag) {
         // Add tag char to string
         addChar(inChar, tmpStr);

         // Check for </XML> end tag, ignore it
         if ( tagFlag && strcmp(tmpStr, endTag) == 0 ) {
            clearStr(tmpStr);
            tagFlag = false;
            dataFlag = false;
         }
      }
    
      if (dataFlag) {
         // Add data char to string
         addChar(inChar, dataStr);
      }
   }

   // If a LF, process the line
   if (inChar == 10 ) {

/*
      Serial.print("tagStr: ");
      Serial.println(tagStr);
      Serial.print("dataStr: ");
      Serial.println(dataStr);
*/

      // Find specific tags and print data
      if (matchTag("<BR>")) {
         Serial.print(line_num);
         Serial.print(dataStr);
         Serial.println("");
         //lcd.setCursor(0,line_num);  
         //lcd.print(dataStr);
         if ((line_num > 0) & (line_num < 5)) {
             lcd.setCursor(0,line_num-1);  
             lcd.print(dataStr);
         } else {
             //line_num = 0;
         }
         line_num = line_num + 1;
         //if (line_num >4) line_num = 0;
      }

      
      // Clear all strings
      clearStr(tmpStr);
      clearStr(tagStr);
      clearStr(dataStr);

      // Clear Flags
      tagFlag = false;
      dataFlag = false;
   }
}

/////////////////////
// Other Functions //
/////////////////////

// Function to clear a string
void clearStr (char* str) {
   int len = strlen(str);
   for (int c = 0; c < len; c++) {
      str[c] = 0;
   }
}

//Function to add a char to a string and check its length
void addChar (char ch, char* str) {
   char *tagMsg  = "<TRUNCATED_TAG>";
   char *dataMsg = "-TRUNCATED_DATA-";

   // Check the max size of the string to make sure it doesn't grow too
   // big.  If string is beyond MAX_STRING_LEN assume it is unimportant
   // and replace it with a warning message.
   if (strlen(str) > MAX_STRING_LEN - 2) {
      if (tagFlag) {
         clearStr(tagStr);
         strcpy(tagStr,tagMsg);
      }
      if (dataFlag) {
      //   clearStr(dataStr);
      //   strcpy(dataStr,dataMsg);  just stop instead of killing the string
      }

      // Clear the temp buffer and flags to stop current processing
      clearStr(tmpStr);
      tagFlag = false;
      dataFlag = false;

   } else {
      // Add char to string
      if ((ch != '.') & (ch != ',')) str[strlen(str)] = ch;
   }
}

// Function to check the current tag for a specific string
boolean matchTag (char* searchTag) {
   if ( strcmp(tagStr, searchTag) == 0 ) {
      return true;
   } else {
      return false;
   }
}

void printArray(Print *output, char* delimeter, byte* data, int len, int base)
{
  char buf[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

  for(int i = 0; i < len; i++)
  {
    if(i != 0)
      output->print(delimeter);
    
    output->print(itoa(data[i], buf, base));
  }

  output->println();
}

Got the arduino ethernet shield working

Ordered an ethernet shield from ebay, and it was shipped from Hong Kong.  It cost 9.95 plus another 9.95 to ship.  I got it in about a week.  I was kinda shocked it came so fast.  Plugged it in and the lights flashed.  Tried the ethernet client and server apps, neither would work.  Fooled with my router, trying to see what IP address was assigned to it.  It never showed up on the DHCP table in the router.  I decided it was busted.

Eventually I gave up and ordered for $39
http://www.hacktronics.com/Arduino/Arduino-Ethernet-Shield/flypage.tpl.html
I bought it through Amazon, but now i see it is out of stock.  It had an SD card slot and was much nicer than the chinese one i bought.  My router saw it immediately, and after changing the IP address to the one my router showed in the DHCP table, and changing the server to google for me.  This is done by
using cmd in the run box and opening a terminal window. type ping www.google.com and you will get back the local IP address for google.    Uploaded to the arduino and ba da bing, data started pouring back.

I found that someone had developed a DHCP version of the ethernet library, that worked perfectly
http://blog.jordanterrell.com/post/Arduino-DHCP-Library-Version-04.aspx
This was awesome.   You download and replace the Arduino libraries.  I had trouble at first getting it to find an IP address, until i notice the line that said some routers need a delay to work, and a delay statement commented out.   I uncommented it, and bingo.  The IP address was obtained at home , and also at work where we have a typical big company network monstrosity.

I used this and the tycho navy time site, and the yahoo stock download pages to write an app to pull some data down and made a little desk clock with an LCD display.  Within the weekend of getting the ethernet shield, my little toy was done!