Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. Locally attached sensors

Locally attached sensors

Scheduled Pinned Locked Moved Development
7 Posts 3 Posters 2.7k Views 4 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • skatunS Offline
    skatunS Offline
    skatun
    wrote on last edited by
    #1

    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 
    Stop
    

    My 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?

    skatunS 1 Reply Last reply
    0
    • skatunS skatun

      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 
      Stop
      

      My 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?

      skatunS Offline
      skatunS Offline
      skatun
      wrote on last edited by
      #2

      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++;
      }
      
      1 Reply Last reply
      0
      • skatunS Offline
        skatunS Offline
        skatun
        wrote on last edited by
        #3

        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++;
        }
        
        1 Reply Last reply
        0
        • mfalkviddM Offline
          mfalkviddM Offline
          mfalkvidd
          Mod
          wrote on last edited by
          #4

          I think you need

          #define MY_GATEWAY_SERIAL
          
          skatunS 1 Reply Last reply
          0
          • mfalkviddM mfalkvidd

            I think you need

            #define MY_GATEWAY_SERIAL
            
            skatunS Offline
            skatunS Offline
            skatun
            wrote on last edited by
            #5

            @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.
            
            1 Reply Last reply
            0
            • badmannenB Offline
              badmannenB Offline
              badmannen
              wrote on last edited by
              #6

              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

              rPi 3 - UNO R3 - Mini - Nano - custom

              skatunS 1 Reply Last reply
              0
              • badmannenB badmannen

                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

                skatunS Offline
                skatunS Offline
                skatun
                wrote on last edited by
                #7

                @badmannen
                I am on to it:)

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                9

                Online

                11.7k

                Users

                11.2k

                Topics

                113.1k

                Posts


                Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • MySensors
                • OpenHardware.io
                • Categories
                • Recent
                • Tags
                • Popular