Go Down

Topic: Amperometro con arduino (Read 8 times) previous topic - next topic

Erik86

#15
Jul 26, 2013, 01:40 am Last Edit: Jul 26, 2013, 01:47 am by Erik86 Reason: 1
Ciao Elvis..valida sta libreria..
Tornando a noi, ho notato che nello sketch della libreria EmonLib.cpp, ci sono delle delay(); cosa che nel tuo di sketch, nn ne ho viste..questo comporta rallentamenti sul ciclo di un programma..soprattutto, come nel tuo caso ce di mezzo una comunicazione seriale..
A me era capitata una cosa analoga..due sketch perfettamente funzionanti se uniti sì rallentavano a vicenda..

elvis

Bene bene, allora provo ad eliminare il delay(100) sulla libreria emonlib.cpp, ma secondo te si può eliminare un po' di cose e mantenere solo le stringhe relative al calcolo della corrente?
Devo dire che ho già fatto qualche tentativo, ma, evidentemente, cancello un po' troppa roba...

Erik86

si non è mai buona cosa cancellare qualcosa dalle librerie..al max modificarle..comunque tieni presente che quelle delay(); sicuramente sono li per dare un tempo alla visualizzazione dei valori..quindi teoricamente cancellandola/e nn dovrebbe succedere niente..
prova e fammi sapere..
tu hai mai usato la shield RTC?

pitusso

#18
Jul 26, 2013, 02:15 pm Last Edit: Jul 26, 2013, 02:24 pm by pitusso Reason: 1
Ciao,
sto lavorando in questo periodo con un progettino che attualmente ha 3 sensori TA e deve crescere sino a 9.
Ad ora (quindi con 3 sensori) continuo a fare aggiornamenti ogni 10 secondi via eth (e 30 sec via gprs) senza problemi di sorta.

Nella libreria inoltre l'unico casi di delay significativo (se 100ms così si possono chiamare) si ha con la print seriale di tutte le variabili gestite, cosa che non hai motivo di utilizzare.

EDIT
io credo che il problema non risieda nella libreria in se, come già detto, ma da problemi colllaterali (overflow, memoria, etc).
Quindi, la cosa che ti consiglio di fare, è fare uso del monitor seriale e inserire nel codice in punti strategici delle print, in modo che tu possa capire in che punto del tuo codice avviene il "blocco".
Trovi poi in rete piccole funzioni che ti permettono di controllare la memoria disponibile di Arduino. Inserisci anche la chiamata a questa funzione in vari punti del tuo codice e verifica.

Erik86

si quella è una prova assolutamente sensata da fare e doverosa..
ma quello che intendo io è che se nel suo programma usa dei serial.print senza usare delay, e quando va ad aggiungere il programma che ha trovato e che contiene dei serial.print però con delay, gli va a rallentare l'intero programma, anche se è solo uno il delay.

tu hai ipotizzato che potrebbe essere la memoria ma se cosi fosse il programma propio non partirebbe..

pitusso

Ciao

Quote
quando va ad aggiungere il programma che ha trovato e che contiene dei serial.print però con delay


il delay è all'interno di una funzione che non è necessario che richiami  :P

Quote
tu hai ipotizzato che potrebbe essere la memoria ma se cosi fosse il programma propio non partirebbe..


ho ipotizzato che tra le altre cose, ci potrebbero essere anche problemi di memoria.

E no, anche se ci fossero, il programma partirebbe.
Solo che il funzionamento sarebbe anomalo, ci sarebbero reset, etc

Erik86

in effetti è dentro a una funzione che lui non richiama.. :. :. :.
per il discorso della memoria adesso che ci penso qualche mese fa un ragazzo aveva dei problemi anomali e alla fine il problema era che arduino aveva la memoria piena perchè il programma era troppo grande..però non gli andava a rallentare il programma, in realtà era propio strippatto, non faceva nente di quello che gli diceva di fare lui.. :smiley-roll: :smiley-roll: :smiley-roll:

elvis

