Go Down

Topic: Aiuto modifica sketch playground su EEM12L-32A (Read 1 time) previous topic - next topic

ziopippo

Feb 11, 2013, 01:15 am Last Edit: Feb 11, 2013, 01:18 am by ziopippo Reason: 1
Ho collegato ad un Arduino Mega questo contatore monofase  http://www.energiasolare100.it/contatore-monofase-a-due-cavi-guida-din-con-uscita-impulsi-p-670.html

Ho usato lo sketch preso dal playground http://playground.arduino.cc/Main/EEM12L-32AKWhMonitoring utilizzando una resistenza come consigliato nell'articolo ma da 330 ohm.

Da quello che ho visto mi rileva la potenza attuale in step di 0,50 w alla volta e non ha mezze misure. Accendendo il microonde per alcuni minuti a 750W mi segnala potenze variabili da 0.0010 a 0.0015 mentre in situazioni "stabili" mi segnala sempre da 0.0000 a 0.0050 ed inoltre il contatore mi si incrementa ovviamente di 0.0050 alla volta.

Come devo modificare il codice per conoscere l'esatta potenza istantanea in uso da utilizzare magari come stato di allerta in per evitare il distacco del contatore per superamento della soglia?

Grazie mille.

uwefed

devi misurare il tempo tra un impulso e l' altro.
Ciao Uwe

ziopippo

Buon giorno uwe e grazie per la risposta.
In effetti non lo avevo scritto ma sul fatto che dovessi calcolare il tempo tra T0 e T1 ci ero già  arrivato.  ;) Quello  che non so è che usando  il playground gli interrupt non so come fare a riconoscere in quel codice il mutamento  di stato da low ad high.  :smiley-red:

leo72

Nel codice che hai linkato agganciano un interrupt al passaggio del pin da alto a basso:
Code: [Select]
attachInterrupt(0, Kirq, FALLING);
Se il tuo problema è misurare lo stato inverso, passaggio da basso ad alto, metti RISING

Documentazione base degli interrupt hardware dell'Arduino:
http://arduino.cc/en/Reference/AttachInterrupt

cyberhs

Il dispositivo fornisce un impulso di 50 ms ogni 0,5 Wh (e non W come erroneamente indicato).

Quindi il programma non fa che sommare gli impulsi che arrivano, azzerandoli nel caso siano superiori al miliardo (500 kWh).

Il programma indicato è probabilmente un prototipo in cui ci sono delle variabili non utilizzate (ad esempio SUM).

Se collego una stufetta da 1kW, leggerò dopo 60 minuti un incremento del contatore (variabile rpk) di 2000 impulsi.

Riceverò, cioè, circa 2000 imp /3600 sec = 0.55 impulsi al secondo.

ziopippo

Grazie a tutti per l'aiuto.
Ho fatto uno sketch di prova mandando usando questo codice
Code: [Select]
int IRQ = 4; //Utilizzo il pin D19 della Mega
volatile int state = LOW;

long tempo_trascorso;
long durata;


void setup()
{
 Serial.begin(9600);
 pinMode(IRQ, OUTPUT);
 attachInterrupt(4, blink, CHANGE);
}

void loop()
{
 if (!state || (durata == 0))
 {
   // Serial.println ("Nessun evento");
 }
 else
 {
   digitalWrite(IRQ, state);
   Serial.print ("stato dell'irq ");
   Serial.print (IRQ);
   Serial.print (" e'= ");
   Serial.print (state);
   Serial.print (" e sono passati ");
   Serial.print (durata/1000);
   Serial.println (" secondi");
   durata = 0;
 }
}

void blink()
{
 state = !state;
 durata = millis()-tempo_trascorso;
 tempo_trascorso = millis();
}



Secondo voi può andar bene?

Accendendo il solito microonde a 750w per qualche minuto questo è il risultato che mi tira fuori il serial monitor
Code: [Select]

