Skip to content

Instantly share code, notes, and snippets.

@adlerweb
Created November 5, 2019 10:06
Show Gist options
  • Save adlerweb/2d60f5bd2af4d91e937a7fd55cd464b2 to your computer and use it in GitHub Desktop.
Save adlerweb/2d60f5bd2af4d91e937a7fd55cd464b2 to your computer and use it in GitHub Desktop.

Revisions

  1. adlerweb created this gist Nov 5, 2019.
    107 changes: 107 additions & 0 deletions irFerraris.ino
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,107 @@
    /***************************************************************************
    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;
    }
    }