Пример скетча для работы с сетевым контроллером 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), результат сообщается в последовательный порт.
Что можно улучшить:
- Научиться писать в EEPROM данные не по одному байту, а хотя-бы строки и числа больше 255.
- Научиться создавать web-страницы на лету, а не только выдавать клиенту содержимое подготовленного буфера.
- Научиться получать прерывание от ENC28J60.
- научиться читать заготовки web-страниц из EEPROM, внутренней и внешней.