Locally attached sensors
-
My serial gateway will have something like 16 locally attached sensor to it. So I would like to keep my serial gateway code as clean and simple as possible, hence I would like some input on how to do this.
I will take the energyMeterPulse sketch in the example folder as an example of my idea.
I would like to rewrite the code to have an constructur like this:
EnergyMeter(DIGITAL_INPUT_SENSOR,PULSE_FACTOR ,SLEEP_MODE,MAX_WATT,CHILD_ID,SEND_FREQUENCY)Then it should have three methods:
Present Start StopMy serial gateway code will then look clean:
void setup() { // Setup locally attached sensors EnergyMeter powerSensor1 = new EnergyMeter(2,1000,false,10000,12,60000) } void presentation() { // Present locally attached sensors powerSensor1.present } void loop() { // Send locally attached sensor data here powerSensor1.start }So how can I restructure energyMeterPulse sketch to achieve this? Or how does other handle heaps of locally attached sensor to gateway?
-
My serial gateway will have something like 16 locally attached sensor to it. So I would like to keep my serial gateway code as clean and simple as possible, hence I would like some input on how to do this.
I will take the energyMeterPulse sketch in the example folder as an example of my idea.
I would like to rewrite the code to have an constructur like this:
EnergyMeter(DIGITAL_INPUT_SENSOR,PULSE_FACTOR ,SLEEP_MODE,MAX_WATT,CHILD_ID,SEND_FREQUENCY)Then it should have three methods:
Present Start StopMy serial gateway code will then look clean:
void setup() { // Setup locally attached sensors EnergyMeter powerSensor1 = new EnergyMeter(2,1000,false,10000,12,60000) } void presentation() { // Present locally attached sensors powerSensor1.present } void loop() { // Send locally attached sensor data here powerSensor1.start }So how can I restructure energyMeterPulse sketch to achieve this? Or how does other handle heaps of locally attached sensor to gateway?
Here is my suggestion, which does not quite work, because I dont know how to make the loop inside a class:)
#include "ENERGYMETER.h" //include the declaration for this class #include <SPI.h> #include <MySensor.h> #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your light sensor. (Only 2 and 3 generates interrupt!) #define PULSE_FACTOR 1000 // Nummber of blinks per KWH of your meeter #define SLEEP_MODE false // Watt-value can only be reported when sleep mode is false. #define MAX_WATT 10000 // Max watt value to report. This filetrs outliers. int DIGITAL_INPUT_SENSOR // Usually the interrupt = pin -2 (on uno/nano anyway) #define CHILD_ID 1 // Id of the sensor child unsigned long SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway. double ppwh = ((double)PULSE_FACTOR)/1000; // Pulses per watt hour boolean pcReceived = false; volatile unsigned long pulseCount = 0; volatile unsigned long lastBlink = 0; volatile unsigned long watt = 0; unsigned long oldPulseCount = 0; unsigned long oldWatt = 0; double oldKwh; unsigned long lastSend; MyMessage wattMsg(CHILD_ID,V_WATT); MyMessage kwhMsg(CHILD_ID,V_KWH); MyMessage pcMsg(CHILD_ID,V_VAR1); const byte LED_PIN = 13; //use the LED @ Arduino pin 13, this should not change so make it const (constant) //<<constructor>> setup the LED, make pin 13 an OUTPUT ENERGYMETER::ENERGYMETER(_DIGITAL_INPUT_SENSOR){ DIGITAL_INPUT_SENSOR = _DIGITAL_INPUT_SENSOR; // Fetch last known pulse count value from gw request(CHILD_ID, V_VAR1); // Use the internal pullup to be able to hook up this sketch directly to an energy meter with S0 output // If no pullup is used, the reported usage will be too high because of the floating pin pinMode(DIGITAL_INPUT_SENSOR,INPUT_PULLUP); attachInterrupt(INTERRUPT, onPulse, RISING); lastSend=millis(); } //<<destructor>> ENERGYMETER::~ENERGYMETER(){/*nothing to destruct*/} //present it void ENERGYMETER::present(){ // Send the sketch version information to the gateway and Controller sendSketchInfo("Energy Meter", "1.0"); // Register this device as power sensor present(CHILD_ID, S_POWER); } //turn the LED off void ENERGYMETER::start(){ void loop() { unsigned long now = millis(); // Only send values at a maximum frequency or woken up from sleep bool sendTime = now - lastSend > SEND_FREQUENCY; if (pcReceived && (SLEEP_MODE || sendTime)) { // New watt value has been calculated if (!SLEEP_MODE && watt != oldWatt) { // Check that we dont get unresonable large watt value. // could hapen when long wraps or false interrupt triggered if (watt<((unsigned long)MAX_WATT)) { send(wattMsg.set(watt)); // Send watt value to gw } Serial.print("Watt:"); Serial.println(watt); oldWatt = watt; } // Pulse cout has changed if (pulseCount != oldPulseCount) { send(pcMsg.set(pulseCount)); // Send pulse count value to gw double kwh = ((double)pulseCount/((double)PULSE_FACTOR)); oldPulseCount = pulseCount; if (kwh != oldKwh) { send(kwhMsg.set(kwh, 4)); // Send kwh value to gw oldKwh = kwh; } } lastSend = now; } else if (sendTime && !pcReceived) { // No count received. Try requesting it again request(CHILD_ID, V_VAR1); lastSend=now; } if (SLEEP_MODE) { sleep(SEND_FREQUENCY); } } } void receive(const MyMessage &message) { if (message.type==V_VAR1) { pulseCount = oldPulseCount = message.getLong(); Serial.print("Received last pulse count from gw:"); Serial.println(pulseCount); pcReceived = true; } } void onPulse() { if (!SLEEP_MODE) { unsigned long newBlink = micros(); unsigned long interval = newBlink-lastBlink; if (interval<10000L) { // Sometimes we get interrupt on RISING return; } watt = (3600000000.0 /interval) / ppwh; lastBlink = newBlink; } pulseCount++; } -
I now get this error message, any idea what the problem might be?
In file included from C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:5:0: C:\Users\kim\Documents\Arduino\libraries\MySensors/MySensor.h:285:4: error: #error No forward link or gateway feature activated. This means nowhere to send messages! Pretty pointless. #error No forward link or gateway feature activated. This means nowhere to send messages! Pretty pointless.Here is my test class:
#include <EnergyMeter.h> EnergyMeter power(1);//initialize an instance of the class void setup(){ power.present(); } void loop(){ power.update();//stay one second on, then a second off }and here is my EnergyMeter.cpp file :
#include "EnergyMeter.h" //include the declaration for this class #include <SPI.h> #include <MySensor.h> long PULSE_FACTOR // Nummber of blinks per KWH of your meeter boolean SLEEP_MODE // Watt-value can only be reported when sleep mode is false. long MAX_WATT // Max watt value to report. This filetrs outliers. int DIGITAL_INPUT_SENSOR // Usually the interrupt = pin -2 (on uno/nano anyway) int CHILD_ID // Id of the sensor child unsigned long SEND_FREQUENCY double ppwh boolean pcReceived = false; volatile unsigned long pulseCount = 0; volatile unsigned long lastBlink = 0; volatile unsigned long watt = 0; unsigned long oldPulseCount = 0; unsigned long oldWatt = 0; double oldKwh; unsigned long lastSend; //<<constructor>> setup the LED, make pin 13 an OUTPUT EnergyMeter::EnergyMeter(int _CHILD_ID){ CHILD_ID = _CHILD_ID; // Id of the sensor child /* Optional Arguments */ SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway. PULSE_FACTOR =1000; // Nummber of blinks per KWH of your meeter SLEEP_MODE = false ; // Watt-value can only be reported when sleep mode is false. MAX_WATT = 10000; // Max watt value to report. This filetrs outliers. DIGITAL_INPUT_SENSOR = 0; // Usually the interrupt = pin -2 (on uno/nano anyway) /*Starting the setup algorithm */ ppwh = ((double)PULSE_FACTOR)/1000; // Pulses per watt hour MyMessage wattMsg(CHILD_ID,V_WATT); MyMessage kwhMsg(CHILD_ID,V_KWH); MyMessage pcMsg(CHILD_ID,V_VAR1); // Fetch last known pulse count value from gw request(CHILD_ID, V_VAR1); // Use the internal pullup to be able to hook up this sketch directly to an energy meter with S0 output // If no pullup is used, the reported usage will be too high because of the floating pin pinMode(DIGITAL_INPUT_SENSOR,INPUT_PULLUP); attachInterrupt(INTERRUPT, onPulse, RISING); lastSend=millis(); } //<<destructor>> EnergyMeter::~EnergyMeter(){/*nothing to destruct*/} //present it void ENERGYMETER::present(){ // Send the sketch version information to the gateway and Controller sendSketchInfo("Energy Meter", "1.0"); // Register this device as power sensor present(CHILD_ID, S_POWER); } //update the reading of the power void ENERGYMETER::update(){ unsigned long now = millis(); // Only send values at a maximum frequency or woken up from sleep bool sendTime = now - lastSend > SEND_FREQUENCY; if (pcReceived && (SLEEP_MODE || sendTime)) { // New watt value has been calculated if (!SLEEP_MODE && watt != oldWatt) { // Check that we dont get unresonable large watt value. // could hapen when long wraps or false interrupt triggered if (watt<((unsigned long)MAX_WATT)) { send(wattMsg.set(watt)); // Send watt value to gw } Serial.print("Watt:"); Serial.println(watt); oldWatt = watt; } // Pulse cout has changed if (pulseCount != oldPulseCount) { send(pcMsg.set(pulseCount)); // Send pulse count value to gw double kwh = ((double)pulseCount/((double)PULSE_FACTOR)); oldPulseCount = pulseCount; if (kwh != oldKwh) { send(kwhMsg.set(kwh, 4)); // Send kwh value to gw oldKwh = kwh; } } lastSend = now; } else if (sendTime && !pcReceived) { // No count received. Try requesting it again request(CHILD_ID, V_VAR1); lastSend=now; } if (SLEEP_MODE) { sleep(SEND_FREQUENCY); } } } void receive(const MyMessage &message) { if (message.type==V_VAR1) { pulseCount = oldPulseCount = message.getLong(); Serial.print("Received last pulse count from gw:"); Serial.println(pulseCount); pcReceived = true; } } void onPulse() { if (!SLEEP_MODE) { unsigned long newBlink = micros(); unsigned long interval = newBlink-lastBlink; if (interval<10000L) { // Sometimes we get interrupt on RISING return; } watt = (3600000000.0 /interval) / ppwh; lastBlink = newBlink; } pulseCount++; } -
@mfalkvidd said:
#define MY_GATEWAY_SERIAL
The define method got rid of that error, so then i Should add it to the constructor?
So that the user that creates the node have to decide if the gateway is serial,wifi, or RF, right?
Now I got these errors instead:
Arduino: 1.6.8 (Windows 7), Board: "Arduino Nano, ATmega328" Build options changed, rebuilding all C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:8:1: error: expected initializer before 'boolean' boolean SLEEP_MODE // Watt-value can only be reported when sleep mode is false. ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp: In constructor 'EnergyMeter::EnergyMeter(int)': C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:27:2: error: 'CHILD_ID' was not declared in this scope CHILD_ID = _CHILD_ID; // Id of the sensor child ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:30:2: error: 'SEND_FREQUENCY' was not declared in this scope SEND_FREQUENCY = 20000; // Minimum time between send (in milliseconds). We don't wnat to spam the gateway. ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:31:2: error: 'PULSE_FACTOR' was not declared in this scope PULSE_FACTOR =1000; // Nummber of blinks per KWH of your meeter ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:32:2: error: 'SLEEP_MODE' was not declared in this scope SLEEP_MODE = false ; // Watt-value can only be reported when sleep mode is false. ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:33:2: error: 'MAX_WATT' was not declared in this scope MAX_WATT = 10000; // Max watt value to report. This filetrs outliers. ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:34:2: error: 'DIGITAL_INPUT_SENSOR' was not declared in this scope DIGITAL_INPUT_SENSOR = 0; // Usually the interrupt = pin -2 (on uno/nano anyway) ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:38:2: error: 'ppwh' was not declared in this scope ppwh = ((double)PULSE_FACTOR)/1000; // Pulses per watt hour ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:51:18: error: 'INTERRUPT' was not declared in this scope attachInterrupt(INTERRUPT, onPulse, RISING); ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:51:29: error: 'onPulse' was not declared in this scope attachInterrupt(INTERRUPT, onPulse, RISING); ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp: At global scope: C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:59:6: error: 'ENERGYMETER' has not been declared void ENERGYMETER::present(){ ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp: In function 'void present()': C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:64:11: error: 'CHILD_ID' was not declared in this scope present(CHILD_ID, S_POWER); ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp: At global scope: C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:69:6: error: 'ENERGYMETER' has not been declared void ENERGYMETER::update(){ ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp: In function 'void update()': C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:73:36: error: 'SEND_FREQUENCY' was not declared in this scope bool sendTime = now - lastSend > SEND_FREQUENCY; ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:74:7: error: 'pcReceived' was not declared in this scope if (pcReceived && (SLEEP_MODE || sendTime)) { ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:74:22: error: 'SLEEP_MODE' was not declared in this scope if (pcReceived && (SLEEP_MODE || sendTime)) { ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:79:32: error: 'MAX_WATT' was not declared in this scope if (watt<((unsigned long)MAX_WATT)) { ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:80:14: error: 'wattMsg' was not declared in this scope send(wattMsg.set(watt)); // Send watt value to gw ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:89:12: error: 'pcMsg' was not declared in this scope send(pcMsg.set(pulseCount)); // Send pulse count value to gw ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:90:49: error: 'PULSE_FACTOR' was not declared in this scope double kwh = ((double)pulseCount/((double)PULSE_FACTOR)); ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:93:14: error: 'kwhMsg' was not declared in this scope send(kwhMsg.set(kwh, 4)); // Send kwh value to gw ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:100:13: error: 'CHILD_ID' was not declared in this scope request(CHILD_ID, V_VAR1); ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:104:7: error: 'SLEEP_MODE' was not declared in this scope if (SLEEP_MODE) { ^ C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp: At global scope: C:\Users\kim\Documents\Arduino\libraries\EnergyMeter\EnergyMeter.cpp:109:1: error: expected declaration before '}' token } ^ exit status 1 Error compiling for board Arduino Nano. This report would have more information with "Show verbose output during compilation" option enabled in File -> Preferences. -
just for a test, try to make another constructor without any in-arguments and see if thoose errors persist. just to check. ( I might be way off here. did this stuff 12 years ago and just got back into it )
//Henrik
@badmannen
I am on to it:)
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login