problema con pachube (www.cosm.com)

Caro Lesto,
tu hai anche ragione, ma da autodidatta e con i capelli oramai biancastri non è così facile...

Ciao Ettore,
spero veramente di riuscir ad offrirti una birra!

Alla fine ho fatto un mix del tuo codice e di quello che avevo originalmente perché anche con caldaia e ventola accesa il valore su pachube rimaneva a 0.
Adesso lo testo per un paio di giorni e poi lo installo sul sistema termosolare.
Veramente grazie ancora, non essendo un programmatore, ma solo un elettricista, confrontare i codici e trovarne gli errori mi aiuta ad imparare tanto.

lesto hai ragione, ma e' comodissimo avere qualcuno che ti scrive il codice :smiley:
ce ne fossero di piu' :stuck_out_tongue_closed_eyes:

Ettore benvenuto sul forum, ti faccio i complimenti sia per la preparazione che per la voglia di condivisione

x elvis, se vuoi cmq implementare un delay, magari per omodita' tua o per altri progetti, che non blocchi l'esecusione del codice devi usare millis, guardati l'esempio di "blink without delay" presente nell'IDE

Per Lesto: hai ragione, ma non hai idea di quanto si impari, vedendo come come uno sketch dovrebbe essere fatto.

Per Testato: grazie del tuo caloroso benvenuto!

Per Elvis: facciamo pure una cassa di birra! Accetto anche altri pagamento in natura... alimentare! (cosa avevi capito? :D)

Ettore Massimo Albani

Bene, sperando che tutto questo lavoro possa servire a qualcun altro, il codice che ho installato è:

/* IDE 1.0.1
 Ethernet shield attached to pins 10, 11, 12, 13
 Arduino uno
 modified by Ettore Massimo Albani
 */

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

#define APIKEY         "XXXXXXXXXXXXXXXXXXXXXXXXXX"   // replace your Cosm api key here
#define FEEDID         XXXX                                // replace your feed ID
#define USERAGENT      "TEST 2"                             // user agent is the project name

byte mac[] = {                                              // MAC address of Ethernet controller
  0xDE, 0xAD, 0xBC, 0xEF, 0xFE, 0xBD};

IPAddress ip(192, 168, 11, 21);                             // IP address on your network here

EthernetClient client;                                      // initialize the library instance:

// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:

// IPAddress server(216, 52, 233, 121);                        // numeric IP for api.cosm.com
char server[] = "api.cosm.com";                             // name address for Cosm API

unsigned long lastConnectionTime = 0;                       // last time you connected to the server, in milliseconds
boolean lastConnected = false;                              // state of the connection last time through the main loop
const unsigned long postingInterval = 10000;                // delay between updates to Cosm.com (10 s)

String DataString = "";                                     // stringa per invio dati
char Buffer[10];                                            // buffer per dftostr()

int otherSensorReadingAria = 0;  
int otherSensorReadingCaldaia = 0;

int caldaiaON = 0;                                          //*INGRESSO ANALOGICO PER CONTROLLO WEB STATO CALDAIA 
int Ventola = 0;                                            //*INGRESSO ANALOGICO PER CONTROLLO WEB STATO VENTOLA

const float AnaRef = 5.0;                                   // valore tensione (5V)
const unsigned int Risoluzione = 1024;                      // risoluzione (10 bit) 

const float RangeMin = 2.0;                                 // temperatura minima °C sensore LM35DZ (alim. 5V, out con res. 2k in serie)
const float RangeMax = 100.0;                               // temperatura massima °C sensore LM35DZ (alim. 5V, out con res. 2k in serie)
const float Incremento = 0.01;                              // incremento (10 mV/°C)

float Volt = 0;                                             // valore sensori analogici in volt

const float Isteresi = 2.5;                                 // isteresi (1 °C)

float TempAria = 0.0;                                       // temperatura aria
float TempAriaMin = 2.0;                                    // soglia inferiore temperatura aria (min 2 °C = RangeMin)
float TempAriaMax = 25.0;                                   // soglia superiore temperatura aria (max 100 °C = RangeMax)

float TempAcqua = 0.0;                                      // temperatura acqua
float TempAcquaMin = 2.0;                                   // soglia inferiore temperatura acqua (min 2 °C)
float TempAcquaMax = 42.0;                                  // soglia superiore temperatura acqua (max 100 °C)

