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
Ma come diavolo è che è così complicato fare sta cosa? Eppure non credo di chiedere troppo
Nessuna idea?
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'è???
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
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
/*
* 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");
}
}