Return to Snippet

Revision: 44938
at April 21, 2011 03:17 by TioSolid


Initial Code
/*
 * Examples  : Arduino Experiment Examples By....Thai Micro Tech
 * Program   : Hardware LED
 * Hardware  : Arduino 328 and ENC28J60
 *           : ET-MINI ENC28J60(Select VCC = +5V)
 *           : SDO -> MOSI(PB3)       = Digital-11        
 *           : SDI <- MISO(PB4)       = Digital-12        
 *           : SCK -> SCK(PB5)        = Digital-13          
 *           : CS# -> SS#(PB2)        = Digital-10        
 *           : LED -> Output Pin(PB1) = Digital-9    
 * Function  : Webserver Control LED
 */

#include "etherShield.h"

#define ledPin  9  // LED Source Drive ("1" = ON , "0" = OFF)
#define ledPin2  8  // LED Source Drive ("1" = ON , "0" = OFF)
#define ledPin3  6  // LED Source Drive ("1" = ON , "0" = OFF)
#define ledPin4  5  // LED Source Drive ("1" = ON , "0" = OFF)

// please modify the following two lines. mac and ip have to be unique
// in your local area network. You can not have the same numbers in
// two devices:
static uint8_t mymac[6]   = {0x54,0x55,0x58,0x10,0x00,0x24};
static uint8_t myip[4]    = {192,168,1,201};
static char baseurl[]     = "http://192.168.1.201/";
static uint16_t mywwwport = 80; // listen port for tcp/www (max range 1-254)

#define BUFFER_SIZE 500
static  uint8_t buf[BUFFER_SIZE+1];
#define STR_BUFFER_SIZE 22
static  char strbuf[STR_BUFFER_SIZE+1];

EtherShield es=EtherShield();

// prepare the webpage by writing the data to the tcp send buffer
uint16_t print_webpage(uint8_t *buf, byte led_status);
int8_t analyse_cmd(char *str);

void setup()
{
  /*initialize enc28j60*/
  es.ES_enc28j60Init(mymac);
  es.ES_enc28j60clkout(2); // change clkout from 6.25MHz to 12.5MHz
  delay(10);
      
  /* Magjack leds configuration, see enc28j60 datasheet, page 11 */
  // LEDA=greed LEDB=yellow
  //
  // 0x880 is PHLCON LEDB=on, LEDA=on
  // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00);
  es.ES_enc28j60PhyWrite(PHLCON,0x880);
  delay(500);
  //
  // 0x990 is PHLCON LEDB=off, LEDA=off
  // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00);
  es.ES_enc28j60PhyWrite(PHLCON,0x990);
  delay(500);
  //
  // 0x880 is PHLCON LEDB=on, LEDA=on
  // enc28j60PhyWrite(PHLCON,0b0000 1000 1000 00 00);
  es.ES_enc28j60PhyWrite(PHLCON,0x880);
  delay(500);
  //
  // 0x990 is PHLCON LEDB=off, LEDA=off
  // enc28j60PhyWrite(PHLCON,0b0000 1001 1001 00 00);
  es.ES_enc28j60PhyWrite(PHLCON,0x990);
  delay(500);
  //
  // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
  // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10);
  es.ES_enc28j60PhyWrite(PHLCON,0x476);
  delay(100);
      
  //init the ethernet/ip layer:
  es.ES_init_ip_arp_udp_tcp(mymac,myip,80);
 
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);  // switch off LED
  pinMode(ledPin2, OUTPUT);
  digitalWrite(ledPin2, LOW);  // switch off LED
  pinMode(ledPin3, OUTPUT);
  digitalWrite(ledPin3, LOW);  // switch off LED
  pinMode(ledPin4, OUTPUT);
  digitalWrite(ledPin4, LOW);  // switch off LED
}

