PchButik.se

Elmätare

En Watt, flera Watten...

Elmätare översikt

Experimentet läser av blinkningarna på elmätaren och mäter tiden mellan varje blink, i millisekunder.

Och visar resultatet i hur många watt det drar just nu. På bilden visar det 1510 Watt.

Elmätare displaybildElmätare koppling

Provade först på ett kopplingsdäck när jag skrev koden.

Koden använder biblioteket 'LedControl'.

För att kunna skriva PchButik på skärmen, så har jag modifierat font-tabellen 'charTable' i filen 'LedControl.h'.

Jag vet att k:et inte är så snyggt, och många andra fonter kan behövas läggas till.

Kod och kod-kommentarer

Huvudkod från projektet:

#include <Arduino.h>
#include "LedControl.h"

void DisplayVariableValue(unsigned long, char);
void DisplayNumber(unsigned long);
void DisplayString(String);
char getChar(String, int);
void PhotoSensorOn();
void PhotoSensorOff();

const byte PhotoSensorPin1 = 2; //danna används som interupt, så kan bara var 2 eller 3 med Uno
const byte PhotoSensorPin2 = 3; //danna används som interupt, så kan bara var 2 eller 3 med Uno
const byte elpatronStatePin = 4; //Reserverad för, Ingång elpatron fotocell
const byte buzzerPin = 5; //Reserverad för, Utgång ljudsignal
const byte ButtPin = 6; //Knapp Pinne

LedControl lc=LedControl(12,11,10,1); //Ettan betyder att vi har en Display i kaskaden.

volatile unsigned long PhotoSensorOnMillis;
volatile unsigned long PhotoSensorOffMillis;
volatile unsigned long PhotoSensorLastOffMillis;
boolean CalulatePhotoSensorTimes;
unsigned long PhotoSensorOnTime;
unsigned long PhotoSensorBetweenTime;

boolean ButtStatus = HIGH;
boolean uppdateDisplay = true;
byte ShowDisplay = 1; //starta med att visa på displayen

void setup() {
    // put your setup code here, to run once:
    pinMode(LED_BUILTIN, OUTPUT);
    pinMode(PhotoSensorPin1, INPUT_PULLUP);
    pinMode(PhotoSensorPin2, INPUT_PULLUP);
    pinMode(ButtPin, INPUT_PULLUP);
    ButtStatus = digitalRead(ButtPin);

    //För att läsa av mellanrummet på elmätarens LED behövs bara en Interrupt.
    //Men denna är förberedd för att läsa hur länge en LED lyser, ex elpaton i en panna.
    //Splittas interrupt i fallande och stigande blir mindre och snabbare kod under interrupt.
    attachInterrupt(digitalPinToInterrupt(PhotoSensorPin1), PhotoSensorOn, FALLING);
    attachInterrupt(digitalPinToInterrupt(PhotoSensorPin2), PhotoSensorOff, RISING);

    CalulatePhotoSensorTimes = false;

    //Initierar LED-Displayen
    lc.shutdown(0,false);
    lc.setIntensity(0,8);
    lc.clearDisplay(0);
    DisplayString((String) "PchButik"); //Tabellen 'charTable' i 'LedControl' för att skriva denna text
    delay(1000);
}

void loop() {
    // put your main code here, to run repeatedly:

    //Om det finns data för att beräkna tider
    if (CalulatePhotoSensorTimes) {
        PhotoSensorOnTime = PhotoSensorOffMillis - PhotoSensorOnMillis;
        PhotoSensorBetweenTime = PhotoSensorOffMillis - PhotoSensorLastOffMillis;
        CalulatePhotoSensorTimes = false;
        uppdateDisplay = true;
    }

    //Kollar om tryck på strömbrytaren
    if (digitalRead(ButtPin) == LOW){
        delay(10); //denna minskar betydelsen kontaktstuds från strömbrytaren
        if (ButtStatus == HIGH){
            ShowDisplay ++;
            uppdateDisplay = true;
            if (ShowDisplay > 2){
                ShowDisplay = 1;
            }
        }
        ButtStatus = LOW;
    } else {
        ButtStatus = HIGH;
    }

    //Kollar om displayen ska uppdateras
    if (uppdateDisplay == true){
        switch (ShowDisplay) {
            case 1:
                DisplayVariableValue(PhotoSensorOnTime, 'L'); //L = Length
                break;
            case 2:
                DisplayVariableValue(3600000/PhotoSensorBetweenTime, 'P'); //P = Power
                break;
        }
        uppdateDisplay = false;
    }
}

//Interrupt
void PhotoSensorOn() {
    digitalWrite(LED_BUILTIN, HIGH);
    PhotoSensorOnMillis = millis();
}

//Interrupt
void PhotoSensorOff() {
    digitalWrite(LED_BUILTIN, LOW);
    PhotoSensorLastOffMillis = PhotoSensorOffMillis;
    PhotoSensorOffMillis = millis();
    CalulatePhotoSensorTimes = true;
}

