Invio dati a google drive

Ciao a tutti,
sono sempre io :stuck_out_tongue: e sto ancora una volta cercando il vostro aiuto per migliorare il mio progetto di maturità
dopo aver interfacciato diversi sensori con arduino e controllato dei led da remoto trammite una pagina html adesso sto cercando di inviare i dati registrati dai sensori e di salvarli su un foglio di calcolo google
su internet ho trovato una guida un po datata perche a quei tempi non esisteva google drive, ma a quanto ho capito il meccanismo dovrebbe essere lo stesso. http://blog.elettronicain.it/2011/08/29/i-dati-da-arduino-a-google-spreadsheet/
questo invece è il mio form https://docs.google.com/forms/d/1tWZ8lGMklrECP9pNZq7uxb5-9rBsWfX9RKFk-CKVREI/viewform
in allegato lo sketch di arduino, non potevo postarlo per via del limite dei caratteri in un post
la parte che riguarda l'invio dei dati è quella finale.
volevo capire esattamente cosa fà il comando "data+" e perche mi da errore
grazie

Progetto_maturit_.ino (12.4 KB)

volevo capire esattamente cosa fà il comando "data+" e perche mi da errore

http://arduino.cc/en/Tutorial/StringAppendOperator

in pratica il comando += aggiunge un valore (nel mio caso il valore della temperatura e dei consumi) ad una stringa (nel mio caso il campo del form da compilare).
non ho invece capito il perche dell'errore:

Progetto_maturit_.ino: In function ‘void loop()’:
Progetto_maturit_:228: error: ambiguous overload for ‘operator+=’ in ‘data += sensors.DallasTemperature::getTempCByIndex(0u)’
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:108: note: candidates are: String& String::operator+=(char)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:109: note:                 String& String::operator+=(unsigned char)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:110: note:                 String& String::operator+=(int)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:111: note:                 String& String::operator+=(unsigned int)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:112: note:                 String& String::operator+=(long int)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:113: note:                 String& String::operator+=(long unsigned int)

A parte che manca il ; in

data+=sensors.getTempCByIndex(0)

Se è un refuso è il ; esiste nel codice allora dimmi che tipo di dato restituisce sensors.getTempCByIndex(0).

Ciao.

sensors.getTempCByIndex(0) restituisce il valore della temperatura che dovrebbe essere un valore a virgola mobile.
Per ottenere la temperatura uso quel comando perche sto usando un DS18B20 con le librerie OneWire e Dallas.Temperature.
questa è l'attuale parte del codice che si occupa di inviare i dati

        //Invio dati a google
        String data;
  data += "";
  data += "&entry.385580262=";
  data += sensors.getTempCByIndex(0);
  data += "&entry.164459648=";
  data += Irms*230.0;
  data += "&submit=Submit";
        
        delay(1);
        client.flush();
        client.stop();

e questo è l'errore che ne risulta dalla compilazione:

Progetto_maturit_.ino: In function ‘void loop()’:
Progetto_maturit_:228: error: ambiguous overload for ‘operator+=’ in ‘data += sensors.DallasTemperature::getTempCByIndex(0u)’
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:108: note: candidates are: String& String::operator+=(char)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:109: note:                 String& String::operator+=(unsigned char)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:110: note:                 String& String::operator+=(int)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:111: note:                 String& String::operator+=(unsigned int)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:112: note:                 String& String::operator+=(long int)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:113: note:                 String& String::operator+=(long unsigned int)
Progetto_maturit_:230: error: ambiguous overload for ‘operator+=’ in ‘data += (Irms * 2.3e+2)’
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:108: note: candidates are: String& String::operator+=(char)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:109: note:                 String& String::operator+=(unsigned char)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:110: note:                 String& String::operator+=(int)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:111: note:                 String& String::operator+=(unsigned int)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:112: note:                 String& String::operator+=(long int)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:113: note:                 String& String::operator+=(long unsigned int)

TuonoPayne:
sensors.getTempCByIndex(0) restituisce il valore della temperatura che dovrebbe essere un valore a virgola mobile.

Mah ... a me sembra semplicemente che il compilatore ti stia segnalando che il tipo "virgola mobile" NON è fra quelli ammessi ... guarda quando ti dice "candidates are:":

/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:108: note: candidates are: String& String::operator+=(char)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:109: note:                 String& String::operator+=(unsigned char)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:110: note:                 String& String::operator+=(int)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:111: note:                 String& String::operator+=(unsigned int)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:112: note:                 String& String::operator+=(long int)
/home/tuonopayne/.Arduino-1.0.5/hardware/arduino/cores/arduino/WString.h:113: note:                 String& String::operator+=(long unsigned int)