void loop()
{
  uint16_t plen, dat_p;
  int8_t cmd;
  int8_t cmd2;
  int8_t cmd3;
  int8_t cmd4;
  static byte led_status = 0;

  plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf);

  /*plen will ne unequal to zero if there is a valid packet (without crc error) */
  if(plen!=0)
  {          
    // arp is broadcast if unknown but a host may also verify the mac address by sending it to a unicast address.
    if(es.ES_eth_type_is_arp_and_my_ip(buf,plen))
    {
      es.ES_make_arp_answer_from_request(buf);
      return;
    }

    // check if ip packets are for us:
    if(es.ES_eth_type_is_ip_and_my_ip(buf,plen)==0)
    {
      return;
    }
  
    if(buf[IP_PROTO_P]==IP_PROTO_ICMP_V && buf[ICMP_TYPE_P]==ICMP_TYPE_ECHOREQUEST_V)
    {
      es.ES_make_echo_reply_from_request(buf,plen);
      return;
    }
  
    // tcp port www start, compare only the lower byte
    if (buf[IP_PROTO_P]==IP_PROTO_TCP_V&&buf[TCP_DST_PORT_H_P]==0&&buf[TCP_DST_PORT_L_P]==mywwwport)
    {
      if (buf[TCP_FLAGS_P] & TCP_FLAGS_SYN_V)
      {
        es.ES_make_tcp_synack_from_syn(buf); // make_tcp_synack_from_syn does already send the syn,ack
        return;    
      }
      if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V)
      {
        es.ES_init_len_info(buf); // init some data structures
        dat_p=es.ES_get_tcp_data_pointer();
        if (dat_p==0)
        { // we can possibly have no data, just ack:
          if (buf[TCP_FLAGS_P] & TCP_FLAGS_FIN_V)
          {
            es.ES_make_tcp_ack_from_any(buf);
          }
          return;
        }
      
        if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0)      // GET /?cmd=0, GET /?cmd=1
        {
          // head, post and other methods for possible status codes see:
          // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
          plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK
Content-Type: text/html

<h1>200 OK</h1>"));
          goto SENDTCP;
        }
  if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0)
        {
          plen=print_webpage(buf, led_status);
          goto SENDTCP;
        }
        cmd=analyse_cmd((char *)&(buf[dat_p+5]));
         cmd2=analyse_cmd((char *)&(buf[dat_p+5]));
          cmd3=analyse_cmd((char *)&(buf[dat_p+5]));
           cmd4=analyse_cmd((char *)&(buf[dat_p+5]));
      
      
        // 192.168.1.201/?led=0    
        if (cmd==0)                             // ?led=0 --> OFF
        {
          led_status = 0;
          digitalWrite(ledPin, LOW);           // LED = OFF
        }
      
        // 192.168.1.201/?led=1
        else if (cmd==1)                        // ?led=1 --> ON
        {
          led_status = 1;
          digitalWrite(ledPin, HIGH);           // LED = ON
        }
      
        
        plen=print_webpage(buf, led_status);        
SENDTCP:es.ES_make_tcp_ack_from_any(buf);       // send ack for http get
        es.ES_make_tcp_ack_with_data(buf,plen); // send data      
      }
    }
  }      
}
// The returned value is stored in the global var strbuf


uint8_t find_key_val(char *str,char *key)
{
  uint8_t found=0;
  uint8_t i=0;
  char *kp;
  kp=key;
  while(*str &&  *str!=' ' && found==0)
  {
    if (*str == *kp)
    {
      kp++;
      if (*kp == '\0')
      {
        str++;
        kp=key;
        if (*str == '=')
        {
          found=1;
        }
      }
    }
    else
    {
      kp=key;
    }
    str++;
  }
  if (found==1)
  {
    // copy the value to a buffer and terminate it with '\0'
    while(*str &&  *str!=' ' && *str!='&' && i<STR_BUFFER_SIZE)
    {
      strbuf[i]=*str;
      i++;
      str++;
    }
    strbuf[i]='\0';
  }
  return(found);
}

int8_t analyse_cmd(char *str)
{
  int8_t r=-1;
    
  if (find_key_val(str,"led"))
  {
    if (*strbuf < 0x3a && *strbuf > 0x2f)  //'0'..'9'
    {
      // is a ASCII number, return it
      r=(*strbuf-0x30);                    // Convert '0'..'9'  to 0..9
    }
  }
  return r;
}

uint16_t print_webpage(uint8_t *buf, byte on_off)
{
  int i=0;
        
  uint16_t plen;
 
  // HTML Header          
  plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK
Content-Type: text/html

"));
 
  // HTML Body
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<center><p><h1>Thai Micro Tech Test Control</h1>"));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<center><hr>"));      
 
  // Start of Form      
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<br><form METHOD=get action=\""));      
  plen=es.ES_fill_tcp_data(buf,plen,baseurl);                                          
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("\">"));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<h2>Status</h2> "));
  
  if(on_off==0)
  {
    plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<h1><font color=\"#FF0000\"> "));        
    plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("OFF"));  
  }
 
  else if(on_off==1)
  {
    plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<h1><font color=\"#00FF00\"> "));        
    plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("ON"));  
 
  }
 
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("</font></h1><br>"));

  if(on_off==0)
  {
    plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=hidden name=led value=1>"));
    plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=submit value=\"SW1 ON\">"));
     }
 
  else if(on_off==1)
  {
    plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=hidden name=led value=0>"));
    plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=submit value=\"SW1 OFF\">"));
  }
 
  // End of Form
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("</form>"));
 
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("</center><hr> <p>Webserver Control By.Thai Micro Tech <a href=\"http://www.thaimicrotech.com\"> Thai Micro Tech <a>"));
  return(plen);
}

Initial URL
http://code-all.blogspot.com/2011/01/arduino-ethernet-control-led.html

Initial Description


Initial Title
Arduino + ET-MINI ENC28J60

Initial Tags


Initial Language
C