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. General Discussion
  3. Triple Axis Compass Sensor for mailbox?

Triple Axis Compass Sensor for mailbox?

Scheduled Pinned Locked Moved General Discussion
12 Posts 3 Posters 3.0k 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.
  • Cliff KarlssonC Cliff Karlsson

    I know this question has been discussed before but would a Triple Axis Compass Sensor be a good alternative for a battery powered mailbox-sensor. I have a type of mailbox that is common in sweden where the lid gets lifted and I would place the sensor under the lid in that case.

    Or would a PIR that is placed in the lid be any better/worse from a battery conserving standpoint?

    YveauxY Offline
    YveauxY Offline
    Yveaux
    Mod
    wrote on last edited by
    #2

    @Cliff-Karlsson Can't you use a simple reed switch & magnet (like a door sensor)?
    These can be tied to an interrupt input of your Arduino and wake it when opening is detected.
    Power usage will be minimal and implementation is simple.

    When using a compass sensor you either have to monitor the signal continuously to detect movement (which consumes 'a lot' of power) or select one which can generate a trigger when a certain displacement is detected (don't know if these event exist -- acceleration sensors which gererate a trigger do exist). The trigger has to be tied to an interrupt pin of your Arduino, and your back at the reed switch suggestion...

    http://yveaux.blogspot.nl

    1 Reply Last reply
    0
    • Cliff KarlssonC Offline
      Cliff KarlssonC Offline
      Cliff Karlsson
      wrote on last edited by
      #3

      Yes, a magnet-switch would probably work. But my main concern regarding the magnet-switch is that I sometimes receives rather large parcels witch are jammed down the mailbox and would possible break of any magnet-switch that are placed inside the mailbox. The lid is where any sensor would be most protected. I might go with the simple magnet switch method to try out the durability but I would like to know if there are any options.

      Would the Triple Axis Accelerometer from the mysensors-shop link work with just waking up when lid is moved? Or could a PIR be able to use interrupt to wake up?

      1 Reply Last reply
      0
      • hekH Offline
        hekH Offline
        hek
        Admin
        wrote on last edited by
        #4

        I've mounted mine like this:

        0_1461511346700_20130804_205852.jpg

        It's been sitting there for almost 3 years now.

        1 Reply Last reply
        1
        • Cliff KarlssonC Offline
          Cliff KarlssonC Offline
          Cliff Karlsson
          wrote on last edited by Cliff Karlsson
          #5

          My mailbox kid of looks like this: 0_1461511903532_binary-590546-277725.jpg

          YveauxY 1 Reply Last reply
          0
          • Cliff KarlssonC Cliff Karlsson

            My mailbox kid of looks like this: 0_1461511903532_binary-590546-277725.jpg

            YveauxY Offline
            YveauxY Offline
            Yveaux
            Mod
            wrote on last edited by
            #6

            @Cliff-Karlsson Could you post a real picture and draw where you would mount the compass sensor?
            I expect the compass sensor is even more fragile than a door sensor and wont last very long...

            http://yveaux.blogspot.nl

            1 Reply Last reply
            0
            • Cliff KarlssonC Offline
              Cliff KarlssonC Offline
              Cliff Karlsson
              wrote on last edited by
              #7

              @Yveaux said:

              @Cliff-Karlsson Could you post a real picture and draw where you would mount the compass sensor?

              It looks similar to this one and I would place everything inside a sealed plastic box glued to the top of the lid if that kind of sensor is a good idea battery-wise.

              0_1461518850285_brevlåda.jpg

              YveauxY 1 Reply Last reply
              0
              • Cliff KarlssonC Cliff Karlsson

                @Yveaux said:

                @Cliff-Karlsson Could you post a real picture and draw where you would mount the compass sensor?

                It looks similar to this one and I would place everything inside a sealed plastic box glued to the top of the lid if that kind of sensor is a good idea battery-wise.

                0_1461518850285_brevlåda.jpg

                YveauxY Offline
                YveauxY Offline
                Yveaux
                Mod
                wrote on last edited by
                #8

                @Cliff-Karlsson I would expect you can find a place to firmly glue a small magnet (neodimium) to the bottom part (the one with 'POST' on it) that will survive even your most extreme AliExpress deliveries ;-)

                http://yveaux.blogspot.nl

                1 Reply Last reply
                1
                • Cliff KarlssonC Offline
                  Cliff KarlssonC Offline
                  Cliff Karlsson
                  wrote on last edited by
                  #9

                  Ahhh, that idea did not strike me that I could use a different neodymium magnet instead of the one that was shipped with the magnet-switch. I guess that I just can place a strong magnet on the side of the mailbox. No glue needed as I almost break my nails of when trying to get those 20x3(?)mm magnets of my refridgerator

                  YveauxY 1 Reply Last reply
                  0
                  • Cliff KarlssonC Cliff Karlsson

                    Ahhh, that idea did not strike me that I could use a different neodymium magnet instead of the one that was shipped with the magnet-switch. I guess that I just can place a strong magnet on the side of the mailbox. No glue needed as I almost break my nails of when trying to get those 20x3(?)mm magnets of my refridgerator

                    YveauxY Offline
                    YveauxY Offline
                    Yveaux
                    Mod
                    wrote on last edited by
                    #10

                    @Cliff-Karlsson They come in all sizes. The door-sensor part without wires contains just a magnet, nothing more.

                    http://yveaux.blogspot.nl

                    1 Reply Last reply
                    0
                    • Cliff KarlssonC Offline
                      Cliff KarlssonC Offline
                      Cliff Karlsson
                      wrote on last edited by
                      #11

                      I want to try to build simple sensor using the door/window/button sketch:

                      
                      #include <MySensor.h>
                      #include <SPI.h>
                      #include <Bounce2.h>
                      
                      #define CHILD_ID 3
                      #define BUTTON_PIN  3  // Arduino Digital I/O pin for button/reed switch
                      
                      MySensor gw;
                      Bounce debouncer = Bounce(); 
                      int oldValue=-1;
                      
                      // Change to V_LIGHT if you use S_LIGHT in presentation below
                      MyMessage msg(CHILD_ID,V_TRIPPED);
                      
                      void setup()  
                      {  
                        gw.begin();
                      
                       // Setup the button
                        pinMode(BUTTON_PIN,INPUT);
                        // Activate internal pull-up
                        digitalWrite(BUTTON_PIN,HIGH);
                        
                        // After setting up the button, setup debouncer
                        debouncer.attach(BUTTON_PIN);
                        debouncer.interval(5);
                        
                        // Register binary input sensor to gw (they will be created as child devices)
                        // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. 
                        // If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
                        gw.present(CHILD_ID, S_DOOR);  
                      }
                      
                      
                      //  Check if digital input has changed and send in new value
                      void loop() 
                      {
                        debouncer.update();
                        // Get the update value
                        int value = debouncer.read();
                       
                        if (value != oldValue) {
                           // Send in the new value
                           gw.send(msg.set(value==HIGH ? 1 : 0));
                           oldValue = value;
                        }
                      } 
                      

                      And also add the battery masuring from :

                      #include <SPI.h>
                      #include <MySensor.h>
                      
                      #define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
                      #define N_ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
                      
                      #define CHILD_ID_MOISTURE 0
                      #define CHILD_ID_BATTERY 1
                      #define SLEEP_TIME 1800000 // Sleep time between reads (in milliseconds)
                      #define THRESHOLD 1.1 // Only make a new reading with reverse polarity if the change is larger than 10%.
                      #define STABILIZATION_TIME 1000 // Let the sensor stabilize before reading
                      #define BATTERY_FULL 3143 // 2xAA usually give 3.143V when full
                      #define BATTERY_ZERO 2340 // 2.34V limit for 328p at 8MHz. 1.9V, limit for nrf24l01 without step-up. 2.8V limit for Atmega328 with default BOD settings.
                      const int SENSOR_ANALOG_PINS[] = {A0, A1}; // Sensor is connected to these two pins. Avoid A3 if using ATSHA204. A6 and A7 cannot be used because they don't have pullups.
                      
                      MySensor gw;
                      MyMessage msg(CHILD_ID_MOISTURE, V_HUM);
                      MyMessage voltage_msg(CHILD_ID_BATTERY, V_VOLTAGE);
                      long oldvoltage = 0;
                      byte direction = 0;
                      int oldMoistureLevel = -1;
                      
                      void setup()
                      {
                        gw.begin();
                      
                        gw.sendSketchInfo("Plant moisture w bat", "1.5");
                      
                        gw.present(CHILD_ID_MOISTURE, S_HUM);
                        delay(250);
                        gw.present(CHILD_ID_BATTERY, S_CUSTOM);
                        for (int i = 0; i < N_ELEMENTS(SENSOR_ANALOG_PINS); i++) {
                          pinMode(SENSOR_ANALOG_PINS[i], OUTPUT);
                          digitalWrite(SENSOR_ANALOG_PINS[i], LOW);
                        }
                      }
                      
                      void loop()
                      {
                        int moistureLevel = readMoisture();
                      
                        // Send rolling average of 2 samples to get rid of the "ripple" produced by different resistance in the internal pull-up resistors
                        // See http://forum.mysensors.org/topic/2147/office-plant-monitoring/55 for more information
                        if (oldMoistureLevel == -1) { // First reading, save current value as old
                          oldMoistureLevel = moistureLevel;
                        }
                        if (moistureLevel > (oldMoistureLevel * THRESHOLD) || moistureLevel < (oldMoistureLevel / THRESHOLD)) {
                          // The change was large, so it was probably not caused by the difference in internal pull-ups.
                          // Measure again, this time with reversed polarity.
                          moistureLevel = readMoisture();
                        }
                        gw.send(msg.set((moistureLevel + oldMoistureLevel) / 2.0 / 10.23, 1));
                        oldMoistureLevel = moistureLevel;
                        long voltage = readVcc();
                        if (oldvoltage != voltage) { // Only send battery information if voltage has changed, to conserve battery.
                          gw.send(voltage_msg.set(voltage / 1000.0, 3)); // redVcc returns millivolts. Set wants volts and how many decimals (3 in our case)
                          gw.sendBatteryLevel(round((voltage - BATTERY_ZERO) * 100.0 / (BATTERY_FULL - BATTERY_ZERO)));
                          oldvoltage = voltage;
                        }
                        gw.sleep(SLEEP_TIME);
                      }
                      
                      int readMoisture() {
                        pinMode(SENSOR_ANALOG_PINS[direction], INPUT_PULLUP); // Power on the sensor
                        analogRead(SENSOR_ANALOG_PINS[direction]);// Read once to let the ADC capacitor start charging
                        gw.sleep(STABILIZATION_TIME);
                        int moistureLevel = (1023 - analogRead(SENSOR_ANALOG_PINS[direction]));
                      
                        // Turn off the sensor to conserve battery and minimize corrosion
                        pinMode(SENSOR_ANALOG_PINS[direction], OUTPUT);
                        digitalWrite(SENSOR_ANALOG_PINS[direction], LOW);
                      
                        direction = (direction + 1) % 2; // Make direction alternate between 0 and 1 to reverse polarity which reduces corrosion
                        return moistureLevel;
                      }
                      
                      long readVcc() {
                        // From http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
                        // Read 1.1V reference against AVcc
                        // set the reference to Vcc and the measurement to the internal 1.1V reference
                      #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
                        ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
                      #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
                        ADMUX = _BV(MUX5) | _BV(MUX0);
                      #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
                        ADMUX = _BV(MUX3) | _BV(MUX2);
                      #else
                        ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
                      #endif
                      
                        delay(2); // Wait for Vref to settle
                        ADCSRA |= _BV(ADSC); // Start conversion
                        while (bit_is_set(ADCSRA, ADSC)); // measuring
                      
                        uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
                        uint8_t high = ADCH; // unlocks both
                      
                        long result = (high << 8) | low;
                      
                        result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
                        return result; // Vcc in millivolts
                      }
                      

                      Do I "just" add these parts to the first sketch to have battery measuring working:

                      #define CHILD_ID_BATTERY 1
                      
                      #define BATTERY_FULL 3143 // 2xAA usually give 3.143V when full
                      #define BATTERY_ZERO 2340
                      
                      MyMessage voltage_msg(CHILD_ID_BATTERY, V_VOLTAGE);
                      long oldvoltage = 0;
                      
                      gw.present(CHILD_ID_BATTERY, S_CUSTOM);
                      
                      long voltage = readVcc();
                        if (oldvoltage != voltage) { // Only send battery information if voltage has changed, to conserve battery.
                          gw.send(voltage_msg.set(voltage / 1000.0, 3)); // redVcc returns millivolts. Set wants volts and how many decimals (3 in our case)
                          gw.sendBatteryLevel(round((voltage - BATTERY_ZERO) * 100.0 / (BATTERY_FULL - BATTERY_ZERO)));
                          oldvoltage = voltage;
                      	
                      	
                      long readVcc() {
                        // From http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
                        // Read 1.1V reference against AVcc
                        // set the reference to Vcc and the measurement to the internal 1.1V reference
                      #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
                        ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
                      #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
                        ADMUX = _BV(MUX5) | _BV(MUX0);
                      #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
                        ADMUX = _BV(MUX3) | _BV(MUX2);
                      #else
                        ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
                      #endif
                      
                        delay(2); // Wait for Vref to settle
                        ADCSRA |= _BV(ADSC); // Start conversion
                        while (bit_is_set(ADCSRA, ADSC)); // measuring
                      
                        uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
                        uint8_t high = ADCH; // unlocks both
                      
                        long result = (high << 8) | low;
                      
                        result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
                        return result; // Vcc in millivolts
                      }
                      
                      1 Reply Last reply
                      0
                      • Cliff KarlssonC Offline
                        Cliff KarlssonC Offline
                        Cliff Karlsson
                        wrote on last edited by
                        #12

                        I used the BinarySwitchSleepSensor sketch and tried adding the battery measuring info. Does this look ok If I only want the sensor to sleep until the magnetswitch attached to PIN 2 is opened and every 6h it reports battery?

                        // Enable debug prints to serial monitor
                        #define MY_DEBUG 
                        #define SLEEP_TIME 21600000 // Sleep time between reads (in milliseconds)
                        // Enable and select radio type attached
                        #define MY_RADIO_NRF24
                        //#define MY_RADIO_RFM69
                        
                        #include <SPI.h>
                        #include <MySensor.h>
                        
                        #define SKETCH_NAME "Mailbox +Battery"
                        #define SKETCH_MAJOR_VER "1"
                        #define SKETCH_MINOR_VER "0"
                        
                        #define PRIMARY_CHILD_ID 3
                        #define CHILD_ID_BATTERY 1
                        
                        #define BATTERY_FULL 3143 // 2xAA usually give 3.143V when full
                        #define BATTERY_ZERO 2340
                        
                        #define PRIMARY_BUTTON_PIN 2   // Arduino Digital I/O pin for button/reed switch
                        
                        
                        
                        
                        // Change to V_LIGHT if you use S_LIGHT in presentation below
                        MyMessage msg(PRIMARY_CHILD_ID, V_TRIPPED);
                        MyMessage voltage_msg(CHILD_ID_BATTERY, V_VOLTAGE);
                        long oldvoltage = 0;
                        
                        void setup()  
                        {  
                          // Setup the buttons
                          pinMode(PRIMARY_BUTTON_PIN, INPUT);
                         
                        
                          // Activate internal pull-ups
                          digitalWrite(PRIMARY_BUTTON_PIN, HIGH);
                        
                        }
                        
                        void presentation() {
                          // Send the sketch version information to the gateway and Controller
                          sendSketchInfo(SKETCH_NAME, SKETCH_MAJOR_VER "." SKETCH_MINOR_VER);
                        
                          // Register binary input sensor to sensor_node (they will be created as child devices)
                          // You can use S_DOOR, S_MOTION or S_LIGHT here depending on your usage. 
                          // If S_LIGHT is used, remember to update variable type you send in. See "msg" above.
                          present(PRIMARY_CHILD_ID, S_DOOR);  
                          delay(250);
                          present(CHILD_ID_BATTERY, S_CUSTOM); 
                        }
                        
                        // Loop will iterate on changes on the BUTTON_PINs
                        void loop() 
                        {
                          uint8_t value;
                          static uint8_t sentValue=2;
                        
                          // Short delay to allow buttons to properly settle
                          sleep(5);
                          
                          value = digitalRead(PRIMARY_BUTTON_PIN);
                          
                          if (value != sentValue) {
                             // Value has changed from last transmission, send the updated value
                             send(msg.set(value==HIGH ? 1 : 0));
                             sentValue = value;
                          }
                        long voltage = readVcc();
                          if (oldvoltage != voltage) { // Only send battery information if voltage has changed, to conserve battery.
                            send(voltage_msg.set(voltage / 1000.0, 3)); // redVcc returns millivolts. Set wants volts and how many decimals (3 in our case)
                            sendBatteryLevel(round((voltage - BATTERY_ZERO) * 100.0 / (BATTERY_FULL - BATTERY_ZERO)));
                            oldvoltage = voltage;
                          }
                          
                        
                          // Sleep until something happens with the sensor
                          sleep(PRIMARY_BUTTON_PIN-2, CHANGE, SLEEP_TIME);
                        } 
                        
                        long readVcc() {
                          // From http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/
                          // Read 1.1V reference against AVcc
                          // set the reference to Vcc and the measurement to the internal 1.1V reference
                        #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
                          ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
                        #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
                          ADMUX = _BV(MUX5) | _BV(MUX0);
                        #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
                          ADMUX = _BV(MUX3) | _BV(MUX2);
                        #else
                          ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
                        #endif
                        
                          delay(2); // Wait for Vref to settle
                          ADCSRA |= _BV(ADSC); // Start conversion
                          while (bit_is_set(ADCSRA, ADSC)); // measuring
                        
                          uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
                          uint8_t high = ADCH; // unlocks both
                        
                          long result = (high << 8) | low;
                        
                          result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
                          return result; // Vcc in millivolts
                        }
                        
                        1 Reply Last reply
                        0
                        Reply
                        • Reply as topic
                        Log in to reply
                        • Oldest to Newest
                        • Newest to Oldest
                        • Most Votes


                        15

                        Online

                        11.8k

                        Users

                        11.2k

                        Topics

                        113.2k

                        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