... difatti vedo vari overload, ma tutti per tipi numerici interi (dal singolo char al unsigned long), ma nulla che riguardi i float/double.

Guglielmo

Non c'è un modo per inviare dati a virgola mobile?
grazie
ciao

Direi NO con l'operatore +=, però potresti convertirli in una stringa e sommare quindi due stringhe :wink:

Guglielmo

Allora ho corretto il codice in questo modo:

        //Invio dati a google
        int Temperatura;
        int Consumi;
        Temperatura = sensors.getTempCByIndex(0);
        Consumi = Irms*230.0;
        
        String data;
  data += "";
  data += "&entry.385580262=";
  data += Temperatura;
  data += "&entry.164459648=";
  data += Consumi;
  data += "&submit=Submit";
        
        delay(1);
        client.flush();
        client.stop(); 
        }

e sembra andaretutto ok in quanto il programma viene compilato correttamente. una volta caricato il programma però succede che arduino invia male i dati, infatti invece di visualizzare il valore della temperatura e dei consumi, non visualizzo niente.
questo è il form che sto utilizzando https://docs.google.com/forms/d/1tWZ8lGMklrECP9pNZq7uxb5-9rBsWfX9RKFk-CKVREI/edit?usp=sharing
e questo è il foglio di google nel quale visualizzo le risposte:
https://docs.google.com/spreadsheet/ccc?key=0Ao25dLCexk9rdDh4eFJGY1NleG1IOHlXZXR4ZzY2eFE&usp=sharing
come si puo vedere arduino ha inviato la risposta ma senza inserire i dati,
Inoltre la risposta è stata inviata una sola volta volta, come posso fare per inviare una risposta ogni tot di tempo?
Grazie

Per l'invio dei dati a Google non ti posso aiutare se non suggerendoti di guardare se le funzioni messe a disposizione da Temboo (sicuramente più aggiornato di quel tuo vecchio link) ti possono essere utili e semplificare la vita. In particolare guarda le infinite chiamate che ti mette a disposizione la loro libreria QUI e, in particolare per Google QUI.

Per il resto, ti suggerisco, hai fini di debug, di fare una Serial.println() della tua stringa "data" così da verificare che contenga veramente quello che tu pensi debba contenere :wink:

Guglielmo

P.S. : Fino ad un certo numero di chiamate/mese, Temboo è totalmente gratuito :wink:

Mah ... a me sembra semplicemente che il compilatore ti stia segnalando che il tipo "virgola mobile" NON è fra quelli ammessi ... guarda quando ti dice "candidates are:":

+1

il problema è la conversione float (che è il tipo di dato che ti torna la funzione getTempCByIndex) in stringa.

Puoi guardare qui:
http://forum.arduino.cc/index.php?topic=103935.0

etc
per possibile soluzione

Ok grazie adesso guardo e poi vi faccio sapere

Ho trovato temboo abbastanza ostico e sono tornato al vechio sketch
ho come suggerito da gpb01 aggiunto un Serial.print ed effettivamente la variabile data ha al suo interno il valore che dovrebbe scrivere nel foglio di google, ma che in realtà non scrive.
idee?
grazie
ciao

TuonoPayne:
Ho trovato temboo abbastanza ostico e sono tornato al vechio sketch

Ostico ??? :astonished: :astonished: :astonished:

Naturalmente rispetto la scelta, ma non condivido assolutamente l'opinione ... anzi, dire che è di una banalità unica ! Ma hai visto le sezioni riguardanti il codice per Arduino ? Perché ci sono tutti gli esempi fatti ....

Guglielmo

Ostico per quanto riguarda la lingua, alcuni termini tecnici sono difficili da capire e non rendono chiara la spiegazione

ho corretto il codice nel seguente modo così dovrebbero venire inviati entrambi i dati, (che in realta non vengono inviati a google drive)

        String data;
        String data1;
  data += "";
  data1 += "";
  data += "&entry.385580262=";
  data += Temperatura;
  Serial.print(data);
  data1 += "&entry.164459648=";
  data1 += Consumi;
  Serial.print(data1);
  data += "&submit=Submit";
  data1 += "&submit=Submit";

        
        delay(1);
        client.flush();
        client.stop();

sto pensando che forse il problema si trovi all'inizio del programma, dove definisco il server google:

#include <String.h>
#include <SPI.h> 
#include <Ethernet.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "EmonLib.h"