void setup() {

  analogReference(DEFAULT);                                 // DEFAULT (5V), INTERNAL (1,1V), EXTERNAL (0÷5V)

  pinMode(A1, INPUT);                                       // sensore di temperatura aria
  pinMode(A3, INPUT);                                       // sensore di temperatura acqua

  pinMode(5, OUTPUT);                                       //*USCITA IN PARALLELO AL RELE CALDAIA PER VISUALIZZAZIONE WEB STATO VENTOLA   
  pinMode(6, OUTPUT);                                       //*USCITA IN PARALLELO AL RELE CALDAIA PER VISUALIZZAZIONE WEB STATO CALDAIA  
  
  pinMode(8, OUTPUT);                                       // relay caldaia ON/OFF
  pinMode(9, OUTPUT);                                       // relay ventola ON/OFF

  Serial.begin(9600);

  if (Ethernet.begin(mac) == 0) {                           // start the Ethernet connection
    Ethernet.begin(mac, ip);                                // DHCP failed, so use a fixed IP address
    Serial.println("Failed to configure Ethernet using DHCP");
  }
}

void loop() {
 caldaiaON = analogRead(A0);                                //*INGRESSO ANALOGICO PER CONTROLLO WEB STATO CALDAIA 
  Ventola = analogRead(A2);                                 //*INGRESSO ANALOGICO PER CONTROLLO WEB STATO VENTOLA
  
  Volt = analogRead(A1) * AnaRef / Risoluzione;             // valore sensore aria in volt
  TempAria = Volt / Incremento + RangeMin;                  // temperatura aria in °C
  delayMicroseconds(120);                                   // 120 µs (min time reading = 100 µs x channel) 

  Volt = analogRead(A3) * AnaRef / Risoluzione;             // valore sensore acqua in volt
  TempAcqua = ((Volt / Incremento + RangeMin)+4);           // temperatura acqua in °C +4°C PER COMPENSAZIONE TERMOMETRO TRIVALVOLA
  delayMicroseconds(120);                                   // 120 µs (min time reading = 100 µs x channel) 

  Serial.print("Temp. Aria: ");
  Serial.println(TempAria, 1);
    otherSensorReadingAria = Ventola;  

  Serial.print("Temp. Acqua: ");
  Serial.println(TempAcqua, 1);
   otherSensorReadingCaldaia = caldaiaON;


  if (TempAria > (TempAriaMax + Isteresi)) {
    digitalWrite(9, HIGH);                                 // relay ventola ON
    digitalWrite(5, HIGH);                                 //*VENTILAZIONE ATTIVATA
    Serial.println("Aria calda - Ventola ON");
  }
  else if (TempAria < (TempAriaMax - Isteresi)) {
    digitalWrite(9, LOW);                                   // relay ventola OFF
    digitalWrite(5, LOW);                                    //*VENTILAZIONE DISATTIVATA
    Serial.println("Aria fredda - Ventola OFF"); 
  }

  if (TempAcqua > (TempAcquaMax + Isteresi)) {
    digitalWrite(8, LOW);                                   // relay caldaia OFF
       digitalWrite(6, LOW);                               //*USCITA IN PARALLELO AL SEGNALE CALDAIA PER TELECONTROLLO
    Serial.println("Acqua Calda - Caldaia OFF");
  }
  else if (TempAcqua < (TempAcquaMax - Isteresi)) {
    digitalWrite(8, HIGH);                                  // relay caldaia ON
        digitalWrite(6, HIGH);                               //*USCITA IN PARALLELO AL SEGNALE CALDAIA PER TELECONTROLLO
    Serial.println("Acqua fredda - Caldaia ON"); 
  }

  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  // if there's no net connection, but there was one last time
  // through the loop, then stop the client:
  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("disconnecting...");
    client.stop();
  }

  // if you're not connected, and ten seconds have passed since
  // your last connection, then connect again and send data: 

  if (millis() < lastConnectionTime) lastConnectionTime = millis();    // evita il blocco dopo 50gg poiché millis() si azzera

  if (!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
    DataString = "TempAria,";
    DataString += FloatFormat(TempAria, 10, 1, false, true);
    DataString += "\nVentola,";
  DataString += otherSensorReadingAria;
    DataString += "\nTempAcqua,";
    DataString += FloatFormat(TempAcqua, 10, 1, false, true);
    DataString += "\nCaldaia,";
  DataString += otherSensorReadingCaldaia; 
    sendData(DataString);
  }
  // store the state of the connection for next time through
  // the loop:
  lastConnected = client.connected();
}

// this method makes a HTTP connection to the server:

void sendData(String thisData) {
  // if there's a successful connection:
  if (client.connect(server, 80)) {
    Serial.println("connecting...");
    // send the HTTP PUT request:
    client.print("PUT /v2/feeds/");
    client.print(FEEDID);
    client.println(".csv HTTP/1.1");
    client.println("Host: api.cosm.com");
    client.print("X-ApiKey: ");
    client.println(APIKEY);
    client.print("User-Agent: ");
    client.println(USERAGENT);
    client.print("Content-Length: ");
    client.println(thisData.length());

    // last pieces of the HTTP PUT request:
    client.println("Content-Type: text/csv");
    client.println("Connection: close");
    client.println();

    // here's the actual content of the PUT request:
    client.println(thisData);
    Serial.println(thisData);
  } 
  else {
    // if you couldn't make a connection:
    Serial.println("connection failed");
    Serial.println();
    Serial.println("disconnecting...");
    client.stop();
  }
  // note the time that the connection was made or attempted:
  lastConnectionTime = millis();
}

String FloatFormat(float X, char Size, unsigned char Decimal, boolean Plus, boolean AutoReduce) {

  char Buffer[Size + 1];

  String Z = dtostrf(X, Size, Decimal, Buffer);
  if (Plus && X > 0) Z[Z.lastIndexOf(' ')] = '+';
  if (AutoReduce) Z.trim();

  return Z;
}

Ed ora che si fa?
... vorrei cercar di capire sia i millis che come inviare a pachube i dati di uscita di una porta digitale senza far rientrare il segnale in una porta analogica usando delle resistenze come in schema.

e... giusto per non annoiarsi... il prossimo progetto sarà inviare i dati del mio impianto fotovoltaico a pachube. Attendo solo che mi arrivino un paio di integrati dalla cina per installare i TA (trasformatori amperometri) sui conduttori.

Grazie veramente a tutti per il supporto ed in particolare ad Ettore che spero di ubbbbriacare presto. :slight_smile:
Elvis

P.S.: nel caso dovessi far aggiornamenti sul progetto "termosolare" li troverete pubblicati sul mio sito 24frames.it.

Ciao Testato,
mi sto "impegnando" con millis, ma riesco ad utilizzarlo solo per ritardare l'accensione della caldaia?

if (TempAcqua > (TempAcquaMax + Isteresi)) {
    digitalWrite(8, LOW);                                   // relay caldaia OFF
       digitalWrite(6, LOW);                               //*USCITA IN PARALLELO AL SEGNALE CALDAIA PER TELECONTROLLO
    Serial.println("Acqua Calda - Caldaia OFF");
  }
  else if (TempAcqua < (TempAcquaMax - Isteresi)) {
    digitalWrite(8, HIGH);                                  // relay caldaia ON
        digitalWrite(6, HIGH);                               //*USCITA IN PARALLELO AL SEGNALE CALDAIA PER TELECONTROLLO
    Serial.println("Acqua fredda - Caldaia ON"); 
  }

Grazie

Dipende da quanti e di che entita' sono gli altri delay in gioco.
Il delay fa il suo mestiere, cioe' blocca l'esecuzione, quindi se tu usi millis solo per la caldaia, ma poi metti un bel delay di 10 secondi da qualche parte, quei 10 secondi sempre delay blocco sono.

In genere se si vuole usare millis lo si fa in tutto lo sketch, tranne i delay "tecnici" quelli che obbligatoriamente devono bloccare tutto, ad esempio in fase di inizializzazione di qualcosa, di qualche protocollo.
Anche nelle librerie ci possono essere delay, e quelli sono nascosti sotto al cofano, ma non credo sia il tuo caso

io avrei bisogno solo di ritardare lo spegnimento della caldaia

elvis:
io avrei bisogno solo di ritardare lo spegnimento della caldaia

puoi provare così metti in alto nello sketch prima del void setup

extern unsigned long timer0_millis;
float mela;

nel void setup metti

mela=1;

poi modifichi le righe incriminate cosi

if ((TempAcqua > (TempAcquaMax + Isteresi)) && mela==1) (timer0_millis = 0, mela = 0 )

if (TempAcqua > (TempAcquaMax + Isteresi)) && (millis()>30000) {
digitalWrite(8, LOW);
digitalWrite(6, LOW);
Serial.println("Acqua Calda - Caldaia OFF");
}

if (TempAcqua < (TempAcquaMax - Isteresi)) {
digitalWrite(8, HIGH);
digitalWrite(6, HIGH);
mela=1;

Serial.println("Acqua fredda - Caldaia ON");
}

spiegazione=
appena si verificano le condizioni per spegnere la caldaia
viene resettato millis()-------- e la variabile mela 1 viene portata 0
appena millis supera i millisecondi che metti (in questo caso 30000 che sono 30 secondi)
porta a LOW i pin 6,8,
la variabile mela 1 che passa a mela 0 serve perche altrimenti resterebbe sempre mela 1 e si continuerebbe a portare il millis() a zero ad ogni ciclo,

