Allego attuale sketch:
CITAZIONE Quote://Includo la libreria per il corretto funzionamento del display
#include <LiquidCrystal.h>
// Dichiaro i pin del display
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// Dichiaro il pin a cui sono collegati i bottoni e la variabile in cui viene memorizzato il valore letto dal pin
int buttonPin = A0;
int buttonValue = 0;
//Dichiaro il pin del sensore di corrente, la variabile in cui sarà memorizzato il valore letto dal sensore e una variabile per il test del sensore
int sensorPin = A5;
float sensorValue = 0.00;
int sensorTest = 0;
//Dichiaro il valore dell'offset, ovvero il valore letto da arduino sulla porta del sensore in assenza di carico
#define sensorOffset 510
//Dichiaro le variabili in cui sarà memorizzato il valore di ampere totali assorbiti ed il numero di letture effettuate
float ampere = 0.00;
int numeroCampionamenti = 0;
long inizioCampionamenti = 0;
//Dichiaro la variabile della tensione stabilita a 230V
float tensione = 230.00;
//Dichiaro la variabile per il calcolo del consumo in watt
int consumo = 0;
//Dichiaro i pin del buzzer, dei led e dei relè
int buzzer = 6;
int verde1 = 7;
int verde2 = 8;
int rosso1 = 1;
int rosso2 = 13;
int bagni = 9;
int stanze = 10;
//Dichiaro variabili per memorizzare lo stato (0 o 1) dei relè e dei bottoni
int rele1 = 0;
int rele2 = 0;
int buttonState = 0;
//Variabili per prevenire ritardi ai pulsanti e regolare il refresh del display
#define intervallcd 3000
unsigned long previousMillslcd = 0;
#define interval1 2000
unsigned long previousMills1 = 0;
#define interval2 2000
unsigned long previousMills2 = 0;
void setup() {
//Setta ADC prescaler a 16 Mhz cambiando quindi la velocita delle letture analogiche
ADCSRA&=0X90+ 0b100;
//Definisco la porta seriale per leggere dati dal monitor seriale. NB: causa l'accensione del led sul PIN 1
//Serial.begin(9600);
//Inizializzo il display
lcd.begin(16, 2);
//Imposto i pin dei led, del buzzer e dei relè come uscite digitali
pinMode(verde1, OUTPUT);
pinMode(verde2, OUTPUT);
pinMode(rosso1, OUTPUT);
pinMode(rosso2, OUTPUT);
pinMode(bagni, OUTPUT);
pinMode(stanze, OUTPUT);
pinMode(buzzer, OUTPUT);
//Accendo i due led verdi e tengo spenti i due rossi
digitalWrite(verde1, HIGH);
digitalWrite(verde2, HIGH);
digitalWrite(rosso1, LOW);
digitalWrite(rosso2, LOW);
//I relè sono normalmente chiusi e con HIGH la bobina non viene eccitata
digitalWrite(bagni, HIGH);
digitalWrite(stanze, HIGH);
}
void loop() {
//Eseguo solo una volta all'accensione delle letture a vuoto per l'assestamento dei valori ottenuti dal sensore di corrente
if (sensorTest == 0) {
do {
sensorValue = analogRead(sensorPin);
lcd.setCursor(0,0);
lcd.print("Check in corso...");
lcd.setCursor(0,1);
//Calcolo e scrivo una percentuale sul display in relazione alla seguente equazione
//sensorOffset : 100% = sensorValue : x %
sensorTest = (sensorValue / sensorOffset) * 100;
lcd.print(sensorTest);
lcd.print("% ");
//Riga utilizzata per leggere il valore senza carico in fase di programmazione
//lcd.print(sensorValue);
//Se il sensore legge prima dei 10 secondi il giusto valore di offset, accorcia l'attesa e parte con il vero loop
if (sensorValue == sensorOffset) {
lcd.clear();
break;
}
}
//Sono necessari circa 10 secondi affinchè l'alimentazione e i condensatori forniscano un valore stabile alla linea 5v usata dal sensore
while(millis() < 10000);
sensorTest = 1;
//Note di fine check e test funzionamento buzzer
tone(buzzer, 4699, 125);
delay(160);
noTone(buzzer);
tone(buzzer, 4699, 125);
delay(160);
noTone(buzzer);
}
//Lettura dati del sensore e calcolo della corrente assorbita e del consumo in watt
ampere = 0.00;
numeroCampionamenti = 0;
inizioCampionamenti = millis() ;
do
{
numeroCampionamenti++;
//sensorOffset è la lettura senza carico quindi l'offset e lo sottraiamo alle letture
sensorValue = (analogRead(sensorPin) - sensorOffset);
//Alcune letture potrebbero avere valore negativo per cui noi consideriamo il valore assoluto
ampere+= abs(sensorValue);
}
//20 sono i millisecondi che verranno campionati
while((millis() - inizioCampionamenti) < 20);
//Per ottenere gli ampere reali moltiplichiamo la media di ampere letti nei 20ms per 0.166 che è il fattore di conversione
ampere=(ampere / numeroCampionamenti) * 0.166;
//Infine moltiplichiamo gli ampere per la tensione stabilita per ottenere il consumo in Watt
consumo = ampere * tensione;
//Per evitare letture negative in assenza di carico
if (consumo < 0) consumo = 0;
//Lettura pin dei bottoni e azioni di distacco manuale o ripristino della corrente tramite i relè
buttonValue = analogRead(buttonPin);
if (millis() - previousMills1 > interval1 ) {
previousMills1 = millis();
//Codice che viene eseguito per il bottone relativo alla linea "bagni"
if ((buttonValue >= 150) && (buttonValue <= 200)) {
switch (rele1) {
//Se rele1 == 0 e viene premuto il bottone, bisogna accendere il relativo led rosso, spegnere il verde ed eccitare la bobina del relè
case 0:
//Il codice viene eseguito solo se il bottone nel precedente loop non era già premuto così da doverlo lasciare e ripremere per eseguire un'altra azione
if (buttonState == 0) {
digitalWrite(verde1, LOW);
digitalWrite(rosso1, HIGH);
digitalWrite(bagni, LOW);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Distacco manuale");
lcd.setCursor(0,1);
lcd.print("Linea 1 OFF");
analogWrite(buzzer, 20);
delay(1000);
analogWrite(buzzer, 0);
//Cambio lo stato del relè e specifico che il bottone è attualmente premuto
rele1 = 1;
buttonState = 1;
}
break;
//Se rele1 == 1 e viene premuto il bottone, bisogna accendere il relativo led verde, spegnere il rosso e diseccitare la bobina del relè
case 1:
//Il codice viene eseguito solo se il bottone nel precedente loop non era già premuto così da doverlo lasciare e ripremere per eseguire un'altra azione
if (buttonState == 0) {
digitalWrite(verde1, HIGH);
digitalWrite(rosso1, LOW);
digitalWrite(bagni, HIGH);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Intervento:");
lcd.setCursor(0,1);
lcd.print("Linea 1 ON");
tone(buzzer, 4699, 125);
delay(160);
noTone(buzzer);
tone(buzzer, 4699, 125);
delay(160);
noTone(buzzer);
//Resetto lo stato del relè e specifico che il bottone è attualmente premuto
rele1 = 0;
buttonState = 1;
}
break;
}
}
}
if (millis() - previousMills2 > interval2 ) {
previousMills2 = millis();
if ((buttonValue >= 800) && (buttonValue <= 900)) {
switch (rele2) {
//Se rele2 == 0 e viene premuto il bottone, bisogna accendere il relativo led rosso, spegnere il verde ed eccitare la bobina del relè
case 0:
//Il codice viene eseguito solo se il bottone nel precedente loop non era già premuto così da doverlo lasciare e ripremere per eseguire un'altra azione
if (buttonState == 0) {
digitalWrite(verde2, LOW);
digitalWrite(rosso2, HIGH);
digitalWrite(stanze, LOW);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Distacco manuale");
lcd.setCursor(0,1);
lcd.print("Linea 2 OFF");
analogWrite(buzzer, 20);
delay(1000);
analogWrite(buzzer, 0);
//Cambio lo stato del relè e specifico che il bottone è attualmente premuto
rele2 = 1;
buttonState = 1;
}
break;
//Se rele2 == 1 e viene premuto il bottone, bisogna accendere il relativo led verde, spegnere il rosso e diseccitare la bobina del relè
case 1:
//Il codice viene eseguito solo se il bottone nel precedente loop non era già premuto così da doverlo lasciare e ripremere per eseguire un'altra azione
if (buttonState == 0) {
digitalWrite(verde2, HIGH);
digitalWrite(rosso2, LOW);
digitalWrite(stanze, HIGH);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Intervento:");
lcd.setCursor(0,1);
lcd.print("Linea 2 ON");
tone(buzzer, 4699, 125);
delay(160);
noTone(buzzer);
tone(buzzer, 4699, 125);
delay(160);
noTone(buzzer);
//Resetto lo stato del relè e specifico che il bottone è attualmente premuto
rele2 = 0;
buttonState = 1;
}
break;
}
}
}
//Codice da eseguire ad ogni loop mentre nessun bottone è premuto per aggiornare lo stato delle linee ed il consumo in watt
if ((buttonValue >= 0) && (buttonValue <= 100)) {
if (millis() - previousMillslcd > intervallcd ) {
previousMillslcd = millis();
lcd.clear();
lcd.setCursor(0,1);
lcd.print("Watt: ");
lcd.setCursor(7,1);
lcd.print(consumo);
}
//In base allo stato delle variabili rele1 e rele2, scrivo sul display l'attuale stato delle linee
lcd.setCursor(0,0);
if ((rele1 == 0) && (rele2 == 0)) {
lcd.print("Linee ON");
}
if ((rele1 == 0) && (rele2 == 1)) {
lcd.print("L1 ON L2 OFF");
}
if ((rele1 == 1) && (rele2 == 0)) {
lcd.print("L1 OFF L2 ON");
}
if ((rele1 == 1) && (rele2 == 1)) {
lcd.print("Linee OFF");
}
//Specifico che nessun bottone è premuto così da rendere possibili gli interventi sulle linee
buttonState = 0;
}
}