char formkey[] = "1tWZ8lGMklrECP9pNZq7uxb5"; 
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // indirizzo mac
byte ip[] = { 192, 168, 1, 12 }; // indirizzo ip da assegnare ad arduino
byte gateway[] = { 192, 168, 1, 1 }; // gateway
byte subnet[] = { 255, 255, 255, 0 }; //subnet mask
byte host[] = { 209,85,229,101 }; // Google IP
EthernetServer server(80); //porta del server

String readString;

io ho definito l'ip di google come host mentre nella guida era definito come server,

Mi è venuto un dubbio non è che per caso quello che sto cercando di fare è impossibile?
intendo creare un web server con arduino e in seguito inviare i dati ad un altro server (in questo caso google)
chiedo questo perche se provo ad inviare i dati attraverso il browser usando questa stringa tutto funziona:

https://docs.google.com/forms/d/1tWZ8lGMklrECP9pNZq7uxb5-9rBsWfX9RKFk-CKVREI/formResponse?entry.385580262=50&submit=Submit

e viene inviato il valore 50 al form di google
mentre se provo an integrare il tutto con le client.print non funziona niente:

client.print("https://docs.google.com/forms/d/1tWZ8lGMklrECP9pNZq7uxb5-9rBsWfX9RKFk-CKVREI/formResponse?entry.385580262=50&submit=Submit")

ottengo solo che come risultato visualizzo nella pagina html dal quale controllo lo stato dei sensori e comando gli attuatori visualizzo il codice per inviare i dati a google

Ciao,
due cose:

  • quando usi un sacco di stringhe, saturi la ram; leggi qui:
    Arduino Playground - Memory
    e racchiudi le stringhe in F(), risparmi ram perchè allochi le stringhe in flash.
  • tu istanzi un server su Arduino, non un client.
    Pertanto puoi accettare connessioni da parte di client, ma non puoi comportarti da client a tua volta (non con il codice che stai usando).
    Inoltre la famosa stringa "data" che contiene la url, a parte dichiararla e riempirla con la url e i valori, non mi pare tu ci stia facendo nulla.

Ti conviene partire da un livello più basso, guardarti gli esempi WebServer e WebClient presenti nell'IDE, e poi crearti le tue due istanze separate, e quindi farne un merge.
Qualcuno nel forum aveva già fatto coesistere client e server.

Ciao.
Purtroppo ho poco tempo per completare il progetto e con l'esame alle porte non posso dedicarmi totalmente al suo completamento.
non ci sarebbe un modo piu semplice per salvare e in seguito visualizzare idati da qualche altra parte? per esempio su una scheda sd?

Purtroppo ho poco tempo per completare il progetto e con l'esame alle porte non posso dedicarmi totalmente al suo completamento.

:cold_sweat:

non ci sarebbe un modo piu semplice per salvare e in seguito visualizzare idati da qualche altra parte? per esempio su una scheda sd?

certo puoi salvare i dati su sd.
Per visualizzarli potresti usare un banale foglio di calcolo - se salvi i dati in formato csv li puoi importare direttamente e poi fare dei grafici sulla tabella.
Oppure puoi passare i dati direttamente via seriale.
Ma anche per queste cose devi dedicare del tempo.

Ok ho inserito la scheda micro sd e ho caricato il seguente esempio:

/*
  SD card test 
   
 This example shows how use the utility libraries on which the'
 SD library is based in order to get info about your SD card.
 Very useful for testing a card when you're not sure whether its working or not.
 	
 The circuit:
  * SD card attached to SPI bus as follows:
 ** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
 ** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
 ** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
 ** CS - depends on your SD card shield or module. 
 		Pin 4 used here for consistency with other Arduino examples

 
 created  28 Mar 2011
 by Limor Fried 
 modified 9 Apr 2012
 by Tom Igoe
 */
 // include the SD library:
#include <SD.h>

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
const int chipSelect = 4;    

void setup()
{
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("\nInitializing SD card...");
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
  // or the SD library functions will not work. 
  pinMode(53, OUTPUT);     // change this to 53 on a mega


  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card is inserted?");
    Serial.println("* Is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    return;
  } else {
   Serial.println("Wiring is correct and a card is present."); 
  }

  // print the type of card
  Serial.print("\nCard type: ");
  switch(card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    return;
  }


  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();
  
  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize *= 512;                            // SD card blocks are always 512 bytes
  Serial.print("Volume size (bytes): ");
  Serial.println(volumesize);
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);

  
  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);
  
  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
}


void loop(void) {
  
}

ma non funziona non riesce ad inizializzare la scheda sd ho anche cambiato il pin da 10 a 53 visto che uso arduino mega 2560 + ethernet shield W5100, la scheda sd ho provato a formattarla sia in fat32 che in fat16