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 kopplingElmÀtare koppling

Provade först pÄ ett kopplingsdÀck nÀr jag skrev koden.

main.cpp

#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Àtares 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.
  //Spittas interrupt i fallanade och stigande blir mindre och snabbare kod under interrupt.
  attachInterrupt(digitalPinToInterrupt(PhotoSensorPin1), PhotoSensorOn, FALLING);
  attachInterrupt(digitalPinToInterrupt(PhotoSensorPin2), PhotoSensorOff, RISING);

  CalulatePhotoSensorTimes = false;

  //Initsiera 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 dt 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 kontaktstuts 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;
}

Koden anvÀnder biblioteket 'LedControl'.

LedControlHack.cpp

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

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

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.

blink_simulate.cpp

#include <Arduino.h>

/*
  Blink

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

  Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
  it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
  the correct LED pin independent of which board is used.
  If you want to know what pin the on-board LED is connected to on your Arduino
  model, check the Technical Specs of your board at:
  https://www.arduino.cc/en/Main/Products

  modified 8 May 2014
  by Scott Fitzgerald
  modified 2 Sep 2016
  by Arturo Guadalupi
  modified 8 Sep 2016
  by Colby Newman

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink
*/

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(100);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1900);                       // wait for a second
}

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.

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.