l'ho provato a modo mio e funziona

Grazie Gingardu,
in questi giorno non sono in casa e non riesco a testarlo, ma appena posso ti faccio sapere come va.
Ho cercato di far un po' di esperimenti con millis... ma non mi entra in testa... Uff!
Grazie ancora ed a presto.

ok , millis non e troppo facile da comprendere nemmeno per me
metto qui il codice messo su al volo per provare quello che interessava a te
ho adoperato solo arduino uno e un potenziometro su A0

appena giro il potenziometro (che dovrebbe simulare TempAcqua )
millis() si azzera (si vede nel monitor seriale )
passano 6 secondi
e il led pin 13 si spegne
se giro il pot al comtrario il led si riaccende

extern unsigned long timer0_millis;
float a;
float b;
float c;
float mela;

 void setup () {  
  pinMode (13, OUTPUT);  
digitalWrite(13, HIGH);
  Serial.begin(9600); 
  mela=1;


}

void loop () 
 {
  
   
a=analogRead  (A0);
b=10;
c=20;





if ((a > (b + c))&& mela==1)(timer0_millis = 0, mela  = 0 );


if ((a > (b + c))&&(millis() > 6000)) { (digitalWrite(13, LOW)); //

       
    Serial.println("Acqua Calda - Caldaia OFF");
  }

if (a < (b + c)){(digitalWrite(13, HIGH),mela=1);

 
                          
    Serial.println("Acqua fredda - Caldaia ON"); 
  }

  
 Serial.println(millis());

 }

Millis non è altro che una funzione che restituisce il numero di millisecondi passati dall'avvio dell'Arduino.
I controlli con millis possono essere bloccanti come nel caso dei delay oppure non bloccanti, dipende da come si struttura il codice.
L'esempio di BlinkWithoutDelay è del secondo tipo: periodicamente viene controllato se è passato l'intervallo predefinito, nel caso cambia lo stato del led.
Il vantaggio è che nel frattempo si possono compiere altre operazioni.

Per capire meglio, immaginiamo una persona che guarda la televisione mentre aspetta di andare fuori con gli amici. Sa che prima delle 22 al bar sotto casa non ci sarà nessuno e la cena termina alle 21, momento in cui si mette di fronte al televisore. Dalle 21 alle 22 la persona guarderà i programmi televisivi ed ogni tanto butterà un'occhiata all'orologio per vedere se sono arrivate le 22. Se non sono arrivate le 22, continuerà a guardare la TV, se sono arrivate si alzerà ed uscirà di casa.

Ora immaginate che la persona sia il vostro Arduino. Gli date 2 compiti da fare: il primo, il principale, equivale al guardare la TV. Il secondo, il controllo dell'orario, è secondario e va fatto ogni tanto. Il micro esegue il primo compito e, terminato questo, controlla l'orario con millis: se non è ancora scattato l'allarme, riesegue il primo altrimenti esegue il secondo compito.

he... he.... una volta compreso appieno lo so che non ci sono piu problemi,
bisogna arrivarci però a quel punto

ci vuole pazienza e sopratutto "pratica" vedendo gli sketch spiegati a dovere aiuta moltissimo,
studiarseli e comprendere

Grazie Leo72 e grazie Gingardu,
ci sono dei concetti che per un elettricista (meccanico-old stile) come me non sono proprio immediati da comprendere, però l'esempio del tipo che guarda la TV mi ha reso abbastanza chiaro il concetto.
In settimana, appena rientro a casa e riprendo per mano Arduino, faccio un po' di esperimenti e vediamo come va!
Grazie e buon week and.

Ciao Gingardu,
ho finalmente avuto modo di testare le modifiche che mi hai consigliato e... FUNZIONA!
Fa esattamente ciò che speravo.
Grazie veramente.

Sul mio sito:

troverete pubblicato lo schema e lo sketch dell'impianto che ho installato.

Alla pagina:

https://cosm.com/feeds/69741

troverete pubblicati i dati inviati da arduino a Pachube.

Il refresh avviene ogni 50sec. circa.

bel lavoro elvis,
e grazie della condivisione.

approfitto per chiederti qualcocsa su cosm, ho visto che la massima larghezza del grafico e' 3 mesi, dopo 3 mesi i vecchi valore vengono persi ?
si puo' salvare, o tenere sul sito, uno storico grafico senza limiti ?

Ciao Testato,
Immagino che i dati su cosm, essendo un servizio gratuito, dopo tre mesi vengano persi...
Potresti pero' salvarli su una micro SD... So che si può fare.