Bene ho buttato giu il codice per gestire l'inverter sul pin di uscita pwm 9.
La logica è quella di controllare se la potenza acea è maggiore della potenza inverter e di incrementare il pwm se è vero altrimenti decrementa. Ho inserito un tempo di attesa dopo ogni regolazione per dare il tempo all'inverter di adeguarsi alla richiesta, ma in caso di decremento della potenza questo tempo diminuisce di 5 volte, per avere una reattività maggiore e non correre il rischio di immettere potenza in rete. In tutti i casi se la potenza acea fosse minore di 0 il pwm si porterebbe immediatamente a 0.
Ho aggiunto anche un tempo di refresh del display per evitare di visualizzare fluttuazioni sui valori.
Che ne dici può andare?
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);//ASSEGNAZIONE PIN LCD
const int BACKLIGH_PIN = 10;
const int INVERTER_PIN = 9;
int OffsetPin = A4;
int TensionePin = A1;
int CorrentePin_Acea = A2;
int CorrentePin_Inverter = A3;
int pwm = 0;
int Potenza_Delta = 10; // potenza di sicurezza massima tra l'acea e l'inverter in watt
float Fattore_Conversione_Tensione = 0.623; //da calcolare
float Fattore_Conversione_Corrente_Acea = 0.073; //da calcolare
float Fattore_Conversione_Corrente_Inverter = 0.073; //da calcolare
float TensioneRMS ;
float CorrenteRMS_Acea ;
float CorrenteRMS_Inverter ;
float PotenzaAttiva_Acea;
float PotenzaAttiva_Inverter;
float PotenzaApparente_Acea;
float PotenzaApparente_Inverter;
float FattorediPotenza_Acea;
float FattorediPotenza_Inverter;
float TensioneRMS_display ;
float CorrenteRMS_Acea_display ;
float CorrenteRMS_Inverter_display;
float PotenzaAttiva_Acea_display;
float PotenzaAttiva_Inverter_display;
unsigned int MediaLetture = 0;
unsigned int disp_refresh = 1000; //tempo di refresh del display
unsigned long ultimo_refresh = 0;//variabile di temporizzazione
unsigned long Ultima_Regolazione_Inverter;// variabile di temporizzazione
unsigned int Regolazione_Refresh = 250;//tempo di attesa prima del prossimo aumento di potenza dell'inverter
unsigned int Nuova_Regolazione_Refresh = Regolazione_Refresh;
void setup() {
//pinMode(BACKLIGH_PIN, OUTPUT);
//digitalWrite(BACKLIGH_PIN, HIGH);
Serial.begin(9600);
pinMode(INVERTER_PIN, OUTPUT);
analogWrite(INVERTER_PIN, pwm);
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("PowerMeter");
lcd.setCursor(0,1);
lcd.print("Enhanced");
delay(2000);
lcd.clear();
ADCSRA&=0X90+ 0b101; //Setta ADC prescaler a 32
}
void loop() {
float SommaV=0;
float SommaI_Acea=0;
float SommaI_Inverter=0;
float SommaP_Acea=0;
float SommaP_Inverter=0;
int NumCampionamenti = 0;
int Offset = analogRead(OffsetPin);
unsigned long start = micros();
while (micros() < (start + 20000)){
float Tensioneinst = (analogRead(TensionePin)-Offset)*Fattore_Conversione_Tensione;
float Correnteinst_Acea = (analogRead(CorrentePin_Acea)-Offset)*Fattore_Conversione_Corrente_Acea;
float Correnteinst_Inverter = (analogRead(CorrentePin_Inverter)-Offset)*Fattore_Conversione_Corrente_Inverter;
SommaV += pow(Tensioneinst,2);
SommaI_Acea += pow(Correnteinst_Acea,2);
SommaI_Inverter += pow(Correnteinst_Inverter,2);
SommaP_Acea += (Tensioneinst*Correnteinst_Acea);
SommaP_Inverter += (Tensioneinst*Correnteinst_Inverter);
NumCampionamenti++;
}
TensioneRMS = sqrt(SommaV / NumCampionamenti);
CorrenteRMS_Acea = sqrt(SommaI_Acea / NumCampionamenti);
CorrenteRMS_Inverter = sqrt(SommaI_Inverter / NumCampionamenti);
if (CorrenteRMS_Acea < 0.10) {//soglia minima
CorrenteRMS_Acea=0;
SommaP_Acea=0;}
if (CorrenteRMS_Inverter < 0.10) {//soglia minima
CorrenteRMS_Inverter=0;
SommaP_Inverter=0;}
PotenzaAttiva_Acea = SommaP_Acea/ NumCampionamenti;
PotenzaAttiva_Inverter = SommaP_Inverter/ NumCampionamenti;
PotenzaApparente_Acea = TensioneRMS * CorrenteRMS_Acea;
PotenzaApparente_Acea = TensioneRMS * CorrenteRMS_Acea;
FattorediPotenza_Acea = PotenzaAttiva_Acea/PotenzaApparente_Acea;
FattorediPotenza_Inverter = PotenzaAttiva_Inverter/PotenzaApparente_Inverter;
//blocco che pilota l'inverter
if(millis() - Ultima_Regolazione_Inverter >= Nuova_Regolazione_Refresh){
if(PotenzaAttiva_Acea > Potenza_Delta{
if(pwm < 255){
pwm++;
Nuova_Regolazione_Refresh = Regolazione_Refresh;
}
}else{
if(pwm > 0){
pwm--;
Nuova_Regolazione_Refresh = Regolazione_Refresh / 5;
}
}
Ultima_Regolazione_Inverter = millis();
}
if(PotenzaAttiva_Acea <= 0){
pwm = 0;
}
analogWrite(INVERTER_PIN, pwm);
/*debug
Serial.print(PotenzaAttiva_Acea);
Serial.print("----");
Serial.print(PotenzaAttiva_Inverter);
Serial.print("----");
Serial.println(pwm);
*/
//****************************
//visualizzo i dati sul display
if(millis() - ultimo_refresh <= disp_refresh){
TensioneRMS_display += TensioneRMS;
CorrenteRMS_Acea_display += CorrenteRMS_Acea;
CorrenteRMS_Inverter_display += CorrenteRMS_Inverter;
PotenzaAttiva_Acea_display += PotenzaAttiva_Acea;
PotenzaAttiva_Inverter_display += PotenzaAttiva_Inverter;
MediaLetture++;
}
else{
TensioneRMS_display = (TensioneRMS_display / MediaLetture);
CorrenteRMS_Acea_display = (CorrenteRMS_Acea_display / MediaLetture);
CorrenteRMS_Inverter_display = (CorrenteRMS_Inverter_display / MediaLetture);
PotenzaAttiva_Acea_display = (PotenzaAttiva_Acea_display / MediaLetture);
PotenzaAttiva_Inverter_display = (PotenzaAttiva_Inverter_display / MediaLetture);
lcd.setCursor(0, 0);
lcd.print(TensioneRMS_display,0);
lcd.print("V ");
lcd.setCursor(5, 0);
lcd.print(CorrenteRMS_Acea_display,1);
lcd.print("A ");
lcd.setCursor(11, 0);
lcd.print(CorrenteRMS_Inverter_display,1);
lcd.print("A ");
lcd.setCursor(0,1);
lcd.print(PotenzaAttiva_Acea_display,0);
lcd.print("W ");
lcd.setCursor(6,1);
lcd.print(PotenzaAttiva_Inverter_display,0);
lcd.print("W ");
lcd.setCursor(12,1);
lcd.print(FattorediPotenza_Acea,2);
lcd.print(" ");
MediaLetture = 0;
TensioneRMS_display = 0;
CorrenteRMS_Acea_display = 0;
CorrenteRMS_Inverter_display = 0;
PotenzaAttiva_Acea_display = 0;
PotenzaAttiva_Inverter_display = 0;
ultimo_refresh = millis();
}
}
//***************************************************