Skip to content

Instantly share code, notes, and snippets.

@ajesler
Created September 23, 2015 12:03
Show Gist options
  • Save ajesler/3c76f93bbe51fe21e626 to your computer and use it in GitHub Desktop.
Save ajesler/3c76f93bbe51fe21e626 to your computer and use it in GitHub Desktop.
#define D3 3
#define SECONDS_PER_HOUR = 3600
const int photoresistorPin = D3;
const int impressionsPerkWh = 1000;
volatile long readingStart = 0;
volatile long readingEnd = 0;
volatile boolean readingAvailable = 0;
void recordDelta() {
boolean hasStartValue = readingStart != 0;
readingStart = readingEnd;
readingEnd = millis();
readingAvailable = hasStartValue;
}
float calculatekW() {
long delta = readingEnd - readingStart; // disable interrupt here?
float flashesPerSecond = delta / 1000;
float kW = SECONDS_PER_HOUR / (flashesPerSecond * impressionsPerkWh)
return kW;
}
void setup() {
attachInterrupt(digitalPinToInterrupt(D3), recordDelta, RISING);
}
float reading;
void loop() {
delay(250);
if (readingAvailable) {
readingAvailable = false;
reading = calculatekW();
Serial.print("Rounded reading is ");
Serial.println(reading);
}
}
/*
http://gammon.com.au/interrupts
http://letsmakerobots.com/node/28278
http://bildr.org/2012/11/photoresistor-arduino/
https://nicegear.co.nz/blog/electricity-meter-usage-over-mqtt/
http://davidorlo.com/articles/arduino/arduino-analog-read-potentiometer-to-digital-out-led-bonus-photoresistor-to-led
http://playground.arduino.cc/Learning/PhotoResistor
http://mqtt.org/
https://www.sparkfun.com/tutorials/326
http://www.analysir.com/blog/2015/06/16/porting-analysir-firmware-to-particles-photon-platform/
*/
////////////////////////////// notes.md
/*
Light threshold should be configurable
Add option to take average value of last n reads
http://www.reuk.co.uk/Flashing-LED-on-Electricity-Meter.htm
*/
////////////////////////////// demo.ino
SmartMeterReader smartMeterReader = new SmartMeterReader(D3);
float reading;
void recordFlashISR() {
smartMeterReader.recordFlash();
}
void setup() {
Serial.begin(115200);
attachInterrupt(digitalPinToInterrupt(D3), recordFlashISR, RISING);
}
void loop() {
if (smartMeterReader.hasReading()) {
reading = smartMeterReader.reading();
Serial.print("Rounded reading is ");
Serial.println(reading);
}
delay(500);
}
////////////////////////////// SmartMeterReader.h
#ifndef SmartMeterReader_H
#define SmartMeterReader_H
#define SECONDS_PER_HOUR = 3600
class SmartMeterReader {
public:
SmartMeterReader(int pin);
void setImpressionsPerkWh(int impressions);
void recordFlash();
boolean hasReading();
float reading();
private:
// prefix with '_'?
int inputPin;
int impressionsPerkWh;
float currentReading;
boolean hasReading;
long startMillis;
long endMillis;
};
#endif
////////////////////////////// SmartMeterReader.cpp
#include "SmartMeterReader.h"
SmartMeterReader::SmartMeterReader(int pin) {
inputPin = pin;
impressionsPerkWh = 1000; // this should be configurable
readingCallback = NULL;
// set the pin mode
pinMode(inputPin, INPUT);
}
void SmartMeterReader::setImpressionsPerkWh(int impressions) {
impressionsPerkWh = impressions;
}
void SmartMeterReader::recordFlash() {
hasReading = startMillis != 0;
startMillis = endMillis;
endMillis = millis();
}
bool SmartMeterReader::hasReading() {
return hasReading;
}
float SmartMeterReader::reading() {
long delta = endMillis - startMillis; // disable interrupt here?
float flashesPerSecond = delta / 1000;
currentReading = SECONDS_PER_HOUR / (flashesPerSecond * impressionsPerkWh)
return currentReading;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment