Arduino ethernet problema con sd

Salve a tutti, ho acquistato da poco una arduino ethernet rev3 con la quale mi sto assai divertendo XD
Sono incorso però in un problema ossia ho sviluppato un webserver tramite la libreria webduino per farmi dare al momento la temperatura dall'apposito sensore e comandare un led, il tutto o tramite browser oppure tramite un'app android appositamente sviluppata da me per l'occasione. Il problema è che ora vorrei usare la microsd per salvarmi magari una sorta di log o in futuro leggere dei dati da essa, ma non riesco assolutamente a scrivere su microsd. Ho provato uno sketch di esempio ed effettivamente quello funziona ma a quanto pare ci sono problemi se nello stesso sketch utilizzo la ethernet. Come posso fare per "switchare" tra la sd e la ethernet?
Qualcuno di voi ha avuto questo problema?
Grazie

Presta attenzione al segnale di select dello spi.

Non so che versione arduino usi, ma so che in alcune versioni a seguito del comando begin che inizializza la rete viene lasciato il select della ethernet a livello basso(ovvero attivo), e non si riesce a comunicare con la SD.

Quindi se fosse questo problema, dopo l'istruzione di inizializzazione della rete (begin) fai un digitalWrite(10,HIGH) per disattivare il chip di rete, dopodichè la libreria della sd quando opportuno selezionerà tramite apposito pin (4) il CS della tua scheda.

Grande, ci siamo quasi!
La versione dell'sdk che leggo nel compilatore è la 1.0.3, non so se ti riferisci a quella.
Allora ho fatto come hai detto tu, nel setup ho impostato il seguente codice

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(10, OUTPUT);
  Ethernet.begin(mac, ip);
  digitalWrite(10, HIGH);
  if (!SD.begin(4)) {
    sdAvailable = false;
  }
  ArduinoServer.addCommand("temp", &temp);
  ArduinoServer.addCommand("led", &led_command);
  ArduinoServer.addCommand("file", &file);
  ArduinoServer.begin();
  delay(100);
}

ora però quello che succede è che una volta scritto sul file la ethernet non risponde più ad altre richieste forse perchè "occupata" dalla sd. Come posso fare per "switchare" tra le 2 risorse?

Posta tutto il codice.
Solo da quel frammento non si capisce

Ok, questo è tutto lo sketch

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

#define TEMP_SENSOR A1
#define LED 8

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
byte ip[] = {192, 10, 1, 166};
//byte ip[] = {10, 0, 0, 166};
WebServer ArduinoServer("", 1567);
File logFile;
String logFileName = "reslog.txt";
boolean sdAvailable = true;

void temp (WebServer &server, WebServer::ConnectionType type,
            char *param, bool param_complete) {
  if (type != WebServer::HEAD) {
    server.httpSuccess();
    if (param_complete == true) {
      float temp = convertTemp(analogRead(TEMP_SENSOR));
      char tempString[10];
      dtostrf(temp, 1, 2, tempString);
      char json[50];
      sprintf(json, "{temp: %s}", tempString);
      char logContent[50];
      sprintf(logContent, "Temperatura ritornata: %s", tempString);
      server.print(json);
      saveToFile(logContent);
    }
  } else {
    server.httpFail();
  }
}

void led_command(WebServer &server, WebServer::ConnectionType type,
                char *param, bool param_complete) {
  if (type != WebServer::HEAD) {
    server.httpSuccess();
    String s = "";
    if (param_complete == true) {
      s = param;
      if (s == "on") {
        digitalWrite(LED, HIGH);
        if (digitalRead(LED) == HIGH) {
          server.print("{led: on_success}");
        } else {
          server.print("{led: on_fail}");
        }
      } else if (s == "off") {
        digitalWrite(LED, LOW);
        if (digitalRead(LED) == LOW) {
          server.print("{led: off_success}");
        } else {
          server.print("{led: off_fail}");
        }
      } else if (s == "status") {
        if (digitalRead(LED) == HIGH) {
          server.print("{led: on}");
        } else {
          server.print("{led: off}");
        }
      } else {
        server.httpFail();
      }
    }
  } else {
    server.httpFail();
  }
}

