ciao a tutti, dopo molte peripezie sono riuscito finalmente a far funzionare in maniera stabile nel tempo la mia scheda ethernet ENC28J60
ho usato come sketch quello intitolato “web_switch”, ossia digitando su una pagina web l’indirizzo IP della shield, accedo alla sua pagina e posso attivare o disattivare un pulsante che poi controllerà un LED presente su arduino.
Fino a qui tutto bene, ora vorrei semplicemente aumentare il numero dei pulsanti che posso gestire ( e quindi anche il numero delle relative uscite ), ma analizzando lo sketch non riesco davvero a capire il modo per farlo; trovo difficoltà soprattutto sul lato pagina web, ossia non capisco quali parametri dovrei aggiungere o modificare per ottenere quello che voglio.
Vi posto lo sketch:
#include "etherShield.h"
static uint8_t mymac[6] = {0x54,0x55,0x58,0x10,0x00,0x24}; // Indirizzo MAC della shield ENC28J60
static uint8_t myip[4] = {192,168,1,20}; // Indirizzo IP della shield ENC28J60
static char baseurl[]="http://192.168.1.20/"; // URL della pagina dove verrano visualizzati i dati
static uint16_t mywwwport =80; // Porta in ascolto
#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();
// Preparazione della pagina web
uint16_t print_webpage(uint8_t *buf, byte on_off);
int8_t analyse_cmd(char *str);
// LED sul pin 4 usato come dispositivo da attivare o disattivare
#define LED_PIN 4
void setup(){
/*inizializzazione enc28j60*/
es.ES_enc28j60Init(mymac);
es.ES_enc28j60clkout(2); // cambio clkout da 6.25MHz a 12.5MHz
delay(10);
/* Configurazione dei LED del connettore ethernet della shield */
// LEDA=verde LEDB=giallo
//
// 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);
//inizializzazione del layer ethernet/ip:
es.ES_init_ip_arp_udp_tcp(mymac,myip,80);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW); // accendi il LED
}
void loop(){
uint16_t plen, dat_p;
int8_t cmd;
byte on_off = 1;
plen = es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf);
/* plen sarà diverso da zero se vi è un pacchetto valido (senza errore CRC) */
if(plen!=0){
// arp è trasmesso se sconosciuto, ma un host può comunque verificare l'indirizzo MAC inviandogli un indirizzo unicast //
if(es.ES_eth_type_is_arp_and_my_ip(buf,plen)){
es.ES_make_arp_answer_from_request(buf);
return;
}
// Controlla se i pacchetti IP sono per noi //
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;
}
// la porta tcp www si avvia, confronto solo il byte più basso //
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 ha già inviato il syn,ack
return;
}
if (buf[TCP_FLAGS_P] & TCP_FLAGS_ACK_V){
es.ES_init_len_info(buf); // inizializzo alcune strutture dati
dat_p=es.ES_get_tcp_data_pointer();
if (dat_p==0){ // possiamo non avere nessun dato, solo 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){
plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>200 OK</h1>"));
goto SENDTCP;
}
if (strncmp("/ ",(char *)&(buf[dat_p+4]),2)==0){
plen=print_webpage(buf, on_off);
goto SENDTCP;
}
cmd=analyse_cmd((char *)&(buf[dat_p+5]));
if (cmd==2){
on_off=1;
digitalWrite(LED_PIN, LOW); // Accendi il LED
}
else if (cmd==3){
on_off=0;
digitalWrite(LED_PIN, HIGH); // Spegni il LED
}
plen=print_webpage(buf, on_off);
plen=print_webpage(buf, on_off);
SENDTCP: es.ES_make_tcp_ack_from_any(buf); // Manda ack per ottenere l'http
es.ES_make_tcp_ack_with_data(buf,plen); // manda i dati
}
}
}
}
// I valori di ritorno sono contenuti nella variabile globale 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){
// Copia il valore su un buffer e lo termino con '\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,"cmd")){
if (*strbuf < 0x3a && *strbuf > 0x2f){
// è un numero ASCII, lo restituisco
r=(*strbuf-0x30);
}
}
return r;
}
uint16_t print_webpage(uint8_t *buf, byte on_off)
{
int i=0;
uint16_t plen;
plen=es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n"));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<center><p><h1>Welcome to Arduino Ethernet Shield V1.0 </h1></p> "));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<hr>
<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> REMOTE LED is </h2> "));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<h1><font color=\"#00FF00\"> "));
if(on_off)
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("ON"));
else
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("OFF"));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR(" </font></h1>
") );
if(on_off){
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=hidden name=cmd value=3>"));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=submit value=\"Switch off\"></form>"));
}
else {
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=hidden name=cmd value=2>"));
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("<input type=submit value=\"Switch on\"></form>"));
}
plen=es.ES_fill_tcp_data_p(buf,plen,PSTR("</center><hr> <p> V1.0 <a href=\"http://www.nuelectronics.com\">www.nuelectronics.com<a>"));
return(plen);
}
quello che vi chiedo è magari di dirmi quale parte dovrei copiare e incollare ( se è così che si deve fare ) per poi cambiare qualche parametro, oppure se devo aggiungere da zero alcune cose, o ancora se la mia modifica implica anche la modifica di alcuni parametri ( per esempio, di default il pulsante me lo ritrovo al centro della pagina…se ne voglio aggiungere un altro, ne metterò uno accanto all’altro quindi credo che i parametri per la “disposizione” del vecchio pulsante andranno cambiati ), ecc.
mi interessa capire il metodo insomma per aggiungere pulsanti, come posizionarli e come agganciarli alle uscite di arduino…vi ringrazio in anticipo.
il collegamento hardware è così disposto: PC - Router - ethernet shield - arduino - led
l’ide usato è lo 0.21 ( per motivi di compatibilità con questa shield ) e il sistema operativo è WIN7 ultimate 64bit