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. Controller Calibration of sensors

Controller Calibration of sensors

Scheduled Pinned Locked Moved Development
13 Posts 3 Posters 2.9k Views 3 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.
  • B Offline
    B Offline
    Ben Andrewes
    wrote on last edited by Ben Andrewes
    #1

    This may well have already been talked about but if it has I couldn't find it so thought I'd ask

    I am aiming to create a multisensor to place in all rooms in my house. As I'm very new to the arduino I thought it would be easier to get one working then just clone it. So I made a sensor with relays, motion, and temp/humidity (DHT11).

    The problem was that the DHT11s had varying accuracy/calibration and e.g. if I put two nodes in the same room they would report wildly different temps. Rather than hard coding the calibration I added a dummy dimmer switch sensor then used the recieved value (a value between 0 and 100%) to adjust the value that the DHT11 was reporting.

    This is the code I made (probably very inefficient but it works)

    int TempOffset = 50; // initial offset is zero when first loaded
    
    //Now divides temp offset by 10 & subtracts 5.  
    //then e.g. 10% received from domoticz gives a temp offset of -4 degrees.  
    //Allows dht offset to be +/- 5 degrees
    float ActualTempOffset = (TempOffset/10)-5;
    
    MyMessage msgTempOffset(CHILD_ID_TEMP_OFFSET, V_PERCENTAGE);
    
    void presentation
    {
     ...other sensors here
    present(CHILD_ID_TEMP_OFFSET, S_DIMMER);
    }
    void receive(const MyMessage &message)
    {
    	... relay stuff here
    	}
        else if (message.type==V_PERCENTAGE)  {
        int TempOffset = atoi(message.data);
        ActualTempOffset = (TempOffset/10)-5;
        Serial.print("New Temp Offset: ");
        Serial.println(ActualTempOffset);
    
        }  
        
    	
    }
    
    
    

    One thing that I would like it to do is to save the calibration state in EEPROM and report it Domoticz on boot to save calibrating each time.

    Can anyone help?

    mfalkviddM 1 Reply Last reply
    0
    • B Ben Andrewes

      This may well have already been talked about but if it has I couldn't find it so thought I'd ask

      I am aiming to create a multisensor to place in all rooms in my house. As I'm very new to the arduino I thought it would be easier to get one working then just clone it. So I made a sensor with relays, motion, and temp/humidity (DHT11).

      The problem was that the DHT11s had varying accuracy/calibration and e.g. if I put two nodes in the same room they would report wildly different temps. Rather than hard coding the calibration I added a dummy dimmer switch sensor then used the recieved value (a value between 0 and 100%) to adjust the value that the DHT11 was reporting.

      This is the code I made (probably very inefficient but it works)

      int TempOffset = 50; // initial offset is zero when first loaded
      
      //Now divides temp offset by 10 & subtracts 5.  
      //then e.g. 10% received from domoticz gives a temp offset of -4 degrees.  
      //Allows dht offset to be +/- 5 degrees
      float ActualTempOffset = (TempOffset/10)-5;
      
      MyMessage msgTempOffset(CHILD_ID_TEMP_OFFSET, V_PERCENTAGE);
      
      void presentation
      {
       ...other sensors here
      present(CHILD_ID_TEMP_OFFSET, S_DIMMER);
      }
      void receive(const MyMessage &message)
      {
      	... relay stuff here
      	}
          else if (message.type==V_PERCENTAGE)  {
          int TempOffset = atoi(message.data);
          ActualTempOffset = (TempOffset/10)-5;
          Serial.print("New Temp Offset: ");
          Serial.println(ActualTempOffset);
      
          }  
          
      	
      }
      
      
      

      One thing that I would like it to do is to save the calibration state in EEPROM and report it Domoticz on boot to save calibrating each time.

      Can anyone help?

      mfalkviddM Online
      mfalkviddM Online
      mfalkvidd
      Mod
      wrote on last edited by mfalkvidd
      #2

      @Ben-Andrewes you can probably look at how the relay example handles state. It does not report to the controller on startup but to do that you just invoke the send function at the end of setup(). It is also possible to request the last known value from the controller if you prefer that.

      See the API for more details on saveState, loadState, receive and request.

      Note that save/loadState can only store one byte (0-255 in decimal) at a time, so either you need to fit the offset into one byte or you need to split the data when saving.

      B 1 Reply Last reply
      1
      • gohanG Offline
        gohanG Offline
        gohan
        Mod
        wrote on last edited by
        #3

        Get a more accurate temp humidity sensor like sht31 and you are good to go. Dht sensors are a pain.

        1 Reply Last reply
        0
        • B Offline
          B Offline
          Ben Andrewes
          wrote on last edited by
          #4

          @gohan said in Controller Calibration of sensors:

          sht31

          Unfortunately as I'm intending to make over 10 of the same sensor cost becomes a consideration - I think the sht31 are about £4 more than the DHTs... My wife only allows me so much pocket money :)

          (I also bought a load of DHT11s before I really had any idea of what I was doing so need to use them up)

          gohanG 1 Reply Last reply
          0
          • mfalkviddM mfalkvidd

            @Ben-Andrewes you can probably look at how the relay example handles state. It does not report to the controller on startup but to do that you just invoke the send function at the end of setup(). It is also possible to request the last known value from the controller if you prefer that.

            See the API for more details on saveState, loadState, receive and request.

            Note that save/loadState can only store one byte (0-255 in decimal) at a time, so either you need to fit the offset into one byte or you need to split the data when saving.

            B Offline
            B Offline
            Ben Andrewes
            wrote on last edited by
            #5

            @mfalkvidd that worked for me (I had tried it but was saving the data to a different part of the eeprom than I thought).

            Cheers

            1 Reply Last reply
            0
            • mfalkviddM Online
              mfalkviddM Online
              mfalkvidd
              Mod
              wrote on last edited by
              #6

              Great work!

              Today I noticed that Domoticz seems to have some sort of built-in offset support:
              0_1500837575136_upload-3396fb5d-13b6-422e-9fd9-692edd4face6
              I haven't tried it though, and your solution is more versatile since it works regardless of controller.

              B 1 Reply Last reply
              1
              • B Ben Andrewes

                @gohan said in Controller Calibration of sensors:

                sht31

                Unfortunately as I'm intending to make over 10 of the same sensor cost becomes a consideration - I think the sht31 are about £4 more than the DHTs... My wife only allows me so much pocket money :)

                (I also bought a load of DHT11s before I really had any idea of what I was doing so need to use them up)

                gohanG Offline
                gohanG Offline
                gohan
                Mod
                wrote on last edited by
                #7

                @Ben-Andrewes consider a Dallas temperature sensor as it is cheap and more reliable than a dht11. There are also dht22 that is still cheap but better than dht11

                1 Reply Last reply
                0
                • mfalkviddM mfalkvidd

                  Great work!

                  Today I noticed that Domoticz seems to have some sort of built-in offset support:
                  0_1500837575136_upload-3396fb5d-13b6-422e-9fd9-692edd4face6
                  I haven't tried it though, and your solution is more versatile since it works regardless of controller.

                  B Offline
                  B Offline
                  Ben Andrewes
                  wrote on last edited by
                  #8

                  @mfalkvidd Damn - I hadn't noticed that - would've saved some time! Oh well, I learnt a bit about programming whilst I was doing it... :)

                  @gohan I have a dallas sensor so might try that, and they are cheap. I think I got a bit carried away with he idea that the DHT would do humidity as well - not that I really know why I want to know the humidity...!

                  If it is of any interest, I'm thinking of adding gesture recognition and reporting to the sensor using an APDS-9960 - I've seen a sketch that uses the APDS-9960, is this a good bit of kit or should I try to use something else?

                  I sort of have an idea of a sensor which has a couple of relays on that I can control from Domoticz, and also reports temp/hum, presence via PIR, and gesture controls to Domoticz which will then handle the logic.....

                  mfalkviddM 1 Reply Last reply
                  1
                  • B Ben Andrewes

                    @mfalkvidd Damn - I hadn't noticed that - would've saved some time! Oh well, I learnt a bit about programming whilst I was doing it... :)

                    @gohan I have a dallas sensor so might try that, and they are cheap. I think I got a bit carried away with he idea that the DHT would do humidity as well - not that I really know why I want to know the humidity...!

                    If it is of any interest, I'm thinking of adding gesture recognition and reporting to the sensor using an APDS-9960 - I've seen a sketch that uses the APDS-9960, is this a good bit of kit or should I try to use something else?

                    I sort of have an idea of a sensor which has a couple of relays on that I can control from Domoticz, and also reports temp/hum, presence via PIR, and gesture controls to Domoticz which will then handle the logic.....

                    mfalkviddM Online
                    mfalkviddM Online
                    mfalkvidd
                    Mod
                    wrote on last edited by
                    #9

                    @Ben-Andrewes the apds-9960 is fun. I did a project a while back (check the videos), but I only used the distance meter, not the gesture recognition.

                    1 Reply Last reply
                    1
                    • B Offline
                      B Offline
                      Ben Andrewes
                      wrote on last edited by Ben Andrewes
                      #10

                      @mfalkvidd That looks very cool, great work.

                      Unfortunately, I'm having trouble with the code for the apds9960 and I think that the interrupt isn't working properly - it seems to fire once then the interrupt is stuck low. I've now tried a test sketch from Sparkfun (official example sketch) without any mysensors stuff and added some serial prints to read the state of the interrupt pin every 5 secs and it always returns 0. Any idea why this might be? Do I need to send a message to the sensor to reset the interrupt back to high after it runs the interruptRoutine?

                      #include <Wire.h>
                      #include <SparkFun_APDS9960.h>
                      
                      // Pins
                      #define APDS9960_INT    3  // Needs to be an interrupt pin
                      
                      // Constants
                      
                      // Global Variables
                      SparkFun_APDS9960 apds = SparkFun_APDS9960();
                      volatile int isr_flag = 0;
                      
                      unsigned long SLEEP_TIME = 5000; // Sleep time between reads (in milliseconds)
                      unsigned long lastRefreshTime = 0; // Use this to implement a non-blocking delay function
                      void interruptRoutine();
                      void handleGesture();
                      
                      void setup() {
                      
                        // Set interrupt pin as input
                        pinMode(APDS9960_INT, INPUT);
                          Serial.println("Pin state is:");
                          Serial.println(digitalRead(APDS9960_INT));
                        // Initialize Serial port
                        Serial.begin(9600);
                        Serial.println();
                        Serial.println(F("--------------------------------"));
                        Serial.println(F("SparkFun APDS-9960 - GestureTest"));
                        Serial.println(F("--------------------------------"));
                      
                        //define sensitivty
                        apds.setGestureGain( 0 );
                      
                          // Initialize interrupt service routine
                        
                        attachInterrupt(digitalPinToInterrupt(APDS9960_INT), interruptRoutine, FALLING);
                      
                      
                        // Initialize APDS-9960 (configure I2C and initial values)
                        if ( apds.init() ) {
                          Serial.println(F("APDS-9960 initialization complete"));
                        } else {
                          Serial.println(F("Something went wrong during APDS-9960 init!"));
                        }
                        
                        // Start running the APDS-9960 gesture sensor engine
                        if ( apds.enableGestureSensor(true) ) {
                          Serial.println(F("Gesture sensor is now running"));
                        } else {
                          Serial.println(F("Something went wrong during gesture sensor init!"));
                        }
                      
                      }
                      
                      void loop() {
                      
                        boolean needRefresh = (millis() - lastRefreshTime) > SLEEP_TIME;
                        if (needRefresh)
                        {
                          lastRefreshTime = millis();
                          Serial.println("I'm Alive");
                          Serial.println("Pin state is:");
                          Serial.println(digitalRead(APDS9960_INT));
                      
                        }  
                        if( isr_flag == 1 ) {
                          Serial.println("Interrupt");
                          detachInterrupt(digitalPinToInterrupt(APDS9960_INT));
                          handleGesture();
                          Serial.print("returned from handling gesture");
                          isr_flag = 0;
                          Serial.println(isr_flag);
                          attachInterrupt(digitalPinToInterrupt(APDS9960_INT), interruptRoutine, FALLING);
                          Serial.println("attachInterrupt executed");
                        }
                      }
                      
                      void interruptRoutine() {
                        Serial.println("Interrupt Routine started");
                        isr_flag = 1;
                      }
                      
                      void handleGesture() {
                        Serial.println("Handling gesture");
                          //if ( apds.isGestureAvailable() ) {
                            //Serial.println("apds.isGestureAvailable() has returned true");
                      /****************
                          switch ( apds.readGesture() ) {
                            case DIR_UP:
                              Serial.println("UP");
                              break;
                            case DIR_DOWN:
                              Serial.println("DOWN");
                              break;
                            case DIR_LEFT:
                              Serial.println("LEFT");
                              break;
                            case DIR_RIGHT:
                              Serial.println("RIGHT");
                              break;
                            case DIR_NEAR:
                              Serial.println("NEAR");
                              break;
                            case DIR_FAR:
                              Serial.println("FAR");
                              break;
                            default:
                              Serial.println("NONE");
                          }
                          *******************/
                        // }
                        
                      }
                      
                      mfalkviddM 1 Reply Last reply
                      0
                      • B Ben Andrewes

                        @mfalkvidd That looks very cool, great work.

                        Unfortunately, I'm having trouble with the code for the apds9960 and I think that the interrupt isn't working properly - it seems to fire once then the interrupt is stuck low. I've now tried a test sketch from Sparkfun (official example sketch) without any mysensors stuff and added some serial prints to read the state of the interrupt pin every 5 secs and it always returns 0. Any idea why this might be? Do I need to send a message to the sensor to reset the interrupt back to high after it runs the interruptRoutine?

                        #include <Wire.h>
                        #include <SparkFun_APDS9960.h>
                        
                        // Pins
                        #define APDS9960_INT    3  // Needs to be an interrupt pin
                        
                        // Constants
                        
                        // Global Variables
                        SparkFun_APDS9960 apds = SparkFun_APDS9960();
                        volatile int isr_flag = 0;
                        
                        unsigned long SLEEP_TIME = 5000; // Sleep time between reads (in milliseconds)
                        unsigned long lastRefreshTime = 0; // Use this to implement a non-blocking delay function
                        void interruptRoutine();
                        void handleGesture();
                        
                        void setup() {
                        
                          // Set interrupt pin as input
                          pinMode(APDS9960_INT, INPUT);
                            Serial.println("Pin state is:");
                            Serial.println(digitalRead(APDS9960_INT));
                          // Initialize Serial port
                          Serial.begin(9600);
                          Serial.println();
                          Serial.println(F("--------------------------------"));
                          Serial.println(F("SparkFun APDS-9960 - GestureTest"));
                          Serial.println(F("--------------------------------"));
                        
                          //define sensitivty
                          apds.setGestureGain( 0 );
                        
                            // Initialize interrupt service routine
                          
                          attachInterrupt(digitalPinToInterrupt(APDS9960_INT), interruptRoutine, FALLING);
                        
                        
                          // Initialize APDS-9960 (configure I2C and initial values)
                          if ( apds.init() ) {
                            Serial.println(F("APDS-9960 initialization complete"));
                          } else {
                            Serial.println(F("Something went wrong during APDS-9960 init!"));
                          }
                          
                          // Start running the APDS-9960 gesture sensor engine
                          if ( apds.enableGestureSensor(true) ) {
                            Serial.println(F("Gesture sensor is now running"));
                          } else {
                            Serial.println(F("Something went wrong during gesture sensor init!"));
                          }
                        
                        }
                        
                        void loop() {
                        
                          boolean needRefresh = (millis() - lastRefreshTime) > SLEEP_TIME;
                          if (needRefresh)
                          {
                            lastRefreshTime = millis();
                            Serial.println("I'm Alive");
                            Serial.println("Pin state is:");
                            Serial.println(digitalRead(APDS9960_INT));
                        
                          }  
                          if( isr_flag == 1 ) {
                            Serial.println("Interrupt");
                            detachInterrupt(digitalPinToInterrupt(APDS9960_INT));
                            handleGesture();
                            Serial.print("returned from handling gesture");
                            isr_flag = 0;
                            Serial.println(isr_flag);
                            attachInterrupt(digitalPinToInterrupt(APDS9960_INT), interruptRoutine, FALLING);
                            Serial.println("attachInterrupt executed");
                          }
                        }
                        
                        void interruptRoutine() {
                          Serial.println("Interrupt Routine started");
                          isr_flag = 1;
                        }
                        
                        void handleGesture() {
                          Serial.println("Handling gesture");
                            //if ( apds.isGestureAvailable() ) {
                              //Serial.println("apds.isGestureAvailable() has returned true");
                        /****************
                            switch ( apds.readGesture() ) {
                              case DIR_UP:
                                Serial.println("UP");
                                break;
                              case DIR_DOWN:
                                Serial.println("DOWN");
                                break;
                              case DIR_LEFT:
                                Serial.println("LEFT");
                                break;
                              case DIR_RIGHT:
                                Serial.println("RIGHT");
                                break;
                              case DIR_NEAR:
                                Serial.println("NEAR");
                                break;
                              case DIR_FAR:
                                Serial.println("FAR");
                                break;
                              default:
                                Serial.println("NONE");
                            }
                            *******************/
                          // }
                          
                        }
                        
                        mfalkviddM Online
                        mfalkviddM Online
                        mfalkvidd
                        Mod
                        wrote on last edited by
                        #11

                        @Ben-Andrewes maybe the interrups doesn't get cleared until you read the sensor?

                        A side note: Doing Serial prints from an interrupt routine can result in strange results. Remove it to make sure you're not chasing ghosts.

                        1 Reply Last reply
                        0
                        • mfalkviddM Online
                          mfalkviddM Online
                          mfalkvidd
                          Mod
                          wrote on last edited by
                          #12

                          From the datasheet:

                          Gesture Interrupts flags: GINT, GVALID, and GFLVL are cleared by emptying e. all data has been read).

                          1 Reply Last reply
                          1
                          • B Offline
                            B Offline
                            Ben Andrewes
                            wrote on last edited by
                            #13

                            Thanks @mfalkvidd - you're right, the interrupt would never be cleared until the code read the gesture. I uncommented the readGesture only to find that the code hanged at that point (think that was why I commented it out before - I'd had a beer or two).

                            I think I really need to spend a bit of time learning about the Arduino programming language, and libraries etc as my programming knowledge is based on BASIC 30yrs ago and a bit of VBA at work. At the moment my arduino programming is just hacking stuff together and seeing if it works...

                            Anyway I found that it was the library that IDE installed was wrong and I needed to get the library direct from Sparkfun... Now it works fine so I just need to MySensorise it...

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


                            15

                            Online

                            11.7k

                            Users

                            11.2k

                            Topics

                            113.0k

                            Posts


                            Copyright 2019 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