Arduino ethernet problema con sd

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

Riguardo alla memoria quando compilo lo sketch ho 26kb su 32 disponibili

Non parliamo della stessa memoria.

Arduino Uno:
Flash Memory 32 KB (ATmega328) 0.5 KB usato dal bootloader .... il resto viene usato per il tuo programma
SRAM 2 KB (ATmega328) .... spazio dedicato alle variabili int, byte, float, long .......
EEPROM 1 KB (ATmega328) ... memoria non volatile dove è l'utente che decide dove, quando e perchè scrivere

Anche io presento lo stesso problema, nel momento in cui cerco di scrivere su sd si pianta tutto, se commento il metodo che lancia la scrittura tutto funziona senza problemi.
Onestamente mi vien da pensare che il problema derivi in qualche modo dalle 2 librerie
allego il codice:

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] =  { 192,168,200,177 };

const int MAX_PAGENAME_LEN = 8; // max characters in page name 
char buffer[MAX_PAGENAME_LEN+1]; // additional character for terminating null

EthernetServer server(80);

const int chipSelect = 4;
File dataFile;

void setup()
{
  
  Serial.begin(9600);
  
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  
  Serial.print("\nInitializing SD card...");
 
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
  digitalWrite(chipSelect,HIGH);
  
  Ethernet.begin(mac, ip);
  server.begin();
  digitalWrite(10,HIGH);
  delay(2000);
}

