Configurazione scheda ethernet

Buonasera a tutti, oggi mi è arrivata la scheda ethernet w5100 ma non riesco proprio a farla funzionare.

Essendo MEGA compatibile l’ho inserita sopra all’arduino, attaccato la rete e provato come prima cosa a caricare lo sketch di esempio DhcpAddressPrinter.

Purtroppo non mi dà nessun risultato, il monitor seriale resta vuoto. La scheda è collegata ad uno switch collegato direttamente al router.

Vi allego il codice che ho caricato. Grazie mille per l’aiuto.

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

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {  
  0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };

// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
  // this check is only needed on the Leonardo:

    ; // wait for serial port to connect. Needed for Leonardo only
  

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    for(;;)
      ;
  }
  // print your local IP address:
  Serial.print("My IP address: ");
  for (byte thisByte = 0; thisByte < 4; thisByte++) {
    // print the value of each byte of the IP address:
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print("."); 
  }
  Serial.println();
}

void loop() {

}

Nella setup() per prima cosa aggiungi un delay di 1 secondo e una frase:

void setup() {
  delay(1000);
  Serial.begin(9600);   // Open serial communications and wait for port to open:
  Serial.println("inizio");

Inoltre quella riga con ; e commento non serve a nulla. Ora qualcosa dovrebbe mostrare. Se non mostra "Failed to configure Ethernet using DHCP" dovrebbe arrivare a stamparti l'IP

Rieccomi qui, sono diventato scemo, un colpo mi è andata, dopo qualche minuto non andava già più.. Ho rismontato la scheda per l'ennesima volta e ha ripreso ad andare, magari era un falso contatto..

Restando in tema di scheda ethernet, sto scrivendo il programma nel quale vorrei inviare dei dati a processing intervallati da ";" in modo da splittarla successivamente.

Come posso fare ad inviare una temperatura con due decimali (float) rilevata da un sensore DS18B20? Ho guardato nel String Object Constructors e ho visto che effettivamente non posso inviare float, cosa potrei fare? Convertirlo?

Grazie per l'aiuto!

Non ho capito bene la domanda. Un sensore ti da la temperatura come numero mica come String object.
Non capisco perchè passare da String. Possibilmente evitala, spreca memoria e può portare ad esaurirla senza che te ne accorgi.
Usa le stringhe del C ovvero vettori/array di caratteri terminati da null (carattere ‘\0’) se devi convertirlo.
Ma mi pare che la Serial.print() accetta un float. Logicamente verrà spedito come testo (come tutti valori i numeri) che poi da Processing dovrai convertire.

float temp=0;
...
Serial.print(temp);
Serial.print(';');

Innanzitutto grazie per l’aiuto… Scusa per le domande ma come puoi immaginare è da poco che mi sono avvicinato alla programmazione e le mie lacune sono più che evidenti.

Sì hai ragione, io la temperatura la ho come float, all’inizio ho fatto tutte le prove arduino/processing usando il l’istruzione Serial.print e tutto funziona correttamente, invio di temperature, ricezione di setpoint ecc…

Adesso vorrei provare a comunicare tramite ethernet, ed ho visto che questo tipo di comunicazione prevede:

Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); e infine Udp.print Udp.endPacket();

Volevo creare una stringa unica da mandare via ma se mi dici che non vale la pena anche dal punto di vista della memoria allora evito. Giusto per capire, ma il comando Udp.print lo uso esattamente come il Serial.print?

Per esempio nel programma di prima il codice per inviare a processing era questo:

Serial.print(temperaturaSala);
  Serial.print(";");
  Serial.print(SPSala);
  Serial.print(";");
  Serial.print(isteresiSala);
  Serial.print(";");
  Serial.print(abilRiscSala);
  Serial.print(";");

Adesso basta che lo mando uguale mettendo Udp anzichè Serial?

bubba21: Giusto per capire, ma il comando Udp.print lo uso esattamente come il Serial.print?

Questo non lo so. La Serial è una classe che è figlia di Stream che a sua volta è figlia di Print ed eredita da essa tutte le varie forme di print() Dipende se Udp anche lei discende da questa bella famigliola :D

EDIT: sembra di si, nella Udp.h vedo questo:

class UDP : public Stream {

Vuol dire che UDP eredita le varie print()

Ok, ho iniziato a fare delle prove non riuscendo a leggere i dati che arduino manda.

Ho fatto una prova al volo:

ARDUINO

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h> // Arduino 1.0 UDP library
#include <OneWire.h>
#include <DallasTemperature.h>


byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x0A }; // mac address
IPAddress ip(192, 168, 1, 17); // indirizzo IP dal mio router netgear
unsigned int localPort = 8888; // porta locale in ascolto

EthernetUDP Udp; // istanza UDP che permette di inviare e ricevere dati