void file(WebServer &server, WebServer::ConnectionType type,
            char *param, bool param_complete) {
  if (type != WebServer::HEAD) {
    server.httpSuccess();
    if (sdAvailable) {
      logFile = SD.open("reslog.txt");
      if (logFile) {
        while (logFile.available()) {
          server.print(logFile.read());
        }
        logFile.close();
      } else {
        server.println("Non sono riuscito ad aprire il file");
      }
    } else {
      server.println("Scheda SD non disponibile");
    }
  } else {
    server.httpFail();
  }
}

float convertTemp(float temp) {
  return (temp * 5.0 * 100.0) / 1024.0;
}

void saveToFile(char data[]) {
  File fileLog = SD.open("request.log", FILE_WRITE);
  if (fileLog) {
    fileLog.println(data);
    fileLog.close();
  }
}

void activateLan() {
  Ethernet.begin(mac, ip);
  digitalWrite(10, HIGH);
}

void activateSD() {
  if (!SD.begin(4)) {
    sdAvailable = false;
  }
}

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(10, OUTPUT);
  activateLan();
  activateSD();
  ArduinoServer.addCommand("temp", &temp);
  ArduinoServer.addCommand("led", &led_command);
  ArduinoServer.addCommand("file", &file);
  ArduinoServer.begin();
  delay(100);
}

void loop() {
  ArduinoServer.processConnection();
}

Quello che faccio al momento è richiamare da browser la funzione temp dove mi viene restituito un json e scrive una stringa nel file reslog.txt sulla sd (cosa che ora fa, prima creava solo il file che era vuoto), solo che successivamente arduino non risponde più alle richieste http

Non conosco la libreria webduino, io uso la tiny (che di tiny ha rimasto poco perchè me la sono rivista quasi tutta).

Ad occhio cosi non sembrerebbe esserci niente di strano, sei sicuro che accade esattamente cosa hai descritto?

Comunque aggiungi un delay nel loop, anche di pochi millisecondi,e aggiungerei un delay anche tra

server.print(json);
// delay here
saveToFile(logContent);

P.S. assicurati anche di aver impostato il Pin 4 come output e mettili entrambi a livello alto all'avvio.

Si dopo che scrive la prima volta anche facendo aggiorna non risponde più. Almeno ora però scrive su file prima lo creava solo.

Pro vero a mettere i delay come mi hai suggerito.

niki77:
P.S. assicurati anche di aver impostato il Pin 4 come output e mettili entrambi a livello alto all'avvio.

Scusa l'ignoranza, come dovrei fare?

djdedo:
Scusa l'ignoranza, come dovrei fare?

pinMpinMode(4, OUTPUT);
digitalWrite(4,HIGH);

su setup dove già lo fai per il pin 10

Ok appena ce l'ho di nuovo davanti provo così! Grazie mille!

Niente da fare, aggiungendo queste modifiche arduino manco mi risponde più via ethernet :frowning:
Ma come diavolo è che è così complicato fare sta cosa? Eppure non credo di chiedere troppo :frowning:

Nessuna idea? :frowning:
Nessun'altro ha avuto questo problema?

Io uso regolarmente insieme ethernet e sd e non ho alcun problema.
Per il server ethernet uso la libreria tinywebserver, e per la sd quella compresa con Arduino.
Magari la libreria che usi tu ha qualche problema,hai provato a vedere se hai l'ultima versione?

Stavo pensando anch'io alla libreria. Credo di avere l'ultima versione ma posso tranquillamente cambiare e provare con quella che usi tu. Alla fine basta che funziona

I problemi della sd non sono sempre derivati dal software, ma anche dalla SD stessa e dalla formattazione che hai fatto, ad esempio se prendi una sd pincopallino di un cellulare e la metti in arduino, molto probabile che dia problemi. (almeno per me è stato così, di tutte non ne andava una come si deve)
Il modello che preferisco in assoluto è la kingston, ormai le 2Gb non le trovi più, prendi una 8 o una 16gb e formattala in fat32 poi usa la lib SD.h che le legge e scrive benissimo
i pin che ti interessano sono il 10 e il 4, ma quello già te lo hanno scritto nei post precedenti.
Anche io la uso da un anno circa e funziona bene.

