From 27ee2a7928f7f7f2089e73d50768888839474fdd Mon Sep 17 00:00:00 2001 From: Juan Ferrer Toribio Date: Wed, 10 Jul 2019 18:09:44 +0200 Subject: [PATCH] Initial commit --- energy-meter.ino | 190 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 energy-meter.ino diff --git a/energy-meter.ino b/energy-meter.ino new file mode 100644 index 0000000..5f00f82 --- /dev/null +++ b/energy-meter.ino @@ -0,0 +1,190 @@ +#include +#include +#include +#include +#include +#include +#include + +//+++++++++++++++++++++++++++++++++++++++++++ Configuration + +#define DB_HOST "db.verdnatura.es" +#define DB_USER "energy-meter" +#define DB_PASS "UeNBY2wR3gxMd34A" +#define DB_PORT 3306 +#define DELAY 100 +#define DEBUG_INTERVAL 1000 +#define RECORD_INTERVAL 60000 +#define SQL "CALL vn.energyMeter_record(%d, %d)" +#define N_INPUTS 9 + +int pins[] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; +byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; + +//+++++++++++++++++++++++++++++++++++++++++++ Code + +typedef struct Input { + int id; + unsigned long timer; +}; + +char query[50]; +unsigned long lastRefresh; +unsigned long lastDebug; +unsigned long lastRecord; +Input inputs[N_INPUTS]; +EthernetClient ethClient; +MySQL_Connection db((Client *) ðClient); +IPAddress dbServer; + +void printTitle(String title) { + #ifdef DEBUG + for (int i = 0; i < 10; i++) + Serial.print('='); + Serial.println(" " + title); + #endif +} + +void showError(String error) { + #ifdef DEBUG + Serial.println(error); + #endif +} + +void abortWithError(String error) { + showError(error); + while (true) delay(1); +} + +int freeRam() { + extern int __heap_start, *__brkval; + int v; + return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); +} + +void setup() { + #ifdef DEBUG + Serial.begin(9600); + while (!Serial); + #endif + + if (Ethernet.begin(mac) == 0) + abortWithError("DHCP config failed."); + if (Ethernet.hardwareStatus() == EthernetNoHardware) + abortWithError("Eth shield not found."); + if (Ethernet.linkStatus() == LinkOFF) + abortWithError("Eth cable not connected."); + + #ifdef DEBUG + Serial.println("IP: " + String(Ethernet.localIP())); + #endif + + if (!dbConnect()) + abortWithError("Aborting."); + + unsigned long now = millis(); + lastRefresh = now; + lastDebug = now; + lastRecord = now; + + for (int i = 0; i < N_INPUTS; i++) { + Input* input = &inputs[i]; + input->id = i + 1; + input->timer = 0; + pinMode(pins[i], INPUT); + } + + #ifdef DEBUG + Serial.println("RAM: " + String(freeRam())); + #endif +} + +boolean dbConnect() { + DNSClient dns; + dns.begin(Ethernet.dnsServerIP()); + + if (dns.getHostByName(DB_HOST, dbServer) != 1) { + showError("Cannot resolve DB."); + return false; + } + + #ifdef DEBUG + Serial.println("Connecting to DB: " + String(dbServer)); + #endif + + if (!db.connect(dbServer, DB_PORT, DB_USER, DB_PASS)) { + showError("Cannot connect to DB."); + return false; + } + + return true; +} + +void refreshTimers() { + unsigned long now = millis(); + + for (int i = 0; i < N_INPUTS; i++) { + Input* input = &inputs[i]; + if (digitalRead(pins[i]) == HIGH) + input->timer += now - lastRefresh; + } + + lastRefresh = now; +} + +void loop() { + refreshTimers(); + Ethernet.maintain(); + + #ifdef DEBUG + if (millis() - lastDebug > DEBUG_INTERVAL) { + printTitle("Status"); + + for (int i = 0; i < N_INPUTS; i++) { + Input* input = &inputs[i]; + Serial.print("Input "); + + String id = String(input->id); + for (int j = 2 - id.length(); j > 0; j--) + Serial.print(" "); + + Serial.print(String(input->id) + ": "); + Serial.print(String(digitalRead(pins[i]) == HIGH)); + Serial.println("/" + String(input->timer)); + } + + lastDebug = millis(); + } + #endif + + if (millis() - lastRecord > RECORD_INTERVAL) { + printTitle("Recording to DB"); + + if (!db.connected()) + dbConnect(); + + for (int i = 0; i < N_INPUTS; i++) { + refreshTimers(); + Input* input = &inputs[i]; + int timer = input->timer; + int seconds = timer / 1000; + input->timer = 0; + + if (seconds > 0 && db.connected()) { + sprintf(query, SQL, input->id, seconds); + + #ifdef DEBUG + Serial.println(query); + #endif + + MySQL_Cursor *cur = new MySQL_Cursor(&db); + cur->execute(query); + delete cur; + } + } + + lastRecord = millis(); + } + + delay(DELAY); +}