Arduino Mega + ENC28J60

Пример скетча для работы с сетевым контроллером ENC28J60 фирмы Microchip с платой Arduino Mega.

В файле библиотеки enc28j60.c следует изменить подключение контроллера к нашей Mega следующим образом:

#define ENC28J60_CONTROL_CS		53 //10
#define SPI_MOSI			51 //11
#define SPI_MISO			50 //12
#define SPI_SCK				52 //13

То есть выводы MOSI, MISO, SCK и CS контроллера ENC28J60 подключены к таким-же выводам платы Mega.

Скетч:

// EtherShield webserver demo
//
#include "etherShield.h"
//Figley: чтение/запись EEPROM
#include <EEPROM.h>

// 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}; //наш MAC-адрес
  
static uint8_t myip[4] = {
  192,168,0,40};//наш IP-адрес

#define MYWWWPORT 80//порт
#define BUFFER_SIZE 950//размер буфера для хранения текста
static uint8_t buf[BUFFER_SIZE+1];

// The ethernet shield
EtherShield es=EtherShield();

uint16_t http200ok(void)
{
  return(es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n")));
}

// prepare the webpage by writing the data to the tcp send buffer
uint16_t print_webpage(uint8_t *buf)
{
  uint16_t plen;
  plen=http200ok();
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<html><head><title>Arduino ENC28J60 Ethernet Shield V1.0</title></head><body>"));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<center><h1>Welcome to Arduino ENC28J60 Ethernet Shield V1.0</h1>"));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<hr><br><h2><font color=\"blue\">-- Put your ARDUINO online -- "));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<br> Control digital outputs"));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<br> Read digital analog inputs HERE"));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<br></font></h2>") );
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("</center><hr>"));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("V1.0 <a href=\"http://www.nuelectronics.com\">www.nuelectronics.com</a>"));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("</body></html>"));
  return(plen);
}

//Figley: номер ячейки памяти EEPROM для хранения счётчика 
int address = 0;//макс. 4096 для Arduino Mega
int value;

void setup(){

  //Figley: init serial connection
  Serial.begin(115200);
  
  // initialize enc28j60
  es.ES_enc28j60Init(mymac);

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

void loop(){
  uint16_t plen, dat_p;

  while(1) {
    // read packet, handle ping and wait for a tcp packet:
    dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf));

    /* dat_p will be unequal to zero if there is a valid 
     * http get */
    if(dat_p==0){
      // no http request
      continue;
    }
    // tcp port 80 begin
    if (strncmp("GET ",(char *)&(buf[dat_p]),4)!=0){
      // head, post and other methods:
      dat_p=http200ok();
      dat_p=es.ES_fill_tcp_data_p(buf,dat_p,PSTR("<h1>200 OK</h1>"));
      goto SENDTCP;
    }
    // just one web page in the "root directory" of the web server
    if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){
      dat_p=print_webpage(buf);
      //читаем счётчик, увеличиваем и пишем его обратно
      value = EEPROM.read(address);
      value++;
      if (value == 255) value = 0;
      EEPROM.write(address,value);
      //выведем значение:
      Serial.print("Index page read counter: ");
      Serial.println(value);
      goto SENDTCP;
    }
    else{
      dat_p=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 401 Unauthorized\r\nContent-Type: text/html\r\n\r\n<h1>401 Unauthorized</h1>"));
      goto SENDTCP;
    }
SENDTCP:
    es.ES_www_server_reply(buf,dat_p); // send web page data
    // tcp port 80 end
  }
}


Ведётся подсчёт запросов страницы (до 256), результат сообщается в последовательный порт.

Что можно улучшить:

  1. Научиться писать в EEPROM данные не по одному байту, а хотя-бы строки и числа больше 255.
  2. Научиться создавать web-страницы на лету, а не только выдавать клиенту содержимое подготовленного буфера.
  3. Научиться получать прерывание от ENC28J60.
  4. научиться читать заготовки web-страниц из EEPROM, внутренней и внешней.

Залишити відповідь