Go Down

Topic: Arduino uno + Ethernetshield über browser nicht erreichbar (Read 1 time) previous topic - next topic

Tiegger

Hallo miteinander,
Ich möchte gerne über den Arduino uno einen webserver laufen lassen und später über internet die einzelnen Pins steuern können. Zunächst soll das ganze allerdings nicht ins Internet, da ich noch die HTML-Seite bearbeiten möchte. Ich habe mich an diesem Tutorial orientiert: http://www.komputer.de/wordpress/archives/497 und bisher alles genau so durchgeführt. Nach dem upload des Programmcodes auf das Board ist dieses allerdings nich über den browser zu erreichen. Ich habe jetzt schon stundenlang das Netz durchsucht, aber an dieser Stelle scheint überaschenderweise kaum jemand ein Problem zu haben. Merkwürdig daran ist auch, dass wir in der Uni das ganze über den Router eines Studienkollegen im Browser schon mal erreichen konnten. Hier bei mir zuhause geht dies jetzt jedoch nicht mehr. Bei mir ist zwar noch ein Access Point als Repeater dazwischen aber der sollte das ja eigentlich nicht beeinflussen.
Ich hoffe es kann mir hier einer helfen.

mkl0815

Poste doch mal den Sketch. Passt denn die eingestellte IP zu Deinem Netz? Kannst Du die IP anpingen? Auf Ping reagiert schon der Ethernet-Chip (Falls es der Wiznet 5100 ist), unabhängig ob Dein Programm funktioniert. Allerdings auch nur, wenn es zumindest soweit gekommen ist, die IP zu setzen.
Ansonsten ist es sicher besser zum Testen erstmal eine "direkte" Verbindung zu wählen, also beide Geräte (Arduino und Computer) am gleichen Hub oder Switch. Somit kannst Du die Netzwerkstrecke als Fehlerquelle erstmal ausschliessen.

Grüße,
Mario.

Tiegger

Danke erstmal für die Antwort.
Das Modul ist das ENC28J60 Breakout. Ich habe PC und Ethernet Shield schon die ganze Zeit über in ein und dem selben Switch und auch auf ping reagiert das modul nicht, allerdings steht die IP die ich anpinge auch im code drin. Ich weis auch nicht genau wie ich den router einstellen muss. Ob das Modul mit DHCP klar kommt oder nicht. Ohne DHCP kommt man aber ohne DNS-Server IP nicht ins Netzwerk bei uns und ich wüsste nicht wie ich dem Arduino die geben kann. Hier noch der Programmcode den ich verwende. Das ist der den ich aus dem Tutorial entnommen habe. Mit dem hat es ja auch schon funktioniert.

Code: [Select]
#include "etherShield.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};
static uint8_t myip[4] = {192,168,178,55};
static char baseurl[]="http://192.168.178.55/";
static uint16_t mywwwport =80; // listen port for tcp/www (max range 1-254)
// or on a different port:
//static char baseurl[]="http://10.0.0.24:88/";
//static uint16_t mywwwport =88; // 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);
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);


}

void loop(){
  uint16_t plen, dat_p;
  int8_t cmd;

  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){
          // 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\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);
            goto SENDTCP;
         }
        cmd=analyse_cmd((char *)&(buf[dat_p+5]));
        if (cmd==1){
             plen=print_webpage(buf);
        }
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,"cmd")){
                if (*strbuf < 0x3a && *strbuf > 0x2f){
                        // is a ASCII number, return it
                        r=(*strbuf-0x30);
                }
        }
        return r;
}


uint16_t print_webpage(uint8_t *buf)
{
        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><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>  V1.0 <a href=\"http://www.nuelectronics.com\">www.nuelectronics.com<a>"));
 
        return(plen);
}

mkl0815

Quote
Das Modul ist das ENC28J60 Breakout.

Hmm, schwierig. Beim WizNet 5100 ist der TCP/IP Stack in der Hardware implementiert, was das Handling deutlich einfacher macht. Beim ENC28J6 muss das glaub ich die Software machen. Die Lib kenne ich gar nicht, da müßte ich erstmal schauen. Falls die Software nicht auf ICMP (ping) Pakete reagiert, wirst Du auf ein Ping auch keine Antwort bekommen. 
Der folgende Code deutet aber darauf hin, das auf einen ICMP ECHO REQUEST eine Antwort geschickt wird:
Code: [Select]
    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;
    }


Dein Arduino hat zumindest schon mal die 192.168.178.55 als IP. Leider ist nirgendwo eine Netzmaske angegeben, daher vermute ich mal, das es eine 255.255.255.0 ist. Hat denn Dein PC aus dem gleichen Netz eine IP, also 192.168.178.0/24 (.1 bis .254 am Ende)? Falls nicht, kann er Dein Board ohne Routing nicht sehen. Der Code im Sketch interessiert sich eh nur für die IP im Paket, sowas wie Routing hab ich da nicht gesehen, es wird einfach an die absendende MAC Adresse (sollte dan die Deines PCs sein) die Antwort geschickt. Dein PC muss also zwingend im gleichen Netz sein wie der Arduino. So blöd es klingt, aber wer sich nicht tiefer mit der TCP/IP Materie auseinandersetzen will, sollte auf ein EthernetShield mit WizNet5100 setzen, oder eine Lib verwenden, die das besser kapselt.

Mario.

nachtaktiv68

Hallo,

das ist mein erster post in diesem Forum :)

Ich habe nahezu die gleiche Konfiguration laufen. Angefangen habe ich mit einem Arduino Nano 3.0 und dem ENC28J60 Modul. Das hatte, mit der gleichen Library und dem gleichen Code wie Du ihn benutzt funktioniert. Dann habe ich - weil mir Arbeitsspeicher und Pins ausgegangen sind - umgerüstet auf einen Mega2560, und übers Netz ging nichts mehr. Nach langer Sucherei habe ich dann festgestellt, dass das Modul gar nicht richtig initialisiert werden konnte und mein Sketch sich in der Setup-Routine schon aufgehängt hat. Schließlich hat sich herausgestellt, dass das Modul beim Mega an anderen Pins anzuschließen ist als beim Nano. Dann ging es aber immer noch nicht, obwohl ich die Pins auch in der Library geändert hatte. Irgendwann bin ich dann im Netz auf eine Bibliothek gestoßen, mit der es funktionierte. So ganz verstehe ich das nicht :)

Was Dein Problem betrifft:

Ich würde mal zum debuggen hinter jede Anweisung in der Setup-Routine sowas einfügen wie

es.ES_enc28j60Init(mymac);
Serial.println("ES_enc28j60Init ok"); <---
...

Und dann in dem seriellen Ausgabefenster schauen, wie weit Dein Sketch kommt. Wenn der Sketch nämlich schon im Setup hängenbleibt, kann er mit einem Browser nicht erreichbar sein.

Dann würde ich mal die Verkabelung ganz genau überprüfen; ich bin (beim Nano) danach vorgegangen, weil ich das Ding dort gekauft habe :)

http://www.komputer.de/wordpress/archives/497

Wobei die beiden Dioden überflüssig sind, ich habe es jetzt einfach an 5V angeschlossen und es läuft. INT brauche ich auch nicht.

Hast Du eigentlich andere Geräte im Netz die Du anpingen kannst? Nur um zu wissen, dass Dein Netz richtig funktioniert?

Die Firewall könntest Du zum Test auch mal deaktivieren.

Hmm jetzt fällt mir nichts mehr ein.

Blinken die LEDs am Breakout eigentlich?

Viel Erfolg, und berichte :)

Gruß Thomas
twitter: @darktom

Go Up