BitBastelei #357 – Digitales Monitoring für alten Ferraris-Stromzähler

BitBastelei #357 - Digitales Monitoring für alten Ferraris-Stromzähler

(1 GB) 00:24:32

2019-11-03 11:00 🛈

Auch wenn sie Langsam durch “Smart”-Meter ersetzt werden: Die alten Ferraris-Stromzähler mit ihrer Scheibe sind doch noch häufig zu finden. Auch hier dreht ein solcher seine Runden, ich hätte aber gerne ein Live-Monitoring um den Stromverbrauch über den Tag zu analysieren. Mit einem IR-Sensor und einem ESP8266 kann man eine solche Aufzeichnung schnell nachrüsten.

Start der Bastelei: 3:43

Code ohne MQTT

Meine MQTT-Implementierung ist leider stark veraltet und würde mit einem aktuellen Arduino ohnehin nicht mehr kompilieren, daher hier ein Beispiel, welches die Werte per Seriell ausgibt. Der Code sollte sich recht einfach mit den Beispielen von PubSubClient oder ähnlichen verschmelzen lassen.

/***************************************************************************
  IR Ferraris Reader
  2019 Adlerweb//Bitbastelei
  Florian Knodt - www.adlerweb.info

  Note: Just a few minutes of coding, not heavily tested, etc
 ***************************************************************************/

#include <Arduino.h>

const unsigned int rpm_per_kWh = 75;

#define IRPIN D1
#define RED LOW
#define SILVER HIGH

//in 10ms = 200ms
#define MINTIME 20

////////END OF CONFIGURATION////////

// 0 = Silver->Red; 1 = Red->Silver
bool lastState = 0;
unsigned long lastmillis = 0;
unsigned long pendingmillis = 0;
bool inbuf[MINTIME];
bool startup=true;

void setup() {
  Serial.begin(115200);
  delay(3000);
  Serial.println("\nPOWER MONITOR - BOOT\n");

  pinMode(IRPIN, INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);
  lastmillis = millis();
}

bool getInput(uint8_t pin) {
  byte inchk=0;
  for(byte i=0; i<5; i++) {
    inchk += digitalRead(pin);
    delay(2);
  }
  if(inchk >= 3) return 1;
  return 0;
}

bool procInput(bool state) {
  byte inchk=0;

  //Array shift
  for (byte k = MINTIME-2; (k >= 0 && k < MINTIME); k--) {
    inbuf[k+1] = inbuf[k];
    inchk += inbuf[k];
  }
  
  //New value
  inbuf[0] = state;
  inchk += state;
  
  //Return average
  if(inchk > MINTIME/2) return 1;
  return 0;
}

void calcPower(void)  {
  unsigned long took = pendingmillis - lastmillis;
  lastmillis = pendingmillis;

  float kWh = 3600000.00 / took / rpm_per_kWh;

  if(!startup) {
    Serial.print(kWh);
    Serial.print(" kW @ ");
    Serial.print(took);
    Serial.println("ms");

    //Add MQTT, HTTP or whatever you want to do with the measurement here

    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
  }else{
    startup=false;
  }
}

void loop() {
  bool cur = getInput(IRPIN);
  cur = procInput(cur);

  switch(lastState) {
    case 0: //Silver; Waiting for transition to red
      if(cur != SILVER) {
        lastState++;
        pendingmillis = millis();
        Serial.println("Silver detected; waiting for red");
        calcPower();
      }
      break;
    case 1: //Red; Waiting for transition to silver
      if(cur != RED) {
        lastState=0;
        Serial.println("Red detected; Waiting for silver");
      }
      break;
  }
}

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.