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 3.1k 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.
  • S Offline
    S 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?

    S 1 Reply Last reply
    0
    • S 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?

      S Offline
      S 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
      • S Offline
        S 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
          
          S 1 Reply Last reply
          0
          • mfalkviddM mfalkvidd

            I think you need

            #define MY_GATEWAY_SERIAL
            
            S Offline
            S 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
            • B Offline
              B 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

              S 1 Reply Last reply
              0
              • B 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

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

                @badmannen
                I am on to it:)

                1 Reply Last reply
                0

                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
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                17

                Online

                12.0k

                Users

                11.2k

                Topics

                113.4k

                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