problemi con shield ethernet

Salve a tutti.
E' la prima volta che mi approccio alla connessione ad internet di Arduino. Ho subito avuto non pochi problemi. Cercando in internet ho trovato molti tutorial e molti post su forum vari ma molto discordanti. Ad esempio ho trovato scritto in molti post che l'indirizzo MAC dovrebbe essere scritto in un adesivo sulla shield (cosa che tornerebbe con il fatto che l'indirizzo MAC deve essere dato dal produttore) mentre, in altri post, si dice che basta inserire un indirizzo MAC casuale, l'importante e' che non sia un indirizzo gia' presente nella nostra rete. Il problema e' che nella mia shield non era presente nessun adesivo con indirizzo MAC. Per questo motivo ho provato ad "inventare" un MAC address. Con il codice che segue il problema e' il seguente: nell'uscita seriale mi stampa connesso e subito dopo disconnesso. Il problema e' che anche mettendo un DNS inesistente il risultato rimane sempre il solito, come se entrasse dentro l'if indipendentemente dalla condizione e stampasse solamente l'uot seriale senza stampare il resto.

#include <SPI.h>
#include <Dhcp.h>
#include <Dns.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <EthernetServer.h>
#include <EthernetUdp.h>


byte mac[]={0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
char server[]="www.google.it";

EthernetClient client;


void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac);

  if(client.connect(server, 80))
  {
    Serial.println("Connessione avvenuta");
    client.println("GET/HTTP/1.1");
    client.println("Host:www.google.it");
    client.println("Connection: close");
    client.println();
  }
  else Serial.println("connessione fallita");
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
  if(!client.connected())
  {
    Serial.println("disconnesso");
    client.stop();
    while (true);
  }
  if(client.available())
  {
    char c=client.read();
    Serial.print(c);
  }
  else Serial.println("non ci sono caratteri disponibili da leggere");
}

Avete qualche consiglio da darmi o un link di una discussione o di un sito dove posso trovare una soluzione?
Grazie in anticipo.

Beh se il problema è il MAC address, puoi intanto usare il MAC address che in genere si mette per sviluppare su queste schedine cinesi, ossia "0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED" (che letto per gruppi diventa DEAD BEEF FEED ossia "cibo di carne morta", spiritosi sti sviluppatori eh?).

Oppure, meglio, ne generi uno "plausibile" con un generatore di MAC address come QUESTO (ma se googli ne trovi svariati) perché se hai più device con Arduino rischi di avere conflitti di MAC.

Una volta fatto questo, il problema è come gestisci tu la cosa e soprattutto spiegaci bene COSA vorresti che il programma debba fare! Immagino connettersi a Google e fare un GET della home page, ma quindi per prima cosa qui non ti colleghi di fatto a nulla perché non può risolvere il nome "www.google.it" con un IP non avendo impostato alcun DNS. Poi hai incluso una marea di librerie che di fatto non usi, dal DNS a Dhcp, EthernetServer, EthernetUdp....

Inizia con le cose semplici, metti l'indirizzo IP di www.google.it (es. "216.58.198.3") al posto del nome. Poi sistema quel loop per evitare di scrivere cose quando non ricevi dati.
Insomma, caricati l'esempio WebCLient della libreria Ethernet e inizia da lì adattandolo per fare una prima prova.
Ad esempio:

#include <SPI.h>
#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress server(216,58,198,3);  // numeric IP for Google (no DNS)
EthernetClient client;

