Arduino+ETH Shield e Google Spreadsheet

Buongiorno a tutti,
sono nuovo del forum e mi chiamo Francesco. Ho da poco tempo acquistato un Arduino UNO e un Ethernet Shield e ho già fatto vari programmini servendomi degli aiuti del forum e degli esempi sul sito.
Venendo al punto, vorrei sapere se come da titolo è possibile scrivere dati su google spreadsheet mediante l' invio di questi con ETH shield. Ho trovato il seguente topic, ma non sono riuscito a fare in modo di ottenere qualcosa di scritto sul foglio di calcolo. Qualcuno di voi ci è riuscito?
Grazie a tutti.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1241360897

codice pls :slight_smile:

Io ho semplicemente copiato il codice che ho trovato nel link postato sopra cambiando la KEY del documento.
Ecco qui:

/*
        * A simple sketch that uses Ethernet Shield to send some values (via POST) to GoogleDocs
        * Based on code by RobertMParker for the WiShield <http://asynclabs.com/forums/viewtopic.php?f=16&t=489>
 */

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

#define DEBUG_PRINT // comment to disable Serial.print

long unsigned int time =0;

//Wireless configuration parameters ----------------------------------------
byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = {
  192,168,0,3};   // IP address of Ethernet Shield
byte gateway[] = {
  192,168,0,1};   // router or gateway IP address
byte subnet[]    = {
  255,255,255,0}; // subnet mask for the local network

// IP Address for spreadsheets.google.com
byte ipGoogle[] = {
  74,125,67,102};
char hostname[] = "spreadsheets.google.com";
char url[] = "/formResponse?formkey=<ENTER_YOUR_KEY_HERE>";



// create a client that connects to Google
Client clientGoogle(ipGoogle,80);

void setup()
{  
  // Enable Serial output and ask WiServer to generate log messages (optional)
#ifdef DEBUG_PRINT
  Serial.begin(115200);
#endif //DEBUG_PRINT
  Ethernet.begin(mac, ip, gateway, subnet);

  // give the Ethernet shield a second to initialize
  delay(1000);
  int time = millis();
  clientGoogle.connect();
}


void loop()
{
  float temperature = (float) random(1000)/10.; // create some random values to test
  float humidity = 45 + (millis()%1000)/100.;
  if ( millis() > time + 10000 && clientGoogle.connected()){ // update sheet each 10 s
    String feedData = "entry.0.single=" + String((int)temperature) + "," + String(int(temperature*100)%100) + "&entry.1.single=" + String(int(humidity)) + "," + String(int(humidity*100)%100) + "&pageNumber=0&backupCache=&submit=Envoyer";
    //Serial.println(feedData);
    postRequest(clientGoogle, ipGoogle, 80, hostname, url, feedData);
    time = millis();
  }
  delay(10);
}

void postRequest(Client client, byte *ip, unsigned int port, char *hostName, char *url, String feedData){
  String buf = "POST " + String(url) + " HTTP/1.1";

#ifdef DEBUG_PRINT
  Serial.println(buf);
  Serial.println("Host: " + String(hostName));
  Serial.println("Content-Type: application/x-www-form-urlencoded");
  Serial.println("Content-Length: " + String(feedData.length()));
  Serial.println("");
  Serial.println(feedData);
  Serial.println("");
  Serial.println("");
#endif

  client.println(buf);
  client.println("Host: " + String(hostName));
  client.println("Content-Type: application/x-www-form-urlencoded");
  client.println("Content-Length: " + String(feedData.length()));
  client.println("");
  client.println(feedData);
  client.println("");
  client.println(""); // POST request as GET ends with 2 line breaks and carriage returns (\n\r);
}

Ogni 10 secondi dovrebbe uploadare dei numeri a caso ma questo non accade. Non so cosa c' è che non va.

ad occhio il codice sembra corretto, però ho fatto un ping

ping spreadsheets.google.com
PING spreadsheets.l.google.com (74.125.79.102) 56(84) bytes of data.

e l'ip è diverso da quello nello sketch...

e poi sei sicuro che il tuo gateway sia 192.168.0.1? prova a scriverlo nella barra del browser, dovrebbe risponderti il router... comunque puoi verificare questo indirizzo, apri un terminale (in windows cerca cmd.exe)
e scrivi "traceroute www.google.it" oppure "tracepath www.google.it", il primo IP che compare nella lista dovrebbe essere il tuo gateway

Ma su "byte ipGoogle[]" ci devo mettere l' ip che mi risulta pingando www.google.com oppure quello che mi risulta pingando spreadsheet.google.com? Ho provato con tutti e due ma comunque non mi funziona.
Se inserisco 192.168.0.1 mi risponde la finestra di login configurazione del router.

E..un' altra cosa..quando apro il mio foglio di calcolo sulla barra indirizzi trovo scritto:
https://spreadsheets.google.com/ccc?key=0ArTGw8....
e non
https://spreadsheets.google.com/formResponse?formkey=0ArTGw8....
centra qualcosa?