void loop()
{
  EthernetClient client = server.available();
  if (client) 
  {
    int type = 0;
    while (client.connected()) 
     {
        if (client.available()) 
        {
        // GET, POST, or HEAD
         memset(buffer,0, sizeof(buffer)); // clear the buffer | scrive l'array con 0
         if(client.readBytesUntil('/',buffer,sizeof(buffer)))
         { 
          if(strcmp(buffer,"POST ") == 0)  //cerca la scritta post http://ruturajv.wordpress.com/2005/12/25/http-post-request/
          {
            client.find("\n\r"); // skip to the body
            // find string starting with "pin", stop on first blank line
            // the POST parameters expected in the form pinDx=Y
            // where x is the pin number and Y is 0 for LOW and 1 for HIGH
            while(client.findUntil("pinD", "\n\r")){
              int pin = client.parseInt();       // the pin number
              int val = client.parseInt();       // 0 or 1
              pinMode(pin, OUTPUT);
              digitalWrite(pin, val);
              digitalWrite(10,HIGH);
              scriviLog(pin,val);
              digitalWrite(10,LOW);
            }
          }
          sendHeader(client,"Domotica");
          //create HTML button to control pin 8
          client.println("<h2>Controllo Pin Digitali</h2>");
          client.println("<table border='1' >");
          for(int i=2;i<=3;i++)
           {
            client.print("<tr><td>digital pin ");
            client.print(i);
            client.print(" </td><td>");
            client.print("<form action='/' method='POST'><p><input type='hidden' name='pinD");
            client.print(i);
            client.print("'");
            client.println(" value='0'><input type='submit' value='Off'/></form>");
            client.print(" </td><td>");
            client.print("<form action='/' method='POST'><p><input type='hidden' name='pinD");
            client.print(i);
            client.print("'");
            client.print(" value='1'><input type='submit' value='On'/></form>");
            client.print(" </td><td>stato: ");
            if(digitalRead(i)==1)
               client.print("ON");
             else
               client.print("OFF");
            client.println("</td></tr>");
            }
          
          for(int i=5;i<10;i++)
           {
            client.print("<tr><td>digital pin ");
            client.print(i);
            client.print(" </td><td>");
            client.print("<form action='/' method='POST'><p><input type='hidden' name='pinD");
            client.print(i);
            client.print("'");
            client.println(" value='0'><input type='submit' value='Off'/></form>");
            client.print(" </td><td>");
            client.print("<form action='/' method='POST'><p><input type='hidden' name='pinD");
            client.print(i);
            client.print("'");
            client.print(" value='1'><input type='submit' value='On'/></form>");
            client.print(" </td><td>stato: ");
            if(digitalRead(i)==1)
               client.print("ON");
             else
               client.print("OFF");
            client.println("</td></tr>");
            }
          
          
          client.println("</table>");
          client.println("</body></html>");
          client.stop();
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    client.stop();
  }
}

void sendHeader(EthernetClient client, char *title)
{
  // send a standard http response header
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println();
  client.print("<html><head><title>");
  client.print(title);
  client.println("</title><body>");
}   


void scriviLog(int pin , int valore)
{
  
  digitalWrite(4,LOW);
  Serial.println("qua ci arrivo");
  dataFile = SD.open("LOG.txt", FILE_WRITE);
  Serial.println("anche qui");
  String dataString = "";
  // if the file is available, write to it:
  dataString="Scrittura del pin n° ";
  dataString+=pin;
  dataString+="al valore:";
  dataString+=valore;
  Serial.println("str creata");
    if (dataFile) 
    {
     Serial.println("inizio scrittura");
     dataFile.println(dataString);
     Serial.println("ho scritto");
     dataFile.close();
     Serial.print("Scrittura avvenuta con successo");
    }
    else 
    {
     Serial.println("error opening datalog.txt");
    }
   digitalWrite(4,HIGH);
   
}

perchè metti il pin 4 a low?
Non sei tu che devi gestire i pin 4 e 10 dello shield

come non è corretto
digitalWrite(10,HIGH);
scriviLog(pin,val);
digitalWrite(10,LOW);

guarda lo fa già libreria w5100.cpp

uint8_t W5100Class::write(uint16_t _addr, uint8_t _data)
{
  setSS();  
  SPI.transfer(0xF0);
  SPI.transfer(_addr >> 8);
  SPI.transfer(_addr & 0xFF);
  SPI.transfer(_data);
  resetSS();
  return 1;

uint8_t W5100Class::read(uint16_t _addr)
{
  setSS();  
  SPI.transfer(0x0F);
  SPI.transfer(_addr >> 8);
  SPI.transfer(_addr & 0xFF);
  uint8_t _data = SPI.transfer(0);
  resetSS();
  return _data;
}
}

dove setSS(); e resetSS(); è

private:
  inline static void initSS()    { DDRB  |=  _BV(4); };  //pin 10
  inline static void setSS()     { PORTB &= ~_BV(4); }; //pin 10
  inline static void resetSS()   { PORTB |=  _BV(4); }; //pin 10

Si lo so e hai ragione, ho copiato l'ultima versione del codice in cui avevo provato a mettere sia il pin 4 che il 10 a H/L per vedere se cambiava qualcosa, ma il risultato è sempre quello...la prima volta il led si accende ma poi il tutto rimane bloccato dentro la funzione scriviLog...

dovresti salvare il messaggio in una variabile e scrivere dopo il client.stop, attenzione se è troppo lunga la stringa puoi incorrere nuovamente a un crash

tra l'altro nel tuo sketch ce ne sono 2 di client.stop ......??

intanto ti ringrazio tantissimo per i preziosi consigli che mi stai dando :wink:
il client.stop doppio è proprio un errore, me lo sono portato dietro da quando ho diviso la creazione della tabella in 2 cicli e non in uno solo...insomma è un copia e incolla mal riuscito...tra un attimo sistemo il tutto e poi ti faccio sapere.
Grazie ancora

Confermo che tutto funziona perfettamente ora, ho rimosso il doppio client.stop() ed effetuato la scrittura a client chiuso.
Ti ringrazio ancora!
lascio qui il codice corretto per i posteri :slight_smile:

/*
 * WebServerPost sketch
 * Turns pin 8 on and off using HTML form
 */

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] =  { 192,168,200,177 };

const int MAX_PAGENAME_LEN = 8; // max characters in page name 
char buffer[MAX_PAGENAME_LEN+1]; // additional character for terminating null

EthernetServer server(80);

Sd2Card card;
SdVolume volume;
SdFile root;
String dataString;

const int chipSelect = 4;
File dataFile;

boolean scrivi=false;
int strPin,strValue;

void setup()
{
  
  Serial.begin(9600);
  
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  
  Serial.print("\nInitializing SD card...");

  
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");

  Ethernet.begin(mac, ip);
  server.begin();
  
  delay(2000);
}

void loop()
{
  EthernetClient client = server.available();
  if (client) 
  {
    int type = 0;
    while (client.connected()) 
     {
        if (client.available()) 
        {
        // GET, POST, or HEAD
         memset(buffer,0, sizeof(buffer)); // clear the buffer | scrive l'array con 0
         if(client.readBytesUntil('/',buffer,sizeof(buffer)))
         { 
          if(strcmp(buffer,"POST ") == 0)  //cerca la scritta post http://ruturajv.wordpress.com/2005/12/25/http-post-request/
          {
            client.find("\n\r"); // skip to the body
            // find string starting with "pin", stop on first blank line
            // the POST parameters expected in the form pinDx=Y
            // where x is the pin number and Y is 0 for LOW and 1 for HIGH
            while(client.findUntil("pinD", "\n\r")){
              int pin = client.parseInt();       // the pin number
              int val = client.parseInt();       // 0 or 1
              pinMode(pin, OUTPUT);
              digitalWrite(pin, val);
              strPin=pin;
              strValue=val;
              scrivi=true; 
            }
          }
          sendHeader(client,"Domotica");
          //create HTML button to control pin 8
          client.println("<h2>Controllo Pin Digitali</h2>");
          client.println("<table border='1' >");
          for(int i=2;i<=3;i++)
           {
            client.print("<tr><td>digital pin ");
            client.print(i);
            client.print(" </td><td>");
            client.print("<form action='/' method='POST'><p><input type='hidden' name='pinD");
            client.print(i);
            client.print("'");
            client.println(" value='0'><input type='submit' value='Off'/></form>");
            client.print(" </td><td>");
            client.print("<form action='/' method='POST'><p><input type='hidden' name='pinD");
            client.print(i);
            client.print("'");
            client.print(" value='1'><input type='submit' value='On'/></form>");
            client.print(" </td><td>stato: ");
            if(digitalRead(i)==1)
               client.print("ON");
             else
               client.print("OFF");
            client.println("</td></tr>");
            }
          
          for(int i=5;i<10;i++)
           {
            client.print("<tr><td>digital pin ");
            client.print(i);
            client.print(" </td><td>");
            client.print("<form action='/' method='POST'><p><input type='hidden' name='pinD");
            client.print(i);
            client.print("'");
            client.println(" value='0'><input type='submit' value='Off'/></form>");
            client.print(" </td><td>");
            client.print("<form action='/' method='POST'><p><input type='hidden' name='pinD");
            client.print(i);
            client.print("'");
            client.print(" value='1'><input type='submit' value='On'/></form>");
            client.print(" </td><td>stato: ");
            if(digitalRead(i)==1)
               client.print("ON");
             else
               client.print("OFF");
            client.println("</td></tr>");
            }
          
          
          client.println("</table>");
          client.println("</body></html>");
          client.stop();   
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    if(scrivi)
      {
      scriviLog();
      scrivi=false;
      }
  }
}

void sendHeader(EthernetClient client, char *title)
{
  // send a standard http response header
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println();
  client.print("<html><head><title>");
  client.print(title);
  client.println("</title><body>");
}   


void scriviLog()
{
  dataFile = SD.open("LOG2.txt", FILE_WRITE);
  dataString="";
  dataString = "è stato modificato lo stato del pin n° ";
  dataString+=strPin;
  dataString+=" ora vale: ";
  dataString+=strValue;
  // if the file is available, write to it:
  if (dataFile) 
    {
     dataFile.println(dataString);
     dataFile.close();
    }
    else 
    {
     Serial.println("error opening datalog.txt");
    }
}