stato dell'irq 4 e'= 1 e sono passati 9 secondi
stato dell'irq 4 e'= 1 e sono passati 9 secondi
stato dell'irq 4 e'= 1 e sono passati 2 secondi
stato dell'irq 4 e'= 1 e sono passati 1 secondi
stato dell'irq 4 e'= 1 e sono passati 1 secondi
stato dell'irq 4 e'= 1 e sono passati 1 secondi
stato dell'irq 4 e'= 1 e sono passati 1 secondi
stato dell'irq 4 e'= 1 e sono passati 1 secondi
stato dell'irq 4 e'= 1 e sono passati 1 secondi
stato dell'irq 4 e'= 1 e sono passati 1 secondi
stato dell'irq 4 e'= 1 e sono passati 3 secondi
stato dell'irq 4 e'= 1 e sono passati 3 secondi
stato dell'irq 4 e'= 1 e sono passati 1 secondi
stato dell'irq 4 e'= 1 e sono passati 1 secondi
stato dell'irq 4 e'= 1 e sono passati 1 secondi
stato dell'irq 4 e'= 1 e sono passati 1 secondi
stato dell'irq 4 e'= 0 e sono passati 0 secondi
stato dell'irq 4 e'= 1 e sono passati 1 secondi
stato dell'irq 4 e'= 1 e sono passati 1 secondi
stato dell'irq 4 e'= 1 e sono passati 1 secondi


Come mostro ora la potenza istantanea da tenere sotto controllo per evitare il distacco enel in caso di superamento della soglia dei 3Kwh?

Inoltre a cosa è dovuto il quart'utlimo risultato (0 secondi)?

Grazie

cyberhs

"Gli è tutto da rifare..."   :D

1 - Il millis() non funziona in una interrupt service routine.
2 - L'attach non può essere su CHANGE poiché la routine viene eesguita due volte.
3 - Il pin sotto interrupt deve essere un input. 

ziopippo

da ciò  penso si sia capito che sono agli inizi.
Ho usato il change perché con gli altri mi diceva quanto tempo durava quello stato mentre a me serve sapere quanto tempo tempo passa tra due stati high.
È possibile avere un aiuto concreto e meno teorico?
Grazie!  :smiley-red:

leo72

@cyberhs:
vorrei correggere, o per meglio dire spiegare meglio, un paio di tue affermazioni, per dare informazioni corrette:

1 - Il millis() non funziona in una interrupt service routine.

Questo è vero solo se si usa il millis per gestire un'attesa perché la routine di gestione dell'interrupt agganciato all'overflow del timer 0 che viene usata per aggiornare il valore del contatore di millisecondi  non può funzionare, e quindi millis dà una lettura sempre uguale. La funzione delay, difatti, che si basa sull'incremento di millis, è una funzione il cui uso è senz'altro da evitare in una routine di interrupt. Nel suo caso, però, lui salva il valore di millis in una variabile, non lo usa per creare un'attesa, per cui l'uso che ne fa è del tutto lecito.

Quote

3 - Il pin sotto interrupt deve essere un input. 

Anche questo non è del tutto corretto perché l'interrupt può essere rilevato indipendentemente dallo stato del pin. Il pin, cioè, può anche essere in stato di output: l'interrupt rileverà lo stesso il cambiamento di stato. Anzi, la tecnica di "scrivere" su un pin agganciato ad un interrupt è spesso usata per simulare degli interrupt software.
Cito dal datasheet (cap 13):
Quote
Observe that, if
enabled, the interrupts will trigger even if the INT0 and INT1 or PCINT23...0 pins are configured as outputs. This
feature provides a way of generating a software interrupt.

ziopippo


...
È possibile avere un aiuto concreto e meno teorico?
Grazie!  :smiley-red:



up...  :P

cyberhs

Per Leo:
grazie per il completamento delle mie affermazioni, ma confesso che non sapevo della possibilità di lasciare in output un pin e di poter rilevare le variazione sotto interrupt. Si impara sempre...

Per Ziopippo:
non puoi pretendere che si risponda subito alle tue richieste: c'è un tempo tecnico per elaborarle.
Ad esempio, sto approntando uno sketch proprio per te ma devo risolvere ancora qualche punto. 

ziopippo

@cyberhs: con il mio up non intendevo mettere fretta a nessuno  ;) ho pensato  però che essendo  già stato trattato diverse volte sul forum (ma solo a livello teorico) qualcuno avesse  già trovato una soluzione  :smiley-red:

cyberhs

#12
Feb 15, 2013, 12:13 pm Last Edit: Feb 15, 2013, 08:52 pm by cyberhs Reason: 1
Come promesso, anche se non l'ho potuto provare!
Code: [Select]
/*
KwH
for Arduino UNO/MEGA R3 & IDE 1.0.1
by Ettore Massimo Albani 13/02/2013
www.cyberhs.it
info@cyberhs.it
*/

const float ImpulsiWh = 0.5;                  // 1 impulso = 0.5 Wh
const long T = 30000;                         // 30 secondi
unsigned long Timer = 0;                      // timer

volatile unsigned int Impulsi = 0;            // impulsi contati
volatile unsigned int ImpulsiMemo = 0;        // memoria impulsi
volatile unsigned long kWh = 0;               // totale energia (kWh)

float W = 0;                                  // potenza istantanea (W)

void setup() {
 Serial.begin(9600);
 attachInterrupt(0, Contatore, FALLING);
}

void loop() {
 if (millis() - Timer > T) {                // timer scaduto
   if (Impulsi > ImpulsiMemo) {             // lettura valida
     W = (Impulsi - ImpulsiMemo) * 3600000 / T * ImpulsiWh;
   }
   ImpulsiMemo = Impulsi;
   Timer = millis();                      // timer partito
 }
 Serial.print("kWh: ");    
 Serial.println(kWh);
 Serial.print("W: ");    
 Serial.println(W, 1);
}

void Contatore() {
 Impulsi ++;                    // incrementa contatore
 if (Impulsi > 1999) {          // raggiunto il kWh
   kWh ++;                      // incrementa kWh
   Impulsi = 0;                 // azzera contatore
 }
}

ziopippo

Grazie mille! Dopo pranzo la carico e poi ti faccio sapere  ;)
Saluti, Ettore.

ziopippo

Ciao ETTORE! Che bello trovare di rado un omonimo!  :D

Rieccomi con i dati rilevati, ma prima volevo innanzitutto ringraziarti  ;) poi dirti che se puoi modificare il tuo post, nel caso questo threed sarà utile a qualcuno, dovresti sostituire questa riga
Code: [Select]
Volatile unsigned long kWh = 0; in
Code: [Select]
volatile unsigned long kWh = 0;  ;) :smiley-sweat:

Volevo poi chiederti se secondo il tuo codice al superamento di 1999 W la variabile kWh dovrebbe incrementarsi esatto? Se è così qualcosa non mi torna e ti trascrivo i dati rilevati prima con il solito microonde a 750w questa volta tenuto acceso per 1.30 minuti ma che mi pare abbia fatto segnare la variabile W massimo a W: 4260.0 con l'appunto che nel frattempo i bimbi si stavano lavando le mani aprendo e chiudendo l'acqua azionando quindi la caldaia diverse volte. Non avrebbe dovuto segnare la W a 750.0? Ed inoltre la variabile kWh: non si sarebbe dovuta incrementare?

Ultima cosa, ho notato che il serial monitor prima di visualizzare l'aumento dei valori rilevati impieghi diversi secondi (non so quanti perchè  non li ho contati per ho visto che inizia a mostrare valori diversi da zero dopo 1.808
Code: [Select]
Serial.println(W, 1); ovvero dopo 3.616 righe stampate) è normale?


Ecco i dati stampati dai quali ovviamente per limidi di caratteri posstabili ammessi dal forum ho omesso i doppioni
Allego però un file con tutti i dati rilevati durante il minuto e mezzo.

Code: [Select]

Contatore KwH for Arduino UNO/MEGA R3 & IDE 1.0.1  by Ettore Massimo Albani 13/02/2013
kWh: 0
W: 0.0
kWh: 0
W: 180.0
kWh: 0
W: 1620.0
kWh: 0
W: 300.0
kWh: 0
W: 1200.0
kWh: 0
W: 4260.0
kWh: 0
W: 480.0
kWh: 0
W: 2040.0


Grazie ancora Ettore.  :smiley-mr-green:

Go Up