#22
Jul 27, 2013, 01:07 am Last Edit: Jul 27, 2013, 01:13 am by elvis Reason: 1
Devo spezzare il codice perché supera i 9500 caratteri.
Parte iniziale:

Code: [Select]


/* IDE 1.0.1

26/04/2013

controllo visibile su https://cosm.com/feeds/123206

CONTROLLO POTENZA GENERATA DAI PANNELLI FOTOVOLTAICI
CONTROLLO CONSUMI IN CASA
CONTROLLO ACCENSIONE E SPEGNIMENTO CALDAIA CON SENSORE LM35 POSIZIONATO SUL TUBO DELL'ACQUA CHE ESCE DAL BOLLITORE DEL SOLARE TERMICO
CONTROLLO TEMPERATURA ACQUAL ALL'INTERNO DEL BOLLITORE DEL SOLARE TERMICO
CONTROLLO ACCENSIONE E SPEGNIMENTO VENTOLA DI ASPIRAZIONE
CONTROLLO TEMPERATURA IN CENTRALE TERMICA
CONTROLLO TEMPERATURA ACQUA IN INGRESSO DEL BOLLITORE DEL SOLARE TERMICO
CONTROLLO ACCENSIONE RESISTENZA DA 2KW COMANDATA DA CENTRALINA IMPIANTO FOTOVOLTAICO


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

#include <SPI.h>
#include <Ethernet.h>
#include "EmonLib.h"                   // Include Emon Library
EnergyMonitor emon1;                   // Create an instance CORRENTE GENERATA DAL FOTOVOLTAICO
EnergyMonitor emon2;                   // Create an instance CORRENTE CONSUMATA IN CASA

#define APIKEY         "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"   // replace your Cosm api key here
#define FEEDID         123206                                // replace your feed ID
#define USERAGENT      "casaelvis Termosolare + Fotovoltaico"         // user agent is the project name

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

IPAddress ip(192, 168, 22, 22);                             // 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 otherSensorReadingResistenza2Kw = 0;

int caldaiaON = 0;                                          //*INGRESSO digitale PER CONTROLLO WEB STATO CALDAIA
int Ventola = 0;                                            //*INGRESSO digitale PER CONTROLLO WEB STATO VENTOLA
int Resistenza = 0;                                            //*INGRESSO digitale PER CONTROLLO WEB STATO resistenza


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 = 1.0;                                 // isteresi (1 °C)

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

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

float TempAcquaINGtermosolare = 0.0;                                      // temperatura acqua in ingresso al termosolare

//////////////////////////////////////////////////////////////
extern unsigned long timer0_millis;
float mela;
//////////////////////////////////////////////

void setup() {
//////////////////////////////////////////////
mela=1;
//////////////////////////////////////////////
 analogReference(DEFAULT);        // DEFAULT (5V), INTERNAL (1,1V), EXTERNAL (0÷5V)
 
 pinMode(A0, INPUT);                                       // NB sensore di temperatura aria
 pinMode(A1, INPUT);                                       // sensore di temperatura acqua
 pinMode(A2, INPUT);                                       // sensore di temperatura acqua ingresso termosolare
 
 pinMode(2, OUTPUT);                                      // D2 uscita per relè in parallelo alla resistenza da 2Kw installata sul bollitore
 pinMode(3, INPUT);                                       //*D3 ingresso controllo stato ventola da D5  
 pinMode(4, INPUT);                                       //*D4 ingresso controllo stato caldaia da D6

 pinMode(5, OUTPUT);                                       //*USCITA IN PARALLELO AL RELE CALDAIA PER VISUALIZZAZIONE WEB STATO VENTOLA  
 pinMode(6, OUTPUT);                                       //*USCITA IN PARALLELO AL RELE ACQUA PER VISUALIZZAZIONE WEB STATO CALDAIA  
 pinMode(7, OUTPUT);                                       // relay ventola ON/OFF
 pinMode(8, OUTPUT);                                       // relay caldaia ON/OFF
 pinMode(9, INPUT);                                        // D10 ingresso per relè in parallelo alla resistenza da 2Kw installata sul bollitore
 
 Serial.begin(9600);
 
  emon1.current(3, 111.1);             // Current: A3 -CORRENTE GENERATA DAL FOTOVOLTAICO-  input pin, calibration.
  emon2.current(4, 111.1);             // Current: A4 -CORRENTE CONSUMATA IN CASA-  input pin, calibration.

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


elvis

Parte finale:

Code: [Select]

void loop() {
 
   double Irms1 = emon1.calcIrms(1480);  // Calculate Irms only
   double Irms2 = emon2.calcIrms(1480);  // Calculate Irms only
   
    Serial.print(F("Potenza Generata dal FV Kw: "));
 Serial.println(Irms1);       // Irms
 
 Serial.print(F("Potenza Consumata in Casa Kw: "));
 Serial.println(Irms2);       // Irms

 
   digitalWrite(2, HIGH);                                // attivazione uscita D2 sempre high per controllo stato resistenza            
   Ventola = digitalRead(3);                                 //*INGRESSO digitale PER CONTROLLO WEB STATO VENTOLA
   caldaiaON = digitalRead(4);                                //*INGRESSO digitale PER CONTROLLO WEB STATO CALDAIA
   Resistenza = digitalRead(9);                           //*INGRESSO digitale PER CONTROLLO WEB STATO resistenza
 
 Volt = analogRead(A0) * 0.5;             // valore sensore aria in volt
 TempAria = Volt;                  // temperatura aria in °C
 delayMicroseconds(120);                                   // 120 µs (min time reading = 100 µs x channel)

 Volt = analogRead(A1) * 0.5;             // valore sensore acqua in volt
 TempAcquaOUTtermosolare = ((Volt)+3);                 // temperatura acqua in °C +X°C PER COMPENSAZIONE TERMOMETRO TRIVALVOLA
 delayMicroseconds(120);                                   // 120 µs (min time reading = 100 µs x channel)
 
 Volt = analogRead(A2) * 0.5;             // valore sensore acqua in volt
 TempAcquaINGtermosolare = ((Volt)+3);                 // temperatura acqua in °C +X°C PER COMPENSAZIONE TERMOMETRO TRIVALVOLA
 delayMicroseconds(120);                                   // 120 µs (min time reading = 100 µs x channel)


     Serial.print("Temp. Acqua ING Termosolare: ");
 Serial.println(TempAcquaINGtermosolare);
 

 Serial.print(F("Temp. Acqua OUT Termosolare: "));
 Serial.println(TempAcquaOUTtermosolare, 1);
  otherSensorReadingCaldaia = caldaiaON;
 

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

 if (TempAria > (TempAriaMax + Isteresi)) {
   digitalWrite(7, HIGH);                                 // relay ventola ON
   digitalWrite(5, HIGH);                                 //*VENTILAZIONE ATTIVATA
   Serial.println("Aria >30°C - Ventola ON");
 }
 else if (TempAria < (TempAriaMax - Isteresi)) {
   digitalWrite(7, LOW);                                   // relay ventola OFF
   digitalWrite(5, LOW);                                    //*VENTILAZIONE DISATTIVATA
   Serial.println(F("Aria <30°C - Ventola OFF"));
 }
////////////////////////////////////////////////////////////////////////////////////////
 if ((TempAcquaOUTtermosolare > (TempAcquaMax + Isteresi)) && mela==1) (timer0_millis = 0, mela = 0 );

 if (TempAcquaOUTtermosolare > (TempAcquaMax + Isteresi) && (millis()>30000)) {
/////////////////////////////////////////////////////////////////////////    
   digitalWrite(8, LOW);                                   // relay caldaia OFF
      digitalWrite(6, LOW);                               //*USCITA IN PARALLELO AL SEGNALE CALDAIA PER TELECONTROLLO
   Serial.println(F("Temp. Acqua Bollitore >43°C - Caldaia OFF"));
 }
 else if (TempAcquaOUTtermosolare < (TempAcquaMax - Isteresi)) {
   digitalWrite(8, HIGH);                                  // relay caldaia ON
       digitalWrite(6, HIGH);        //*USCITA IN PARALLELO AL SEGNALE CALDAIA PER TELECONTROLLO
   mela=1;
   Serial.println(F("Temp. Acqua Bollitore <43°C - 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(F("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 += "\nResistenza,";
   DataString += FloatFormat(Resistenza, 10, 1, false, true);
   DataString += "\nTempAcquaINGtermosolare,";
   DataString += FloatFormat(TempAcquaINGtermosolare, 10, 1, false, true);
   DataString += "\nTempAcquaOUTtermosolare,";
   DataString += FloatFormat(TempAcquaOUTtermosolare, 10, 1, false, true);  
   DataString += "\nCaldaia,";
   DataString += otherSensorReadingCaldaia;
   DataString += "\nIrms1,";
   DataString += FloatFormat(Irms1, 10, 1, false, true);  
   DataString += "\nIrms2,";
   DataString += FloatFormat(Irms2, 10, 1, false, true);
   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(F("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(F("connection failed"));
   Serial.println();
   Serial.println(F("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;
}  



Subito dopo il void loop, alla riga:
Code: [Select]

double Irms1 = emon1.calcIrms(1480);  // Calculate Irms only


si nota un forte rallentamento del codice, motivo per cui mi piacerebbe utilizzare la parte di libreria relativa al solo calcolo della corrente Irms ed evitare di far fare ad arduino calcoli, a virgola mobile, che non mi servono.

grazie

Erik86

Bene e anche oggi abbiamo imparato qualcosa..alla prossima..

elvis


Erik86

Cioè che se il programma che si scrive, passa La memoria supportata possiamo avere dei rallentamenti sul ciclo dell'intero sketch..io nn l'ho sapevo.. :)

elvis

Ho capito, ma ritornando al mio sketch, è possibile "asciugare" la libreria di EmonLib in modo tale da utilizzare solo la parte relativa al calcolo della corrente ed evitare il blocco del ciclo di circa 0,8sec?


pitusso

#28
Jul 28, 2013, 11:58 pm Last Edit: Jul 29, 2013, 12:02 am by pitusso Reason: 1
Ciao

Quote
Ho capito, ma ritornando al mio sketch, è possibile "asciugare" la libreria di EmonLib in modo tale da utilizzare solo la parte relativa al calcolo della corrente ed evitare il blocco del ciclo di circa 0,8sec?


la funzione che richiami fa solo quello che gli chiedi, non esegue altri calcoli inutili.
Motivo per cui credo sarebbe un lavoro inutile.

Poi, parti di ritardo di 0.8 secondi... mi sembrava avessi parlato di ritardi mostruosi...
Considera che il parametro che passi alla funzione calcIrms è il numero di samples da effettuare...

Non hai fatto nulla per verificare lo stato della memoria.
Usa la funzione proposta a fondo pagina:
http://playground.arduino.cc/Code/AvailableMemory



elvis

Adesso co capito... Non credevo che uno sketch come questo fosse ebbe stanza lungo per occupare tutta la memoria...
Credevo che un ritardo di 0.8sec per i due Irms fossero tanti, comunque mi diventa un grande ritardo in un'altro sketch dove utilizzo 3 amperometri e dovendo inviare i dati via radio con dei moduli da 500mW, impiegando lo sketch 1,2sec per fare un ciclo, per legge, dopo l'invio di un pacchetto devo lasciare la frequenza libera per un tempo pari a 10 volte il tempi impiegato ad inviare i dati il che significa che posso avere un refresh solo ogni 12 sec e speravo si riuscir ad abbassarlo a 6sec. elimiinando calcoli superflui... ma, in realtà, mi avete insegnato, questi calcoli inutili arduino non li fa...

In questi giorni non sono in casa, ma appena riesco faccio il controllo della memoria.
Ti farò sapere. Grazie per il tuo aiuto.

Go Up