ciao

Ho acquistato una sandisk da 4gb appositamente e l'ho formattata in fat32. La libreria che uso per la sd è la sua e scrivendo uno sketch di prova funziona tutto regolarmente per questo i dubbi non sono andati sulla scheda sd.

Grazie mille, sembra sia proprio la libreria a creare problemi. Ho utilizzato la tiny e sembra funzionare tutto come dovrebbe.
L'unica cosa che ho notato però è che nel setup la TinyWebServer fa mettere queste istruzioni

  pinMode(SS_PIN, OUTPUT);
  digitalWrite(SS_PIN, HIGH);
  
  pinMode(ETHER_CS, OUTPUT);
  digitalWrite(ETHER_CS, HIGH);
  
  pinMode(SD_CS, OUTPUT);
  digitalWrite(SD_CS, HIGH);

dove ETHER_CS e SD_CS sono rispettivamente i pin della ethernet e della sd che ho valorizzato precedentemente, ma SS_PIN cos'è??? :astonished:

La libreria sd.h non da problemi.
Questo è la stessa cosa di quello che hai nella tiny è l'avevi in qualche post più in su

 pinMode(10, OUTPUT);
 pinMode(4, OUTPUT);
  Ethernet.begin(mac, ip);
  digitalWrite(10, HIGH);
  if (!SD.begin(4)) {
    sdAvailable = false;
  }

ma SS_PIN cos'è???

Note about Slave Select (SS) pin on AVR based boards

All AVR based boards have an SS pin that is useful when they act as a slave controlled by an external master. Since this library supports only master mode, this pin should be set always as OUTPUT otherwise the SPI interface could be put automatically into slave mode by hardware, rendering the library inoperative.

Salve, anch'io ho lo stesso problema, sto testando una scheda Arduino Ethernet Rev.3 con IDE 1.03 per OSX e adattatore USB2/serial di Arduino.

Se provo ad utilizzare le librerie separatamente tutto funziona correttamente, se invece provo a utilizzare la scheda SD e la rete ethernet nello stesso sketch il programma un funziona e si pianta: sulla porta seriale invece di avere l'output corretto (sostanzialmente delle Serial.println) ho una serie di caratteri spuri o contenuti parziali del file che sto leggendo.

Dalla documentazione ho visto che entrambi i dispositivi utilizzano il canale condiviso SPI e pertanto e' indispensabile che l'accesso a questa risorsa sia effettuato rigorosamente in modo esclusivo. Tutto ciò e' possibile tramite i pin digitali 10 (ethernet) e 4 (SD).
Collegando a questi pin due led ho potuto constatare che gli stati cambiamo in modo corretto rispetto a quanto scritto nel codice e che pertanto l'accesso al bus SPI dovrebbe essere giusto.

E' possibile che ci possa essere qualche problema legato alle librerie con la parte seriale della scheda?

Saluti

Giovanni

Benvenuto gvnsbt

Il tuo problema si riconosce molto bene in alcune mie esperienze personali con questo shield, ti posso garantire che la libreria ethernet e SD possono lavorare bene nello stesso sketch, il problema sta nella memoria dedicata alle variabili e ai buffer che è pochissima, i caratteri strani sono spesso provocati da una saturazione della memoria per poi arrivare a un crash. Nel tuo caso, dove non hai fornito ne uno sketch ne il modello di arduino che usi posso solo al 90% dirti che è un problema di ram.

ciao

Pablos, grazie per la risposta. Riguardo alla memoria quando compilo lo sketch ho 26kb su 32 disponibili, e quindi davo per scontato che ci fosse abbastanza spazio ma evidentemente non e' così :-(. Come si fa a capire quanta memoria viene riservata per le variabili, c'e' un modo per poter liberare la ram dalle variabili non piu' utilizzate?

La scheda che sto utilizzando e' una Arduino Ethernet REV. 3.
Visto che da pochi giorni mi sono "affacciato" al mondo Arduino, prima di postare il codice vorrei avere un'idea un po' piu' precisa di come funziona questo ambiente.

Saluti, e grazie ancora per la risposta.

Saluti

Giovanni