Nepelemes energia visszatáplálás mérő. SW-t igénylő kód Arduinohoz
Video link: https://youtu.be/g8UmQp0Xlzs
Bekötés:
FeszultsegAnalogBemenetiPin = A1; ide kell kötni a ZMPT101B-t
AramAnalogBemenetiPin = A2; ide kell kötni az árammal arányos jelet. 2.5V-os DC offset tartozik a 0A-hoz.
LED a pin2-re, ami világít ha visszatáplálás van.
ZMCT103-ról levettem a fekete mérőfejet, amin át kell fűzni a kábelt. És helyette bekötöttem a képen láthat nyithatót. A ZMT103 panelt megtartottam. ZMT103 kimenete egy kis kondival le van választva, hogy ne jusson ki a 2.5V DC offset. Kondit rövidre kell zárni, hogy kijusson.
1Amper kb. 450mV-os Vpp feszültséget okoz ZMCT103 kiemenetén. Ekkor érvényes a kódban ez a sor: mVperAmp = 166.87;
Az áram tartomány lehet nagyobb is, ha ZMXT103 piotija lejjebb van tekerve.
Ha nincs kijelződ, akkor serial print is tökéletes :)
Kód
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#define TFT_CS 10
#define TFT_RST 9
#define TFT_DC 8
#define TFT_SZELSEG 128
#define TFT_MAGASSAG 160
// Adafruit ST7735 kijelző objektum létrehozása
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
// Tizedespont pontosságú változó definiálása
int tizedespontPontossag = 1;
// Analóg bemeneti pinek definiálása
int FeszultsegAnalogBemenetiPin = A1;
int AramAnalogBemenetiPin = A2;
// Feszültség és áram mintákkal kapcsolatos változók inicializálása
float feszultsegMinta = 0;
float feszultsegUtolso = 0;
float feszultsegOsszeg = 0;
float feszultsegSzamolas = 0;
float feszultsegAtlaga;
float RMSFeszultsegAtlaga;
int feszultsegOffset = 0;
float feszultsegOsszegOffset = 0;
float aramMinta = 0;
float aramUtolso = 0;
float aramOsszeg = 0;
float aramSzamolas = 0;
float aramAtlaga;
float RMSAramAtlaga = 0;
float VeglegesRMSAram;
float aramKijelzes = 0;
float aramOsszegOffset = 0;
float offsetAramAtlaga = 0;
float aramOffsetUtolso = 0;
float aramOffsetSzamolas = 0;
float aramMinta1;
float aramMinta2;
float aramMinta3;
float latszolagosTeljesitmeny;
float valodiTeljesitmeny = 0;
float teljesitmenyMinta = 0;
float teljesitmenyUtolso = 0;
float teljesitmenySzamolas = 0;
float teljesitmenyOsszeg = 0;
float teljesitmenyTenyero = 0;
float napiEnergia = 0;
float energiaUtolso = 0;
float energiaSzamolas = 0;
float energiaOsszeg = 0;
float veglegesEnergiaErtek = 0;
float felhalmozottEnergia = 0;
float behozottVeglegesEnergiaErtek = 0;
float kivitettVeglegesEnergiaErtek = 0;
unsigned long kezdoMikro;
float a;
float kapcsolo01 = 9;
unsigned long kezdoGombMillis;
unsigned long aktualisGombMillis;
unsigned long kezdoMillisLCD;
unsigned long aktualisMillisLCD;
const unsigned long periodusLCD = 1000;
int oldal = 1;
int mehet = 0;
// LED kimenet
const int LED_PIN = 2;
void setup() {
// LED inicializálása kimenetként
pinMode(LED_PIN, OUTPUT);// Kijelző inicializálása
tft.initR(INITR_BLACKTAB);
tft.fillScreen(ST7735_WHITE);
tft.setTextSize(2);
tft.setTextColor(ST7735_BLUE);
kezdoMikro = micros();
kezdoMillisLCD = millis();
kezdoGombMillis = millis();
}
void loop() {
// Feszültség mintavételezés
if (millis() >= feszultsegUtolso + 1) {
feszultsegMinta = 2 * (analogRead(FeszultsegAnalogBemenetiPin) - 510);
feszultsegOsszegOffset = feszultsegOsszegOffset + feszultsegMinta;
feszultsegOsszeg = feszultsegOsszeg + sq(feszultsegMinta);
feszultsegSzamolas = feszultsegSzamolas + 1;
feszultsegUtolso = millis();
}
// Feszültség átlagolása és RMS számítása
if (feszultsegSzamolas == 1000) {
feszultsegAtlaga = feszultsegOsszeg / feszultsegSzamolas;
RMSFeszultsegAtlaga = sqrt(feszultsegAtlaga);
feszultsegOsszeg = 0;
feszultsegSzamolas = 0;
feszultsegOsszegOffset = 0;
}
// Áram mintavételezés
if (millis() >= aramUtolso + 1) {
aramMinta = analogRead(AramAnalogBemenetiPin) - 513;
aramOsszegOffset = aramOsszegOffset + aramMinta;
aramOsszeg = aramOsszeg + sq(aramMinta);
aramSzamolas = aramSzamolas + 1;
aramUtolso = millis();
}
// Áram átlagolása és RMS számítása
if (aramSzamolas == 1000) {
offsetAramAtlaga = aramOsszegOffset / aramSzamolas;
aramAtlaga = aramOsszeg / aramSzamolas;
RMSAramAtlaga = sqrt(aramAtlaga);
VeglegesRMSAram = (((RMSAramAtlaga / 1024) * 5000) / mVperAmp);
aramOsszeg = 0;
aramSzamolas = 0;
aramOsszegOffset = 0;
}
// Teljesítmény számítás
if (millis() >= teljesitmenyUtolso + 1) {
aramMinta1 = analogRead(AramAnalogBemenetiPin) - 513;
aramMinta2 = (aramMinta1 / 1024) * 5000;
aramMinta3 = aramMinta2 / mVperAmp;
feszultsegMinta = 2 * (analogRead(FeszultsegAnalogBemenetiPin) - 513);
teljesitmenyMinta = feszultsegMinta * aramMinta3;
teljesitmenyOsszeg = teljesitmenyOsszeg + teljesitmenyMinta;
teljesitmenySzamolas = teljesitmenySzamolas + 1;
teljesitmenyUtolso = millis();
}
// Teljesítmény átlagolása
if (teljesitmenySzamolas == 1000) {
valodiTeljesitmeny = (teljesitmenyOsszeg / teljesitmenySzamolas);
latszolagosTeljesitmeny = VeglegesRMSAram * RMSFeszultsegAtlaga;
teljesitmenyTenyero = valodiTeljesitmeny / latszolagosTeljesitmeny;// A teljesítménytényezőt ellenőrzés és korrekció alá helyezzük
if (teljesitmenyTenyero > 1 || teljesitmenyTenyero < 0) {
teljesitmenyTenyero = 0;
}teljesitmenyOsszeg = 0;
teljesitmenySzamolas = 0;
}
// Energia számítás
if (millis() >= energiaUtolso + 1) {
energiaSzamolas = energiaSzamolas + 1;
energiaUtolso = millis();
}
if (energiaSzamolas == 1000) {
felhalmozottEnergia = valodiTeljesitmeny / 3600;
veglegesEnergiaErtek = veglegesEnergiaErtek + felhalmozottEnergia;// Energia értékeket kezeljük
if (felhalmozottEnergia >= 0) {
behozottVeglegesEnergiaErtek = behozottVeglegesEnergiaErtek + felhalmozottEnergia;
}
if (felhalmozottEnergia < 0) {
kivitettVeglegesEnergiaErtek = kivitettVeglegesEnergiaErtek - felhalmozottEnergia;
}energiaSzamolas = 0;
}
aktualisMillisLCD = millis();
if (aktualisMillisLCD - kezdoMillisLCD >= periodusLCD) {
if (valodiTeljesitmeny >= 0) {
aramKijelzes = VeglegesRMSAram;
}
if (valodiTeljesitmeny < 0) {
aramKijelzes = -VeglegesRMSAram;// Bekapcsoljuk a LED-et, mivel az áramKijelzés negatív
digitalWrite(LED_PIN, HIGH);
}
else {
// Kikapcsoljuk a LED-et, mivel az áramKijelzés nem negatív
digitalWrite(LED_PIN, LOW);
}
// Kijelzőn megjelenítendő értékek beállítása
tft.fillRect(0, 0, TFT_SZELSEG, TFT_MAGASSAG, ST7735_WHITE);
tft.setCursor(15, 5);
tft.print(aramKijelzes, tizedespontPontossag * 2);
tft.print(" A");
tft.setCursor(15, 30);
tft.print(RMSFeszultsegAtlaga, tizedespontPontossag);
tft.print(" V");
tft.setCursor(15, 55);
tft.print(valodiTeljesitmeny, tizedespontPontossag);
tft.print(" W");
tft.setCursor(5, 80);
tft.print("T:");
tft.print(veglegesEnergiaErtek / 1000, tizedespontPontossag * 2);
tft.setTextSize(1);
tft.setTextColor(ST7735_RED);
tft.print("kWh");
tft.setTextColor(ST7735_BLUE);
tft.setTextSize(2);
tft.setCursor(5, 105);
tft.print("I:");
tft.print(behozottVeglegesEnergiaErtek / 1000, tizedespontPontossag * 2);
tft.setTextSize(1);
tft.setTextColor(ST7735_RED);
tft.print("kWh");
tft.setTextColor(ST7735_BLUE);
tft.setTextSize(2);
tft.setCursor(5, 130);
tft.print("E:");
tft.print(kivitettVeglegesEnergiaErtek / 1000, tizedespontPontossag * 2);
tft.setTextSize(1);
tft.setTextColor(ST7735_RED);
tft.print("kWh");
tft.setTextColor(ST7735_BLUE);
tft.setTextSize(2);
kezdoMillisLCD = aktualisMillisLCD;
mehet = 1;
}
}