Mailbox alarm with moteino

Here is how I build my alarm, quite simple to do and to get push messages from prowl or mail.
For Gateway I use a moteino connected to a raspberryPi model B+ as you can see from the pictures below.

Feel free to ask questions or guidance if you want to build one by you own.

The work in pictures:
Gateway

Mailbox alarm

The result

Prowl push msg

Schematic:
Mailbox moteino schematic

Arduino IDE Code:

    #include <RFM69.h>
    #include <SPI.h>
    #include <LowPower.h>
    #include <PinChangeInt.h>        // Two lines to include pinChangeInt library
 
    //======================================================================
    // NOTE!  The logic of mailbox OPEN vs CLOSED has been reversed for D4
    // D4 = HIGH is Mailbox OPENED (magnetic switch open)
    // D4 = LOW  is Mailbox CLOSED (magnetic switch closed)
    //======================================================================
 
 
    #define NODEID 2 // unique for each node on same network
    #define GATEWAYID 1
    #define NETWORKID 100 // the same on all nodes that talk to each other
    #define FREQUENCY RF69_868MHZ
    #define ENCRYPTKEY "sampleEncryptKey" // exactly the same 16 characters/bytes on all nodes!
    #define ACK_TIME 30 // max # of ms to wait for an ack
    #define LED 9 // Moteinos have LEDs on D9
    #define SERIAL_BAUD 115200
    #define D4 4
 
    #ifdef SERIAL_EN
      #define DEBUG(input)   {Serial.print(input); delay(1);}
      #define DEBUGln(input) {Serial.println(input); delay(1);}
    #else
      #define DEBUG(input);
      #define DEBUGln(input);
    #endif
 
    RFM69 radio;
    bool promiscuousMode = false; // Set to 'true' to sniff all packets on the same network
    bool sentOpen = true;
    bool stateCheck=LOW;
 
    uint32_t switchTime=0;      // variable to monitor when the switch last changed state (for debouncing)
    #define  DEBOUNCE_TIME  50  // give it 50 mS to debounce a noisy switch
 
    // Add function to catch interrupt, doesn't need to do anything as the interrupt is all that's needed to wakeup
    void wakeUp(void)   
    {
    }
 
    void setup()
    {
 
    //Setup the pins
      pinMode(LED, OUTPUT);
      pinMode(D4, INPUT_PULLUP);  // TOMWS: Use internal pullup as it's easier than adding an external one...
 
    //Start the Serial
      Serial.begin(SERIAL_BAUD);
      delay(10);
 
    //Initialize the radio
      radio.initialize(FREQUENCY,NODEID,NETWORKID);
      #ifdef IS_RFM69HW
      //radio.setHighPower(); // Uncomment only for RFM69HW!
      #endif
      radio.encrypt(ENCRYPTKEY); // Turn encryption ON
      radio.promiscuous(promiscuousMode);  // TOMWS: This is not necessary if not using this mode
      char buff[50];
      sprintf(buff, "\nTransmiting at %d Mhz...", FREQUENCY==RF69_433MHZ ? 433 : FREQUENCY==RF69_868MHZ ? 868 : 915);
      Serial.println(buff);
    }
 
 
    void loop()
    {
 
      if (digitalRead(D4) == HIGH)  // If the mailbox is opened
      {
        switchTime = millis();   // record when we saw the switch change state
        stateCheck = LOW;
        if (sentOpen == false)  // have we already sent this?
        {
          // no, send it now
          if (radio.sendWithRetry(GATEWAYID, "MAIL:OPN", 8))
          {
            Serial.println(" nothing...");
            // Blink(LED,3);
          } else
          {
            Serial.println("Sending Open mailboxstatus to gateway..");
          }
          sentOpen = true;
          radio.sleep();  // we're done with the radio, make it sleep to save power immediately
        }
      } else 
      {
        switchTime = millis();   // record when we saw the switch change state
        stateCheck = HIGH;
        if (sentOpen == true)  // have we already sent this?
        {
          delay(10000);
          // no, send it now
          if (radio.sendWithRetry(GATEWAYID, "MAIL:CLS", 8))
          {
            Serial.println(" nothing...");
 
          } else
          {
            Serial.println("Sending closed, once... ");
          }
          sentOpen = false;
          radio.sleep();  // we're done with the radio, make it sleep to save power immediately
        }
      }
 
      while ((switchTime-millis()) < DEBOUNCE_TIME)  // debounce the switch
      {
        if (digitalRead(D4) == stateCheck) switchTime = millis();  // if we sense a 'bounce' reset the timer
      }
 
      Serial.flush();  // need to do before sleeping.
 
      // Allow wake up pin to trigger interrupt on either edge.
      PCintPort::attachInterrupt(D4, wakeUp, CHANGE);  // New code to trap interrupt on pin change
 
      LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);  // Changed to SLEEP_FOREVER so that only interrupts wake up, no WDT used
 
      // WOKEN UP!  Disable further interrupts until debounced
      PCintPort::detachInterrupt(D4);  // disable interrupts until debounced
 
    }
 
    void Blink(byte PIN, int DELAY_MS) // Local led blinking function
    {
     // pinMode(PIN, OUTPUT);
     // digitalWrite(PIN,HIGH);
     // delay(DELAY_MS);
     // digitalWrite(PIN,LOW);
    }

Shopping list:
Kjell o Co www.kjell.com
Artnr:
39780 Batterycase 4xR6 (AA) (fits perfect in the Box, had to remove some plastic)
89024 Box Höjd: 20 mm
42480 AA Litium 4-pack

Leave a Reply