l'ip va quello spreadshett...
centra qualcosa, devi modificare l'algoritmo per usare ccc?blbla e non l'altro modo (evidentemente l'algoritmo è vecchio)

ed infine tu stai usando HTTPS, mentre l'algoritmo supporta solo HTTP...

Pensi dunque non ci sia maniera di andare a scr ivere sul foglio di calcolo con algoritmo https? =(

non lo so. in HTTPS tutte le comunicazioni sono criptate, bisogna vedere se arduino ha abbastanza potenza di calcolo per criptare i dati, oppure abbastanza memoria per criptare i dati o-line e poi spedirli una volta elaborati.

allora ho fatto qualche prova anch'io. Se non ti logghi in google, spreadsheet usa l'HTTP, però i dati restano salvato solo 24 ore, infatti se noti lo sketch che hai postato NON si autentica.

se vuoi implementare l'HTTPS, ecco tutto ciò che ti serve; la RFC: RFC 5246 - The Transport Layer Security (TLS) Protocol Version 1.2
per chi non lo sapesse le RFC sono i documenti tecnici che, se approvati, divengono standard di internet.
Ovviamente spiegano per filo e per segno come devono comportarsi i programmi per essere compatibili.
Per esempo lFTP, l'HTTP, e molti altri....

dopo di che puoi seguire questa guida:

che in pratica spiega il protocollo al di sopra dell'HTTPS ( e comunque credo che le api, ovvero le funzioni, siano le stesse per l'http)

Mi sa che HTTPS è un pò troppo per me.. :frowning: va bhe..grazie comunque per l' interesse e la spiegazione. C' è un tasto Thanks su questo forum?

no, ma ci vorrebbe in effetti :slight_smile:
comunque puoi usare l'http, però devi ricordarti di fare il backup dei dati ogni 24h e che il link al foglio cambia...

Volevo comunicare che sono riuscito a scrivere sul foglio di calcolo Google seguendo questa guida:

Probabilmente c' è ancora qualcosa da sistemare perchè dopo qualche inserimento l' ETH shield sembra come incepparsi e conclude la trasmissione. Questa cosa mi serviva per rilevare dei dati di temperatura e umidità per poterli poi rappresentare comodamente su un grafico inserito in un sito Google.

Anche io stò facendo la stessa cosa ma ho lo stesso tuo identico problema...dopo 5-6 scritture il sistema si ferma e non scrive più nelle label dello spreadsheet...come hai risolto Devon ???

Ho letto che l' Ethernet Shield (basato su WizNet5100) si blocca se usato con troppa insistenza.
Ho anche letto che c'e' un trucco per non farlo bloccare.

Cerca con la chiave "Wiznet 5100"

pietro78:
Anche io stò facendo la stessa cosa ma ho lo stesso tuo identico problema...dopo 5-6 scritture il sistema si ferma e non scrive più nelle label dello spreadsheet...come hai risolto Devon ???

Io ho usato il codice modificato in questo modo e così funziona.

/* Arduino to Google Docs
created 2011

This example code is in the public domain.

http://www.open-electronics.org

http://www.futurashop.it

Arduino data &ifq&entry.0.single=Boris&entry.2.single=Landoni&submit=Submit
Original from http://goodsite.cocolog-nifty.com/uessay/2010/07/arduinogoogle-d.html
Modified by John Missikos 11/6/11
Modified by Andrea Fainozzi 30/6/11
Modified by Boris Landoni 8/7/11

*/

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

char formkey[] = "dEtqRGhDa1pOTVJRLTlzNWw3U3htV0E6MQ"; //Replace with your Key
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; //Replace with your Ethernet shield MAC
byte ip[] = { 192,168,0,4}; //The Arduino device IP address
byte subnet[] = { 255,255,255,0};
byte gateway[] = { 192,168,0,1};
byte server[] = { 209,85,229,101 }; // Google IP
Client client(server, 80);
unsigned long time;
#define dataPin 2
#define clockPin 3
SHT1x sht1x(dataPin, clockPin);
float temp_c;
float humidity;
String data;

void setup()
{
Serial.begin(9600);
Ethernet.begin(mac, ip , gateway , subnet);
delay(1000);
Serial.println("connecting...");
}

void loop(){

if ( millis() > time + 10000){ // update sheet each 10 s
temp_c = sht1x.readTemperatureC(); //read temperature
humidity = sht1x.readHumidity(); //read humidity
data+="";
data+="entry.0.single=";
data+=(int) temp_c;
data+="&entry.1.single=";
data+=(int) humidity;
data+="&submit=Submit";

if (client.connect()) {
Serial.println("connected");

client.print("POST /formResponse?formkey=");
client.print(formkey);
client.println("&ifq HTTP/1.1");
client.println("Host: spreadsheets.google.com");
client.println("Content-Type: application/x-www-form-urlencoded");
client.println("Connection: close");
client.print("Content-Length: ");
client.println(data.length());
client.println();
client.print(data);
client.println();
//Show on serial monitor
Serial.print("POST /formResponse?formkey=");
Serial.print(formkey);
Serial.println("&ifq HTTP/1.1");
Serial.println("Host: spreadsheets.google.com");
Serial.println("Content-Type: application/x-www-form-urlencoded");
Serial.println("Connection: close");
Serial.print("Content-Length: ");
Serial.println(data.length());
Serial.println();
Serial.print(data);
Serial.println();
time = millis();
}
delay(10);
client.stop();
Serial.println("disconnected..");
}
delay(1000);
}

Che bello Devon, il tuo primo Topic XD, non ti sei un po' emozionato a rivederlo in UP?
A breve apro anch'io un Topic sul mondo Ethernet, abbene sì, è venuto il momento, ma io devo fare una cosa un po' particolare, tra qualche giorno ne riparliamo. :wink:

Ok il codice postato da Devon funzionicchia...a mio avviso c'è ancora qualche problema legato al server google spreadsheet che a volte "risponde male" e difatti al debug sulle serialPrint leggo dei caratteri strani...e comunque tutta la notte ha funzionato ...ho messo un time millis 1000,un secondo e mi ha mandato regolarmente tutti i dati...

Ora volevo chiedere se volessi aggiungere oltre ai due dati analogici di A0 e A1 anche un paio di DigitalRead di due Ingressi digitali come modifico lo sketch??
Premetto che ho provato così come segue ma nulla...o meglio mi stampa lo stato del pin in un'altra label dello spreadsheet ma modificandolo durante le letture non mi varia da 0 a 1 oppure da 1 a 0..ottengo sempre la stampa a 1 ...aggiungo che chiaramente ho inserito una 4,7 K di resistenza...
Grazie e buona giornata a tutti...allego lo sketch con le modifiche in rosso...ciao a tutti...


/* Arduino to Google Docs
created 2011

This example code is in the public domain.

Arduino data &ifq&entry.0.single=Boris&entry.2.single=Landoni&submit=Submit
Original from http://goodsite.cocolog-nifty.com/uessay/2010/07/arduinogoogle-d.html
Modified by John Missikos 11/6/11
Modified by Andrea Fainozzi 30/6/11
Modified by Boris Landoni 8/7/11

*/

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

char formkey[] = "dEtqRGhDa1pOTVJRLTlzNWw3U3htV0E6MQ"; //Replace with your Key
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; //Replace with your Ethernet shield MAC
byte ip[] = { 192,168,0,4}; //The Arduino device IP address
byte subnet[] = { 255,255,255,0};
byte gateway[] = { 192,168,0,1};
byte server[] = { 209,85,229,101 }; // Google IP
Client client(server, 80);
unsigned long time;
#define dataPin 2
#define clockPin 3
int statoPin = 5
SHT1x sht1x(dataPin, clockPin);
float temp_c;
float humidity;
String data;

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

pinMode(statoPin, INPUT);
Ethernet.begin(mac, ip , gateway , subnet);
delay(1000);
Serial.println("connecting...");
}

