Power Controller: controllo consumi elettrici di un'utenza domestica

VISUALIZZAZIONE A DISPLAY

Con riferimento ai collegamenti mostrati in Fig.4, di seguito si può trovare il codice per la misura in linea di tensione e potenza assorbita, visualizzabile con il Display 128 x 64 pixel.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
constexpr uint8_t Sync = 2;
int sensorValue;
int cyccnt = 0;
byte stcur = 1; // stato corrente di fase
int Volt_pin = A0;
int MaxVolt = 0;
long MedVolt = 0;
double Volt;
int DeVolt;
int Amp2_pin=A2; // corrente assorbita
int MinAmp2 = 1023;
int MaxAmp2 = 0;
long MedAmp2 = 0;
double Amp2 = 0;
int DeAmp2;
byte MaxVerso2;
byte AMax2 = 0;
unsigned int WattSec2;
void setup()
{
  pinMode(Sync, INPUT);
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(WHITE);  
  while(digitalRead(Sync) == LOW){} // Attende di sincronizzarsi alla fase positiva
}
void loop()
{
  if(stcur == 0){
    if (digitalRead(Sync) == HIGH){ // Registra la transizione a fase positiva
      stcur = 1; // fase positiva diventa la fase corrente
      cyccnt = cyccnt  + 1; // conta il numero di cicli
      DeVolt = MaxVolt;     
      MedVolt = MedVolt + DeVolt;
      DeAmp2 = MaxAmp2 - MinAmp2; 
      MedAmp2 = MedAmp2 + DeAmp2; 
      AMax2 = AMax2 + MaxVerso2;                
      MaxVolt = 0;
      MinAmp2 = 1023;
      MaxAmp2 = 0;      
      if(cyccnt == 48){ // Ha effettuato medie per un secondo
        MedVolt = MedVolt + 2*DeVolt;
        MedAmp2 = MedAmp2 + 2*DeAmp2;  
        Volt = 0.004711*double(MedVolt) + 35;  // taratura corrente
        Amp2 = 0.0010255*double(MedAmp2) - 0.045;  // taratura corrente
        WattSec2 = int((Volt*Amp2) + 0.5);  
        display.clearDisplay();   
        display.setCursor(0,0);              
        display.print("V");
        display.println(int(Volt + 0.5));            
        if(AMax2 < 25) display.print(" -");
        else display.print(" +");        
        display.print("C");      
        display.println(WattSec2);
        MedVolt = 0;
        MedAmp2 = 0;
        AMax2 = 0;      
        cyccnt = 0;               
        while(digitalRead(Sync) == LOW){ // Risincronizzazione 
        } 
        stcur = 1;
      }
    }
  }    
  else {
    if (digitalRead(Sync) == 0){
      stcur = 0;
    }
  }  
  sensorValue = analogRead(Volt_pin);
  if(sensorValue>MaxVolt) MaxVolt=sensorValue;    
  sensorValue = analogRead(Amp2_pin);
  if(sensorValue
  if(sensorValue>MaxAmp2) {
    MaxAmp2=sensorValue;
    MaxVerso2 = stcur;      
  }
}

Per l'installazione delle librerie di gestione del display, si rimanda all'ottimo link: Installazione Display 128x64 IC2
Da notare che la gestione del display consuma circa 30 msec di tempo macchina, cioè circa 2 cicli di oscillazione delle rete. Per evitare di perdere di sincronismo nelle misure, si è scelto di eseguire le misure su 48 cicli e stimare le due successive misure, replicando due volte il risultato della 48sima misura. In questo modo si produce una misura esattamente ogni secondo (naturalmente entro la precisione di variazione della frequenza di rete).

Progetto connesso: Misura produzione/consumo di un impianto fotovoltaico.