void setup() {
  // You can use Ethernet.init(pin) to configure the CS pin
  Ethernet.init(10);  // Most Arduino shields
  Serial.begin(9600);
  
  Serial.println("Initialize Ethernet with DHCP:");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    while (true) {
	  delay(1); // do nothing, no point running without Ethernet hardware
    }
  } else {
    Serial.print("  DHCP assigned IP ");
    Serial.println(Ethernet.localIP());
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.print("connecting to ");
  Serial.print(server);
  Serial.println("...");

  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.print("connected to ");
    Serial.println(client.remoteIP());
    // Make a HTTP request:
    client.println("GET /search?q=arduino HTTP/1.1");
    client.println("Host: www.google.it");
    client.println("Connection: close");
    client.println();
  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop() {

  // if there are incoming bytes available
  // from the server, read them and print them:
  if(client.available())
  {
    char c=client.read();
    Serial.print(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    while (true) {
      delay(1);
    }
  }
}

In seguito potrai aggiungere l'uso del DNS e quant'altro. Ma sempre UN passo alla volta.

Grazie mille della risposta.
Si l'idea era proprio quella di partire un passo alla volta. Alla fine vorrei poter leggere un db per fare determinate cose al variare dei parametri nel db pero' volevo partire con un semplice GET. Si mi sono accorto delle librerie in piu' ma sono quelle che inserisce l'IDE di default quando gli dico di inserire le librerie ethernet.
Grazie per i consigli e per l'esempio. A proposito di quest'ultimo avrei alcune domande. Per iniziare un po a "studiarlo" l'ho copiato ed incollato nell'IDE ma provando a compilarlo mi da errore in questi due punti:

  • Ethernet.init(10);
  • Serial.println(client.remoteIP());

l'erroe rimane sempre il solito:
Arduino:1.8.5 (Windows 8.1), Scheda:"Arduino/Genuino Uno"

sketch_ethernet_v2.0:32: error: 'class EthernetClient' has no member named 'remoteIP'

Serial.println(client.remoteIP());

^

come posso fare per risolvere la cosa?
Grazie di nuovo per la risposta.

Quando inserisco libreria Ethernet ottengo
#include <Ethernet.h>
e basta. Versione IDE 1.8.8 (ma sono sicuro che anche la 1.8.5 fa così)
Quindi... che libreria stai usando ? Che shield hai ? Quella ufficiale ? Che monta il Wiz5100 oppure usi una clone con altre librerie ?

Grazie di nuovo delle risposte.
Nella 1.8.5 mi aveva aggiunto tutte quelle librie.
Sto usando una shield clone trovate in un kit. Una domanda molto stupida: a seconda della shield possono variare le librie? Scusatemi per le domande molto banali.

rockykinotto:
Una domanda molto stupida: a seconda della shield possono variare le librie?

Si, in funzione del chipset che montano, cambia la libreria (... hardware diverso ... software diverso :smiley:).

Guglielmo

Giusto non fa una piega :smiley:
da Quello che riesco a vedere il chipset e' il W5100.
Come posso procedere? va bene la libria che aggiunge l"IDE o cen'e' una specifica?

Il W5100 è lo stesso del vecchio shield Ethernet di Arduino, quindi dovrebbe andare bene la classica libreria Ethernet che installa 'IDE (... attenzione a non confondere con la Ethernet2 che è per il W5500).

Guglielmo

ok Grazie mille.
Pero' a regola non avrebbe dovuto darmi gli errori di compilazione che ho elencato prima giusto?

NON ho esaminato bene il tuo codice ...
... perché non provi l'esempio che veine fornito apposta per il metodo remoteIP() nel reference della libreria e vedi se ti da ugualmente errore?

Guglielmo

rockykinotto:
Arduino:1.8.5 (Windows 8.1), Scheda:"Arduino/Genuino Uno"

sketch_ethernet_v2.0:32: error: 'class EthernetClient' has no member named 'remoteIP'

Serial.println(client.remoteIP());

^

Per me hai qualche casino con le librerie o ti manca qualche aggiornamento perché il metodo "remoteIP()" è presente nella Ethernet da qualche tempo...

Se comunque nel frattempo che verifichi le librerie (cosa che consiglio caldamente altrimenti se non hai il controllo delle versioni rischi di peggiorare i problemi man mano che avanzi con il progetto) e vuoi andare avanti, commenta quella riga (tanto è solo una informazione addizionale mostrata sulla seriale) e vedi se funziona.