void setup()
{
  //Ethernet.begin(mac, ip, gateway, subnet); // inizializza Ethernet and UDP SE LASCIO COSI' NON FUNZIONA, TOGLI GATEWAY E SUBNET
  Ethernet.begin(mac, ip); // inizializza Ethernet and UDP:
  Udp.begin(localPort);   // inizializza UDP:

  
} // fine setup



void loop() {
  
   Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //inizializza per la risposta
   
   Udp.print("CIAO");
Udp.print(";");
Udp.endPacket();
    
  delay (1000);
  
}

PROCESSING

import hypermedia.net.*;               // libreria per udp
UDP udp;                               // defisce l'oggetto udp

 String ip       = "192.168.1.17"; // the remote IP address
 int port        = 8888;        // the destination port
 
 String RispostaArduino;
 
 
 
 void setup() {
  
  udp = new UDP( this, 6000 );  // create a new datagram connection on port 
  udp.listen( true );           // and wait for incoming message  
  
 }
 
 
 
 void receive( byte[] data, String ip, int port)   {       

RispostaArduino = new String( data );

if (RispostaArduino.equals("") == true ) { println("Nessuna risposta");
} else { 
println(RispostaArduino); }

 }

Errori non ne ho, semplicemente non mi scrive nulla, non ho neanche un “Nessuna risposta”. Dove può essere il problema?

Beh, da una parte apri la porta 8888 e dall'altra 6000, mi sembra.

Ho provato a settare 8888 anzichè 6000 ma niente..

Ma in questa parte di codice, quando invio i dati da arduino,

Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //inizializza per la risposta

sbaglio o non setto da nessuna parte l'ip e la porta del remoto?

Lo hai detto nel setup() con questo: Udp.begin(localPort); Purtroppo non conosco Udp(). Non ho mai provato. Ti rispondo in base a quel che vedo come programmatore. Sorry.

Però... quelle porte le hai APERTE sul router? Se il router ha un suo firewall, se la porta non la apri, la comunicazione su quella porta viene bloccata.

Secondo, dove hai trovato esempio UDP per Processing ? In quel IDE non ho mai provato Udp(). Hai trovato da qualche parte un "demo" o tutorial ? EDIT: questo? http://ubaa.net/shared/processing/udp/udp_class_udp.htm

Grazie ancora per l'aiuto che mi stai dando!

Sì le ho aperte direttamente nel router. Il codice di processing e arduino lo ho preso inizialmente da un progetto di un ragazzo qui sul forum e ho provato ad adeguarlo, fino ad adesso senza riuscirci :)

A parte gli scherzi, avevo trovato anche qui sul sito questo tutorial ( http://arduino.cc/en/Tutorial/UDPSendReceiveString#.Uy7a1YURcTk ) dove è presente la parte di processing per la ricezione da arduino e viceversa.

Ti ringrazio per il link, adesso provo a capirci fuori qualcosa :)

Cercando in internet per UDP ed Arduino ho leggiucchiato che in librerie UDP fornite con IDE precedente a 1.0.2 c'erano dei bachi. Che versione IDE Arduino usi?

Ah cavolo.. Ho appena controllato, la 1.0.5 -r2

Beh allora non dovrebbero esserci problemi.

credo che processing deve chiedere per avere risposta tipo: processing chiede : udp.send( "b", ip, 8888);

arduino: risponde

come nell'esempio UdpSendRiceiveString

controlla le porte non so se è giusta processing inserisci questo :

void draw(){
   udp.send( "b", ip, 8888 ); 
   delay (1000);
 }

in arduino integra con questo:

String ss;
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
void loop() {
   Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
   int packetSize = Udp.parsePacket();
     ss = packetBuffer;
 Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); //inizializza per la risposta
 if (ss == "b"){  
   Udp.print("ciao");
Udp.print(";");
Udp.endPacket();
    delay (1000);
 } 
}

una cosa del genere prova

Ah cavolo, quindi arduino risponde solo quando ha un pacchetto in arrivo.

Effetivamento mi è bastato aggiungere nel loop

  int packetSize = Udp.parsePacket();
  if(packetSize)

per avere la risposta, modificando Udp.print in Udp.write.

Nel mio caso specifico, io voglio che arduino continui ad inviare i dati a processing perchè devo aggiornare continuamente la lettura delle temperature, qual è secondo voi il metodo migliore per fare ciò?

Camperos, ci siamo sovrapposti, grazie per i consigli, adesso ci studio su un attimo.

Grazie a tutti per l'aiuto, siete mitici! :)

Ok ci siamo, funzionare funziona, c’è solo un “piccolo” problema… Quando avvio processing e provo a ricevere i dati, una volta fatto questo è come se la linea si saturasse e non riesco più a navigare in rete, scollego il cavo di rete dall’arduino e si rimette tutto ad andare… :cold_sweat:

hai messo 1 secondo di delay tra una richiesta e l'altra ? comunque usa i "millis" al posto del delay.

se non lo hai ancora fatto prova con una porta diversa