PowerMeterRx 4.0
Ecco il codice e lo schema!
/* Progetto PowerPowerMeterRx 4.0
***Ricevitore***
"" Energia Alternativa & Energia Fai Da Te ""
http://www.energialternativa.org/ Ricevitore rivisitato da Supermomo717 del PowerMeter_3_5 realizzato da ElettroshockNow.
Si tratta di un sistema remoto per Trasmettitore Powermeter 4.0 per gestione di 2 uscite.
Il Ricevitore Powermeter 4.0 rielabora i valori ricevuti dal Trasmettitore PowerMeter 4.0
e ne gestisce i carichi, collegati.
Caratteristiche:
- Introdotto Display Lcd con keypad per modifica diretta delle soglie intervento uscite.
- Introdotto avviso ricezione segnale da TX direttamente da LCD.
- Introdotto intervallo di tempo antecedente lo spegnimento a raggiungimento una determinata
soglia minima (per ovviare al problema che un carico in avvio possa far leggere al
Ricevitore un raggiungimento di sottosoglia e staccare
l'uscita al momento in cui il carico stesso dovrebbe avviarsi).
- Il display si spegne automaticamente dopo 2 minuti se la produzione dell'impianto è
minore dell'assorbimento. Per Accendere il display premere pulsante scorrimento pagine.
- Introdotto LED esterno per controllo ricezione corretta segnale da TX
- Introdotte nuove visualizzazioni pagine con diverse combinazioni di potenze monitorabili
Necessario funzionamento in abbinamento a PowerMeterTx 4.0 ***Trasmettitore***
Per tutte le connessioni fare riferimento solo allo Sketch.
Saluti
Supermomo717
*/
#include <LiquidCrystal.h>
#include <VirtualWire.h>
const byte PagDefault = 1; // Scegli la schermata di default..
//0 = Wattmetro
//1 = Voltmetro + Stato sistema (immissione o prelievo).
//2 = Amperometro
//3 = Contatori
byte pagina = PagDefault; //PAGINA DA VISUALIZZARE SULL'LCD
const int PagPin = 2;//Pulsante normalmente chiuso, se premuto scorre le pagine
const int Uscita2 = 3; //assegnazione pin uscita 2
const int Uscita1 = 12; //assegnazione pin uscita 1
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);//ASSEGNAZIONE PIN LCD SHIELD SAINSMART
const int BACKLIGH_PIN = 10;//Assegnazione pin Retroilluminazione
unsigned long StandBy; // Tempo StandBy display LCD
//pin 11 assegnato a ricevitore
const int ledPin = 13; //pin del led per controllo ricezione segnale da TX
unsigned long lcd_Time;
int ledState = LOW; // ledState usato per settare lo stato del led
long previousMillis = 0; //conteggio durata impulso led verifica segnale
long interval = 100; //durata impulso led
byte monitor = 1;
// impostazioni uscite
int Uscita_1_ON ;
int Uscita_1_Time_On ;
int Uscita_1_Time_Off ;
unsigned long TUscita1in = 0;
unsigned long TUscita1out = 0;
int Uscita_1_OFF ;
int Uscita_2_ON ;
int Uscita_2_Time_On;
int Uscita_2_Time_Off ;
unsigned long TUscita2in = 0;
unsigned long TUscita2out = 0;
int Uscita_2_OFF;
int PotenzaMon; //Potenza da Monitorare
int Tensione;
int PotenzaPro;
int PotenzaPro2;
int PotenzaAss;
float CorrentePro;
float CorrentePro2;
float CorrenteAss;
float TotalePro;
float TotalePro2;
float TotaleAss;
//impostazioni relative alla Tastiera della shield
int lcd_key = 0;
int adc_key_in = 0;
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
// read the buttons
int read_LCD_buttons()
{
adc_key_in = analogRead(0); // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 150) return btnUP;
if (adc_key_in < 280) return btnDOWN;
if (adc_key_in < 450) return btnLEFT;
if (adc_key_in < 650) return btnSELECT;
return btnNONE; // when all others fail, return this...
}
void setup()
{
lcd.begin(16, 2);
pinMode(BACKLIGH_PIN, OUTPUT);
digitalWrite(BACKLIGH_PIN, HIGH);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("RicePwMeter V4.0");
lcd.setCursor(0,1);
lcd.print("By Supermomo717");
delay(3000);
//Settaggio porte uscite
pinMode(Uscita1, OUTPUT);
digitalWrite(Uscita1, LOW);
pinMode(Uscita2, OUTPUT);
digitalWrite(Uscita2, LOW);
pinMode(ledPin, OUTPUT);
monitor = 3; // DEFAULT Potenza da monitorare
//1 = Totale Prodotta (GSE+ EXTRA)
//2 = Totale Assorbita
//3 = Totale Prodotta - Assorbita
//4 = Assorbita - Totale Prodotta
//5 = Esubero = EXTRA - Assorbita
//6 = GSE
//7 = EXTRA
Uscita_1_ON = 800; //Accendi a XXX Watt ** Variabile da tastiera **
Uscita_1_Time_On = 10; //Accendi dopo TOT secondi raggiunti XXX Watt ** Variabile da tastiera **
Uscita_1_Time_Off = 10; //Spegni dopo TOT secondi raggiunti YYY Watt NON Variabile da tastiera
Uscita_1_OFF = 100; //Spegni a YYY Watt ** Variabile da tastiera **
Uscita_2_ON = 1800; //Accendi a xxx Watt ** Variabile da tastiera **
Uscita_2_Time_On = 10; //Accendi dopo tot secondi raggiunti xxx Watt ** Variabile da tastiera **
Uscita_2_Time_Off = 10; //Spegni dopo tot secondi raggiunti yyy Watt NON Variabile da tastiera
Uscita_2_OFF = 1700 ; //Spegni a yyy Watt
Serial.begin(9600); // Debugging only
Serial.println("Inizializzazione");
// Initialise the IO and ISR
vw_set_ptt_inverted(true); // Required for DR3100
vw_setup(2000); // Bits per sec
vw_rx_start(); // Start the receiver PLL running
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
{
// parte relativa al lampeggio del led di controllo quando RX ha segnale da TX
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState); // originale è ledPin per lampeggio led 13 su Arduino
}
/*
int i;
digitalWrite(13, true); // Flash a light to show received good message
// Message with a good checksum received, dump it.
Serial.print("Got: ");
for (i = 0; i < buflen; i++)
{
Serial.print(buf[i], DEC);
Serial.print(" ");
}
*/
Tensione = buf[1];
PotenzaPro = (int(buf[3]<<8)+buf[2]);
PotenzaPro2 = (int(buf[5]<<8)+buf[4]);
PotenzaAss = (int(buf[7]<<8)+buf[6]);
CorrentePro = float(int(buf[9]<<8)+buf[8])/100;
CorrenteAss = float(int(buf[11]<<8)+buf[10])/100;
TotalePro = float(long(buf[14]<<16)+int(buf[13]<<8)+buf[12])/10; //Prodotta GSE
TotaleAss = float(long(buf[17]<<16)+int(buf[16]<<8)+buf[15])/10; //Cosnumata
TotalePro2= float(long(buf[20]<<16)+int(buf[19]<<8)+buf[18])/10; //Prodotta Extra
Serial.write ("Potenza GSE ");
Serial.print(PotenzaPro);
Serial.println (" Watt");
Serial.write ("Potenza EXTRA ");
Serial.print(PotenzaPro2);
Serial.println (" Watt");
Serial.write ("Potenza Prodotta TOTALE ");
Serial.print(PotenzaPro+PotenzaPro2);
Serial.println (" Watt");
Serial.write ("Potenza Assorbita di ");
Serial.print(PotenzaAss);
Serial.println (" Watt");
Serial.write ("Immetto in rete una Potenza di ");
Serial.print(PotenzaMon);
Serial.println (" Watt");
Serial.write ("Accensione Uscita 1 Impostata a ");
Serial.print(Uscita_1_ON);
Serial.println("Watt");
Serial.write ("Spegnimento Uscita 1 Impostata= ");
Serial.print(Uscita_1_OFF);
Serial.println("Watt");
Serial.write ("Accensione Uscita 2 Impostata a ");
Serial.print(Uscita_2_ON);
Serial.println("Watt");
Serial.write ("Spegnimento Uscita 2 Impostata= ");
Serial.print(Uscita_2_OFF);
Serial.println("Watt");
Serial.write ("Totale Prodotta GSE= ");
Serial.print(TotalePro);
Serial.println(" Kwh");
Serial.write ("Totale Prodotta EXTRA= ");
Serial.print(TotalePro2);
Serial.println(" Kwh");
Serial.write ("Totale Consumata= ");
Serial.print(TotaleAss);
Serial.println(" Kwh");
Serial.println("");
}
switch (monitor){ //Selettore potenza da monitorare
case 1:
PotenzaMon=PotenzaPro+PotenzaPro2; //potenza totale
break;
case 2:
PotenzaMon=PotenzaAss; //potenza Assorbita
break;
case 3:
PotenzaMon=PotenzaPro+PotenzaPro2-PotenzaAss; //potenza Prodotta - potenza Assorbita
break;
case 4:
PotenzaMon=PotenzaAss-PotenzaPro-PotenzaPro2; //potenza Assorbita - potenza Prodotta
break;
case 5:
PotenzaMon=PotenzaPro2-PotenzaAss; //Potenza in Esubero
break;
case 6:
PotenzaMon=PotenzaPro; //potenza GSE
break;
case 7:
PotenzaMon=PotenzaPro2; //potenza EXTRA
break;
}
if (PotenzaMon<Uscita_1_ON) TUscita1in=millis();
else if (millis()>(Uscita_1_Time_On*1000+TUscita1in)) digitalWrite(Uscita1,LOW);
if (PotenzaMon>Uscita_1_OFF) TUscita1out=millis();
else if (millis()>(Uscita_1_Time_Off*1000+TUscita1out)) digitalWrite(Uscita1,HIGH);
if (PotenzaMon<Uscita_2_ON) TUscita2in=millis();
else if (millis()>(Uscita_2_Time_On*1000+TUscita2in)) digitalWrite(Uscita2,LOW);
if (PotenzaMon>Uscita_2_OFF) TUscita2out=millis();
else if (millis()>(Uscita_2_Time_Off*1000+TUscita2out)) digitalWrite(Uscita2,HIGH);
if ((digitalRead(PagPin) == LOW) && digitalRead (BACKLIGH_PIN == LOW)) // Prima pressione pulsante accende display
{
digitalWrite(BACKLIGH_PIN, HIGH);
StandBy=millis();
delay(200);
}
if (digitalRead(PagPin) == LOW) // Pressione pulsante per cambio pagina
{
pagina++;
StandBy=millis();
delay(200);
if (pagina>11)pagina=0;
}
if ((millis() > StandBy+120000) && (PotenzaPro+PotenzaPro2)-PotenzaAss <0) digitalWrite(BACKLIGH_PIN, LOW); //Spegne display se non usato dopo 120 secondi
lcd_key = read_LCD_buttons(); // read the buttons
if (pagina<11&lcd_key==btnDOWN) {
pagina++;
delay(200);
}
if (pagina>0&lcd_key==btnUP) {
pagina--;
delay(200);
}
if (pagina==4&&lcd_key==btnRIGHT&&monitor<7) {
monitor++;
delay(200);
}
if (pagina==4&&lcd_key==btnLEFT&&monitor>1) {
monitor--;
delay(200);
}
if (pagina==5&lcd_key==btnRIGHT) Uscita_1_ON=Uscita_1_ON+1;
if (pagina==5&lcd_key==btnLEFT) Uscita_1_ON=Uscita_1_ON-1;
if (pagina==6&lcd_key==btnRIGHT) Uscita_1_Time_On=Uscita_1_Time_On+1;
if (pagina==6&lcd_key==btnLEFT) Uscita_1_Time_On=Uscita_1_Time_On-1;
if (pagina==7&lcd_key==btnRIGHT) Uscita_1_OFF=Uscita_1_OFF+1;
if (pagina==7&lcd_key==btnLEFT) Uscita_1_OFF=Uscita_1_OFF-1;
if (pagina==8&lcd_key==btnRIGHT) Uscita_2_ON=Uscita_2_ON+1;
if (pagina==8&lcd_key==btnLEFT) Uscita_2_ON=Uscita_2_ON-1;
if (pagina==9&lcd_key==btnRIGHT) Uscita_2_Time_On=Uscita_2_Time_On+1;
if (pagina==9&lcd_key==btnLEFT) Uscita_2_Time_On=Uscita_2_Time_On-1;
if (pagina==10&lcd_key==btnRIGHT) Uscita_2_OFF=Uscita_2_OFF+1;
if (pagina==10&lcd_key==btnLEFT) Uscita_2_OFF=Uscita_2_OFF-1;
if((millis()>(lcd_Time+500))