Oggi si conta
1 2 3 4 5 6 7 8 9 bo!!
Stavo realizzando un semplice Wattmetro ,ma come al solito si è cappottato l'orizzonte e in crisi di pazzia pura ho partorito questo......il
Powermeter Rev3.3
Si tratta semplicemente di :
-un Voltmetro AC.....
-un doppio Amperometro AC.....
-un doppio Wattmetro ........
-un doppio contatore con memoria di Backup (metti che vada via la luce)
Le sue applicazioni sono molteplici:
-Vuoi misurare la potenza che produci..ora puoi
-e che consumi ...ora puoi
-Volevi sapere la tensione per un rapido Trouble Shooting..ora puoi
-Hai il contatore in comune e vuoi sapere i due consumi ...ora puoi
-Vuoi stare comodamente al computer e leggere i consumi...ora puoi (magari se si implementasse un programmino in VB)...
-Vabbè puoi farci quello che ti pare,,,,io lo metto a disposizione del Forum nella speranza che sia utile a qualcuno oltre a me
Dettaglio
"LE PAGINE DEL DISPLAY"Prima pagina (nel programma la numero 0)
Seconda pagina (nel programma la numero 1)
Terza pagina (nel programma la numero 2)
Quarta pagina (nel programma indovinate )
Avete notato niente !!????
Nella seconda pagina sono presenti dei tratti in quanto dipende in quale configurazione vi trovate.
Mi spiego meglio.......
-Io vado di On grid Tie e ho alcune esigenze.-Pippo và di Isola ed usa un inverter-Pluto và di Isola ed usa un UPS.....-Puffo scrocca Quindi in che configurazione vi trovate ????
Semplicemente o A o B......
Come realizzarlo???
Bo!!provate a chiedere al vicino
oppure
W il Fai da Te .......
Iniziamo :
Sezione Alimentatore e adattatore di livello!!!!
Lo so ..lo so ..il condensatore dovè.........bo !!!Cmq l'ho dimenticato volontariamente .
Il display ed i sensori ....(i miei piccolini ACS712 da 30A)ecco come vanno collegati
Nella Configurazione B il PowerMeter visualizza sulla pagina 2 lo Stato dell'UPS
-ACTIVE se stà fornendo energia
-STBY se in attesa
Spero che sia di vostro gradimento e che il mio non sia figlio unico
Saluti Veri
ElettroshockNow
Ora una Breve panoramica della realizzazione:
Il sensore ACS712 da 30A
Consiglio un bel giro di nastro autoagglomerante
Magari installandoli in maniera fissa
L'arduino pronto per sposarsi con il display
L'interno nasconde
L'estetica finale
A dimenticavo.....
Ciao...
Dimenticavo una cosina ...il codice Rev3.5
/*Progetto Powermeter Rev3.5
Un sentito ringraziamento al Forum
"" Energia Alternativa & Energia Fai Da Te ""
http://energiaalternativa.forumcommunity.net/
Saluti
ElettroshockNow
----------------------------------------------------------------------------
INFO:il Powermeter dispone di memoria eeprom interna nella quale salva a cadenza di
4 ore il valore contenuto nei contatori e le soglie impostate.
Se si desidera resettare i contatori e ricaricare le soglie di default :
-disalimentare il circuito
-premere e mantenere premuto il pulsante (il Pulsante è connesso al Pin2)
-alimentare il circuito
-attendere la scritta "ATTENZIONE RESET CONTATORI TRA 4H"
-rilasciare il pulsante
A questo punto il reset è armato e sarà attivato allo scadere delle 4H.
Quindi se erroneamente si resettano i contatori ,basterà disalimentare e rialimentare il
circuito per recuperare l'ultimo Backup.
-----------------------------------------------------------------
*/
//IMPOSTAZIONI UTENTE (Scegliere le preferenze)
const boolean ConfigB = false; //Configurazione B ? true or false
//Scegli lo schema di installazione piu' adatto
//false = doppio contatore simultaneo
//true = doppio contatore funzionamento selettivo
const byte PagDefault = 0; // Scegli la schermata di default..:-)
//0 = Wattmetro
//1 = Voltmetro + stato UPS
//2 = Amperometro
//3 = Contatori
const boolean Retroilluminazione = false; // Retroilluminazione Display
//true= con timer (solo con pulsante)
//false= sempre ON
const int TempoLed = 200; //Scegli il Tempo della retroilluminazione
//allo spengimento si imposterà la pagina di Default
//Ogni unita vale circa 2 secondi :-)
//------------------------------------------------------------
// LIBRERIE
#include <VirtualWire.h>
#include <LiquidCrystal.h>
#include <EEPROM.h>
#include <DFR_Key.h>
//-----------------------------------------------------------
// VARIABILI E COSTANTI
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);//ASSEGNAZIONE PIN LCD
const int BACKLIGH_PIN = 10;//Assegnazione Retroilluminazione
DFR_Key keypad;
String keyString = "";
int localKey = 0; //Select-1;Left-2;Up-3;Down-4;Right-5;
const int ProdottaPin = A1;
const int AssorbitaPin = A2;
const int TensionePin = A3;
const int transmit_pin = 3;
const int receive_pin = 14;
const int transmit_en_pin = 15;
const int Uscita1 = 11;
const int Uscita2 = 12;
const int ADR=100;//Indirizzo PowerMeter
const int ResetPin = 2;//se posto a 1 resetta i contatori
const int PagPin = 2;//se premuto scorre le pagine
byte pagina = PagDefault; //PAGINA DA VISUALIZZARE SULL'LCD
byte monitor = 1; //Potenza da monitorare
int Timeout = TempoLed;//Timeout
int lcd_Time;
byte Tensione = 0;
byte Frequenza = 50;
unsigned long ProdottaMedia = 0;//Somma delle campionature
unsigned long AssorbitaMedia = 0;//Somma delle campionature
float ProdottaMediaP = 0;//Amper Prodotti
float AssorbitaMediaP = 0;//Amper Assorbiti
int PotenzaPro;//Potenza Prodotta (Amper Prodotti*Tensione)
int PotenzaAss;//Potenza Assorbita (Amper Assorbiti*Tensione)
int PotenzaMon;//Potenza da Monitorare
unsigned long time = 0;//Tempo dall'ultimo invio via radio
unsigned long Tmemoria = 0;//Tempo dall'ultimo BackUp
unsigned long TCampionature = 0;//Tempo dall'ultima Campionatura
float TotProdotta = 0;//Contatore Totale Prodotta
float TotAssorbita = 0;//Contatore Totale Assorbita
int Uscita_1_ON ;
int Uscita_1_Time ;
unsigned long TUscita1 = 0;
int Uscita_1_OFF ;
int Uscita_2_ON ;
int Uscita_2_Time;
unsigned long TUscita2 = 0;
int Uscita_2_OFF;
void setup() {
ADCSRA&=0X90+0b100;
Serial.begin(9600);
keypad.setRate(50);
vw_set_tx_pin(transmit_pin);
vw_set_rx_pin(receive_pin);
vw_set_ptt_pin(transmit_en_pin);
vw_set_ptt_inverted(true);
vw_setup(2000);
pinMode(Uscita1, OUTPUT);
digitalWrite(Uscita1,LOW);
pinMode(Uscita2, OUTPUT);
digitalWrite(Uscita2,LOW);
pinMode(ResetPin, INPUT);
lcd.begin(16, 2);
pinMode(BACKLIGH_PIN, OUTPUT);
digitalWrite(BACKLIGH_PIN, HIGH);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("PowerMeter V3.5 By");
lcd.setCursor(0,1);
lcd.print("ElettroshockNow");
delay(2000);
//recupero dati contatori dal BackUp
monitor=EEPROM.read(0x0F);
unsigned char k,mem;
for (k=0;k<4;k++){
mem = EEPROM.read(0x00+k);
((unsigned char*) &TotProdotta)[k]=mem;
}
for (k=0;k<4;k++){
mem = EEPROM.read(0x05+k);
((unsigned char*) &TotAssorbita)[k]=mem;
}
for (k=0;k<2;k++){
mem = EEPROM.read(0x10+k);
((unsigned char*) &Uscita_1_ON)[k]=mem;
}
for (k=0;k<2;k++){
mem = EEPROM.read(0x12+k);
((unsigned char*) &Uscita_1_Time)[k]=mem;
}
for (k=0;k<2;k++){
mem = EEPROM.read(0x14+k);
((unsigned char*) &Uscita_1_OFF)[k]=mem;
}
for (k=0;k<2;k++){
mem = EEPROM.read(0x20+k);
((unsigned char*) &Uscita_2_ON)[k]=mem;
}
for (k=0;k<2;k++){
mem = EEPROM.read(0x22+k);
((unsigned char*) &Uscita_2_Time)[k]=mem;
}
for (k=0;k<2;k++){
mem = EEPROM.read(0x24+k);
((unsigned char*) &Uscita_2_OFF)[k]=mem;
}
if (digitalRead(ResetPin) == HIGH) {//se premuto Resetta i contatori
monitor = 1;
TotProdotta = 0;
TotAssorbita = 0;
Uscita_1_ON = 1000;
Uscita_1_Time = 10;
Uscita_1_OFF = 500;
Uscita_2_ON = 1200;
Uscita_2_Time = 600;
Uscita_2_OFF = 800;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("ATTENZIONE RESET");
lcd.setCursor(0,1);
lcd.print("CONTATORI TRA 4H");
delay(5000);
}
}
void loop() {
//-----------------------------------------------------------------
//MISURA I SENSORI E CALCOLA LE CORRENTI E LE POTENZE E LA TENSIONE
int Tensionepicco = 0;
ProdottaMedia = 0 ;
AssorbitaMedia = 0 ;
for (int i=0;i<1000;i++){
ProdottaMedia += abs(analogRead(ProdottaPin)-510);
AssorbitaMedia += abs(analogRead(AssorbitaPin)-510);
int Tensioneinst = analogRead(TensionePin);
if (Tensionepicco<Tensioneinst)Tensionepicco=Tensioneinst;
}
Tensione=Tensionepicco*.45;//Taratura sensore Tensione
ProdottaMediaP= (ProdottaMedia*.000079)-0.032;//calcola gli Amper istantanei Prodotti
AssorbitaMediaP= (AssorbitaMedia*.000079)-0.032;//calcola gli Amper istantanei Assorbiti
if (ConfigB & AssorbitaMediaP > 0.2)ProdottaMediaP=0;
PotenzaPro=int(ProdottaMediaP*Tensione/10)*10;//Calcola Potenza istantanea Prodotta (Step da 10W)
PotenzaAss=int(AssorbitaMediaP*Tensione/10)*10;//Calcola Potenza istantanea Assorbita (Step da 10W)
//Calcola e memorizza in EEPROM i Contatori Potenze
if (micros()>TCampionature){// if è per prevenire il reset del contatore ogni 70ore!!
TotProdotta+=ProdottaMediaP*Tensione*(micros()-TCampionature)/1000000/3600/1000;//Calcola i Kwh Prodotti
TotAssorbita+=AssorbitaMediaP*Tensione*(micros()-TCampionature)/1000000/3600/1000;//Calcola i Kwh Consumati
}
TCampionature=micros();
if (millis()>(Tmemoria + 14400000)){//BackUp ogni 4 ore= 14400000mS
EEPROM.write(0x0F,monitor);
unsigned char k,mem;
for (k=0;k<4;k++){
mem = ((unsigned char*) &TotProdotta)[k];
EEPROM.write(0x00+k,mem);
}
for (k=0;k<4;k++){
mem = ((unsigned char*) &TotAssorbita)[k];
EEPROM.write(0x05+k,mem);
}
for (k=0;k<2;k++){
mem = ((unsigned char*) &Uscita_1_ON)[k];
EEPROM.write(0x10+k,mem);
}
for (k=0;k<2;k++){
mem = ((unsigned char*) &Uscita_1_Time)[k];
EEPROM.write(0x12+k,mem);
}
for (k=0;k<2;k++){
mem = ((unsigned char*) &Uscita_1_OFF)[k];
EEPROM.write(0x14+k,mem);
}
for (k=0;k<2;k++){
mem = ((unsigned char*) &Uscita_2_ON)[k];
EEPROM.write(0x20+k,mem);
}
for (k=0;k<2;k++){
mem = ((unsigned char*) &Uscita_2_Time)[k];
EEPROM.write(0x22+k,mem);
}
for (k=0;k<2;k++){
mem = ((unsigned char*) &Uscita_2_OFF)[k];
EEPROM.write(0x24+k,mem);
}
Tmemoria=millis();
}
//---------------------------------------------------------------
//VISUALIZZA E SPENGE IL DISPLAY SE NON USATO
if (digitalRead(PagPin) == HIGH & Timeout<=0){
digitalWrite(BACKLIGH_PIN, HIGH);//accendi LCD
Timeout=TempoLed;
delay(1000);
}
if (Timeout>0) {
digitalWrite(BACKLIGH_PIN, HIGH);//accendi LCD
if (Retroilluminazione)Timeout--;
if (digitalRead(PagPin) == HIGH){
pagina++;
if (pagina>10)pagina=0;
}
localKey=keypad.getKey();
if (pagina<10&localKey==3) pagina++;
if (pagina>0&localKey==4) pagina--;
if (pagina==4&&localKey==5&&monitor<4) monitor++;
if (pagina==4&&localKey==2&&monitor>1) monitor--;
if (pagina==5&localKey==5) Uscita_1_ON=Uscita_1_ON+10;
if (pagina==5&localKey==2) Uscita_1_ON=Uscita_1_ON-10;
if (pagina==6&localKey==5) Uscita_1_Time=Uscita_1_Time+5;
if (pagina==6&localKey==2) Uscita_1_Time=Uscita_1_Time-5;
if (pagina==7&localKey==5) Uscita_1_OFF=Uscita_1_OFF+10;
if (pagina==7&localKey==2) Uscita_1_OFF=Uscita_1_OFF-10;
if (pagina==8&localKey==5) Uscita_2_ON=Uscita_2_ON+10;
if (pagina==8&localKey==2) Uscita_2_ON=Uscita_2_ON-10;
if (pagina==9&localKey==5) Uscita_2_Time=Uscita_2_Time+5;
if (pagina==9&localKey==2) Uscita_2_Time=Uscita_2_Time-5;
if (pagina==10&localKey==5) Uscita_2_OFF=Uscita_2_OFF+10;
if (pagina==10&localKey==2) Uscita_2_OFF=Uscita_2_OFF-10;
switch (monitor){ //Seleziona la Potenza da Monitorare
case 1:
PotenzaMon=PotenzaPro;
break;
case 2:
PotenzaMon=PotenzaAss;
break;
case 3:
PotenzaMon=PotenzaPro-PotenzaAss;
break;
case 4:
PotenzaMon=PotenzaAss-PotenzaPro;
break;
}
if (PotenzaMon<Uscita_1_ON) TUscita1=millis();
else if (millis()>(Uscita_1_Time*1000+TUscita1)) digitalWrite(Uscita1,HIGH);
if (PotenzaMon<Uscita_1_OFF) digitalWrite(Uscita1,LOW);
if (PotenzaMon<Uscita_2_ON) TUscita2=millis();
else if (millis()>(Uscita_2_Time*1000+TUscita2)) digitalWrite(Uscita2,HIGH);
if (PotenzaMon<Uscita_2_OFF) digitalWrite(Uscita2,LOW);
if((millis()>(lcd_Time+1000))||(pagina>3)){
lcd_Time = millis();
switch (pagina){
case 0 :
lcd.setCursor(0, 0);
lcd.print ("Assorbita= ");
lcd.print (PotenzaAss);
lcd.print ("W ");
lcd.setCursor(0,1);
lcd.print ("Prodotta = ");
lcd.print (PotenzaPro);
lcd.print ("W ");
break;
case 1 :
lcd.setCursor(0, 0);
lcd.print ("Tensione= ");
lcd.print (Tensione);
lcd.print ("V ");
lcd.setCursor(0,1);
if(ConfigB){
lcd.print ("Stato UPS=");
if (AssorbitaMediaP > 0.2) lcd.print ("STBY ");
else lcd.print ("ACTIVE ");
}
else lcd.print ("----------------");
break;
case 2 :
lcd.setCursor(0, 0);
lcd.print ("CorrenteA= ");
lcd.print (AssorbitaMediaP,2);
lcd.print ("A ");
lcd.setCursor(0,1);
lcd.print ("CorrenteP= ");
lcd.print (ProdottaMediaP,2);
lcd.print ("A ");
break;
case 3 :
lcd.setCursor(0, 0);
lcd.print ("TotA= ");
lcd.print (TotAssorbita,1);
lcd.print ("Kwh ");
lcd.setCursor(0,1);
lcd.print ("TotP= ");
lcd.print (TotProdotta,1);
lcd.print ("Kwh ");
break;
case 4 :
lcd.setCursor(0, 0);
lcd.print ("<< Monitorare >> ");
lcd.setCursor(0,1);
switch (monitor){
case 1:
lcd.print ("Pot. Prodotta ");
break;
case 2:
lcd.print ("Pot. Assorbita ");
break;
case 3:
lcd.print ("Prod. - Assorb. ");
break;
case 4:
lcd.print ("Assorb. - Prod. ");
break;
}
break;
case 5 :
lcd.setCursor(0, 0);
lcd.print ("Soglia Uscita 1 ");
lcd.setCursor(15, 0);
if (digitalRead(Uscita1))lcd.print("*");
lcd.setCursor(0,1);
lcd.print ("- ON=");
lcd.print (Uscita_1_ON);
lcd.print ("Watt ");
lcd.setCursor(15,1);
lcd.print ("+");
break;
case 6 :
lcd.setCursor(0, 0);
lcd.print ("Soglia Uscita 1 ");
lcd.setCursor(15, 0);
if (digitalRead(Uscita1))lcd.print("*");
lcd.setCursor(0,1);
lcd.print ("- TEMPO=");
lcd.print (Uscita_1_Time);
lcd.print ("Sec ");
lcd.setCursor(15,1);
lcd.print ("+");
break;
case 7 :
lcd.setCursor(0, 0);
lcd.print ("Soglia Uscita 1 ");
lcd.setCursor(15, 0);
if (digitalRead(Uscita1))lcd.print("*");
lcd.setCursor(0,1);
lcd.print ("- OFF=");
lcd.print (Uscita_1_OFF);
lcd.print ("Watt ");
lcd.setCursor(15,1);
lcd.print ("+");
break;
case 8 :
lcd.setCursor(0, 0);
lcd.print ("Soglia Uscita 2 ");
lcd.setCursor(15, 0);
if (digitalRead(Uscita2))lcd.print("*");
lcd.setCursor(0,1);
lcd.print ("- ON=");
lcd.print (Uscita_2_ON);
lcd.print ("Watt ");
lcd.setCursor(15,1);
lcd.print ("+");
break;
case 9 :
lcd.setCursor(0, 0);
lcd.print ("Soglia Uscita 2 ");
lcd.setCursor(15, 0);
if (digitalRead(Uscita2))lcd.print("*");
lcd.setCursor(0,1);
lcd.print ("- TEMPO=");
lcd.print (Uscita_2_Time);
lcd.print ("Sec ");
lcd.setCursor(15,1);
lcd.print ("+");
break;
case 10 :
lcd.setCursor(0, 0);
lcd.print ("Soglia Uscita 2 ");
lcd.setCursor(15, 0);
if (digitalRead(Uscita2))lcd.print("*");
lcd.setCursor(0,1);
lcd.print ("- OFF=");
lcd.print (Uscita_2_OFF);
lcd.print ("Watt ");
lcd.setCursor(15,1);
lcd.print ("+");
break;
}
}
}
else {
digitalWrite(BACKLIGH_PIN, LOW);//Spenge LCD
pagina=PagDefault;//imposta la pagina default
}
/*
Serial.write ("Tensione= ");
Serial.println(Tensione);
Serial.write ("Frequenza= ");
Serial.println(Frequenza);
Serial.write ("Amper RMS assorbiti= ");
Serial.println(AssorbitaMediaP);
Serial.write ("Amper RMS Prodotti= ");
Serial.println(ProdottaMediaP);
Serial.write ("Potenza assorbita= ");
Serial.println(PotenzaAss);
Serial.write ("Potenza Prodotta= ");
Serial.println(PotenzaPro);
Serial.write ("Totale consumata= ");
Serial.println(TotAssorbita);
Serial.write ("Totale Prodotta= ");
Serial.println(TotProdotta);
Serial.write ("Taratura Sensore Assorbita= ");
Serial.println(AssorbitaMedia);
Serial.write ("Taratura Sensore Prodotta= ");
Serial.println(ProdottaMedia);
*/
//TRASMETTI DATI OGNI 15 SECONDI OPPURE IMMEDIATAMENTE SE LA POTENZA PRODOTTA
//E' PROSSIMA ALLA POTENZA ASSORBITA
if (ProdottaMediaP != 0 && (ProdottaMediaP > (AssorbitaMediaP - 0.30)) && ConfigB==false || millis() > (time + 15000)){
time = millis();
byte Pro1 = PotenzaPro&0xFF;
byte Pro2=(PotenzaPro&0xFF00)>>8;
byte Ass1=PotenzaAss&0xFF;
byte Ass2=(PotenzaAss&0xFF00)>>8;
byte CPro1= int(ProdottaMediaP*100)&0xFF;
byte CPro2= (int(ProdottaMediaP*100)&0xFF00)>>8;
byte CAss1= int(AssorbitaMediaP*100)&0xFF;
byte CAss2= (int(AssorbitaMediaP*100)&0xFF00)>>8;
byte TPro1= long(TotProdotta*10)&0xFF;
byte TPro2= (long(TotProdotta*10)&0xFF00)>>8;
byte TPro3= (long(TotProdotta*10)&0xFF0000)>>16;
byte TAss1= long(TotAssorbita*10)&0xFF;
byte TAss2= (long(TotAssorbita*10)&0xFF00)>>8;
byte TAss3= (long(TotAssorbita*10)&0xFF0000)>>16;
byte CKS = (ADR+Tensione+Pro1+Pro2+Ass1+Ass2+CPro1+CPro2+CAss1+CAss2+TPro1+TPro2+TPro3+TAss1+TAss2+TAss3)/16;
char msg[17] = {ADR,Tensione,Pro1,Pro2,Ass1,Ass2,CPro1,CPro2,CAss1,CAss2,TPro1,TPro2,TPro3,TAss1,TAss2,TAss3,CKS};
digitalWrite(13, true); // Flash a light to show transmitting
vw_send((uint8_t *)msg, 17 );
vw_wait_tx(); // Wait until the whole message is gone
digitalWrite(13, false);
}
}