void loop(){

if ( millis() > time + 10000){ // update sheet each 10 s
temp_c = sht1x.readTemperatureC(); //read temperature
humidity = sht1x.readHumidity(); //read humidity
data+="";
data+="entry.0.single=";
data+=(int) temp_c;
data+="&entry.1.single=";
data+=(int) humidity;
data+="&entry.2.single=";
data+=digitalRead(statoPin);
data+="&submit=Submit";

if (client.connect()) {
Serial.println("connected");

client.print("POST /formResponse?formkey=");
client.print(formkey);
client.println("&ifq HTTP/1.1");
client.println("Host: spreadsheets.google.com");
client.println("Content-Type: application/x-www-form-urlencoded");
client.println("Connection: close");
client.print("Content-Length: ");
client.println(data.length());
client.println();
client.print(data);
client.println();
//Show on serial monitor
Serial.print("POST /formResponse?formkey=");
Serial.println(statoPin);
Serial.print(formkey);
Serial.println("&ifq HTTP/1.1");
Serial.println("Host: spreadsheets.google.com");
Serial.println("Content-Type: application/x-www-form-urlencoded");
Serial.println("Connection: close");
Serial.print("Content-Length: ");
Serial.println(data.length());
Serial.println();
Serial.print(data);
Serial.println();
time = millis();
}
delay(10);
client.stop();
Serial.println("disconnected..");
}
delay(1000);
}

prova con data+=(int)digitalRead(statoPin);

anche se dubito.. per me il problema è o il pin è usato dalla shield, o il circuito è errato

:stuck_out_tongue_closed_eyes: Effettivamente quando l' ho visto ho subito pensato..ma chi lo ha ripescato??

Siamo curiosi..staremo a vedere.
@Pietro78
Io a questo punto proverei ad allinearmi in questo modo. Dichiara una variabile int. (tipo int val=0;. Poi modifichi così il tuo programma.

 if ( millis() > time + 10000){ // update sheet each 10 s
    temp_c = sht1x.readTemperatureC();    //read temperature
    humidity = sht1x.readHumidity();      //read humidity
    val = digitalRead(statoPin);
    data+="";
    data+="entry.0.single=";
    data+=(int) temp_c;
    data+="&entry.1.single=";
    data+=(int) humidity;
    data+="&entry.2.single=";
    data+=(int) val;
    data+="&submit=Submit";