//Skriver ut ett tal.
void DisplayNumber(unsigned long number){
    if(number > 99999999){
        DisplayString("E9"); //Betyder Error 9, talet är för högt
        return;
    }
    String s = String(number);
    int l = s.length();
    for (int i = 0; i <= 7; i++) {
        lc.setChar(0, i, getChar(s, l-1-i), false);
    }
}

//Skriver ut ett tecken av en variabel och värde.
void DisplayVariableValue(unsigned long number, char c){
    if(number > 999999){
        DisplayString("E6"); //Betyder Error 6, talet är för högt
        return;
    }
    DisplayNumber(number);
    lc.setChar(0, 7, c, false);
}

//Skriver ut en sträng.
void DisplayString(String s){
    int l = s.length();
    if(l > 8){
        s = "E8"; //Betyder Error 8, strängen är för lång
        l = s.length();
    }
    lc.setChar(0, 7, getChar(s, l-8), false);
    lc.setChar(0, 6, getChar(s, l-7), false);
    lc.setChar(0, 5, getChar(s, l-6), false);
    lc.setChar(0, 4, getChar(s, l-5), false);
    lc.setChar(0, 3, getChar(s, l-4), false);
    lc.setChar(0, 2, getChar(s, l-3), false);
    lc.setChar(0, 1, getChar(s, l-2), false);
    lc.setChar(0, 0, getChar(s, l-1), false);
}

//Denna returnerar vilket tecken som är på platsen i strängen.
//Är platsen utanför strängen returneras ett blanksteg.
char getChar(String s, int i){
    char rc = ' ';
    if(s.length() > (unsigned int) i ){
        rc = s.charAt(i);
    }
    return rc;
}

Modifierad teckentabell i LedControl.h:

const static byte charTable [] PROGMEM  = {
        B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000, //00-07
        B01111111,B01111011,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111, //08-15
        B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, //16-23
        B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, //24-31
        B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, //32-39
        B00000000,B00000000,B00000000,B00000000,B10000000,B00000001,B10000000,B00000000, //40-47
        B01111110,B00110000,B01101101,B01111001,B00110011,B01011011,B01011111,B01110000, //48-55
        B01111111,B01111011,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, //56-63
        B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000, //64-71
        B00110111,B00000000,B00000000,B00000000,B00001110,B00000000,B00000000,B00000000, //72-79
        B01100111,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000, //80-87
        B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00001000, //88-95
        B00000000,B01110111,B00011111,B00001101,B00111101,B01001111,B01000111,B00000000, //96-103
        B00010111,B00000100,B00000000,B00000111,B00001110,B00000000,B00010101,B00011101, //104-111
        B00010111,B00000000,B00000000,B00000000,B00001111,B00011100,B00000000,B00000000, //112-119
        B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000  //120-127
};

Blink-simulering som användes för test:

#include <Arduino.h>

/*
    Blink

    Turns an LED on for one second, then off for one second, repeatedly.
*/

void setup() {
    pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(100);
    digitalWrite(LED_BUILTIN, LOW);
    delay(1900);
}

För att simulera blinkningarna använde jag exempel-sketchen Blink från Arduino på en annan Nano.

Summan 100+1900 blir 2000 millisekunder. 3600000 är antalet millisekunder på en timma.

3600000 / 2000 = 1800 Watt. Så displayen ska visa 1800, men visar ibland 1799 och 1801.

Elmätare test på kopplingsdäck

Byggde den sedan mer permanent på experimentkort för Nano.

Tyvärr kan jag inte hitta detta kort i Fritzing, så tyvärr inga kopplingar att visa.

Kanske kan närbilden hjälpa att visa hur det är byggt.

Elmätare permanent bygge

Knappen växlar mellan att visa L-värde och P-värde och den startar med L-värde.

L-värdet visar hur många millisekunder LED:en i elmätaren lyser. Detta har ingen praktisk betydelse, jag var bara nyfiken.

Min mätare har 78-80 millisekunder lys-tid.

Elmätare knapp och display
Elmätare adapter

Adapter

Den är monterad med en adapter med dubbelhäftande tejp.

Elmätare adapter närbild

Framtiden

Experimentet med elmätaren är tänkt att integreras i denna modul.

Denna mäter el-patronens drifttid.

Sparar datum och klockslag när den startar och stoppar laddning.

Det går sedan att läsa av i vårt lokala nät, LAN.

Inköpslista:

  • 1913 Fotodiod med hållare för montering. Alt.1: länk. Alt.2: länk.
  • 0406 8 siffror med 7 segment LED-display och drivare: länk.
  • 0988 ATmega328 5 Volt Arduino nano kompatibel: länk.
  • 2889 Experimentkort Nano 3.0 med genomomgående hål: länk.
  • 2626 3 st. XH 2.54 5P hona och hane med kabel och kontakt: länk.
  • 1936 Female to Female Dupont Cable 70cm 3pin: länk.

Video

Video som visar elmätaren i praktisk drift och displayens beteende.

Denna sida är konverterad med hjälp av AI.
En sida för dig som bygger elektronik själv, experimenterar och laborerar.
Skapad av Per-Anders Hult för PchButik.se.