Elmätare
En Watt, flera Watten...
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.
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.
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.
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.
Adapter
Den är monterad med en adapter med dubbelhäftande tejp.
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.


