Mailbox Detection System
- VJ

- Sep 6, 2020
- 7 min read
Updated: Sep 7, 2020

The inspiration for this project is that a few days ago our package was stolen. This mechanism will immediately alert us when someone drops off a package in our mailbox, so we can immediately pick it up. If anyone unwanted tries to open our mailbox we can instantly go outside to see them. It is an alert system that informs us when our mailbox is opened. There are two parts that need to be made, the receiver and the sender modules. They use a HC12 radio module to reduce cost and it fits our needs.
Materials:
Hardware:
In this project we use two modules. One will be kept in the house constantly connected to an external power supply in the wall. The other will be inside the mailbox sleeping ready to wake up and alert if the mailbox door is opened. The way we tell if the mailbox door opened is using the photoresistor. The resistor catches light from the open mailbox and alerts the module inside the house using the HC12.
Mailbox Module:
For this project longevity is the most important part. We want the system to last for as long as possible on a minimal battery. That is why we use the attiny85 and the MOSFET. The attiny sleep mode will be covered in the software but the MOSFET acts as a switch to turn on and off the radio module to optimize power. The current system should last for a year with no charge, using a 1000maH liPo battery. if you increase the maH then the time increases. This is optimal so we can just leave the module running in the mailbox without recharge or external power supply. The mailbox module has to be as small as possible to not disturb the mailman. When the photoresistor detects light, then it sends a signal to the HC12 and the module inside the house goes off.
Circuit:
HC12 VCC --> liPo VCC
HC12 GND --> MOSFET Drain 2
HC12 Rx --> attiny pin 6
HC12 Tx --> attiny pin 5
Photoresistor + --> attiny pin 1
Photoresistor - --> liPo GND
attiny pin 4 --> liPo GND
attiny pin 8 --> liPo VCC
MOSFET Gate 1 --> attiny pin 2
MOSFET Source 3 --> liPo GND
The HC12 ground gets connected when the MOSFET switch is activated by pin 2 (digital pin 3) on the attiny. This saves power when the attiny isn't sending signals. The photoresistor resets the attiny (covered in software) when light sources the GND current to pin 1. Attiny pin 4 and 8 are GND and VCC respectively and need to be connected to run.
This is what the module looks like after I finished soldering it. The female headers are for the power and the photoresistor. The attiny85 is hidden underneath the body of the HC12 for space efficiency. I want this as small as possible so it doesn't bother the mailman, and also so it isn't readily visible without bending down.

This is how our module sits inside the mailbox. I soldered it all together as small as i could to be inconspicuous and used double sided tape and hot glue to keep everything secure. I also bent the photoresistor to face the door and hotglued the module to the liPo battery. The liPo battery is stuck to the ceiling using double sided adhesive pads.
Receiver Module:
The receiver module is simple and easy. Its job is simply to buzz if it gets a signal from the other HC12, and since it has an infinite power supply from the wall socket I don't to worry about longevity. When the signal is received it just rings a buzzer for as long as you would need, alerting you that the mailbox was opened.
Circuit:
HC12 VCC --> Nano VCC
HC12 GND --> Nano GND
HC12 Rx --> Nano Rx
HC12 Tx --> Nano Tx
Buzzer GND --> Nano GND
Buzzer VCC --> Nano GPIO 3
Software:
Mailbox Module:
The software in this project is the really tricky part because of the need for energy conservation. Also, there were a few problems I ran into while building this project, and many of the fixes came into the code.
HC12:
Two of the main problems were that 1. the HC12 used a large amount of power and 2. the attiny doesn't come with a serial communication. An easy fix to the serial problem would be to use the software serial library, but I later found out that you could not use software serial and pin interrupt sleep mode in the same project. Originally I was going to use pin interrupt, so I had to scrap that idea of keeping the attiny asleep that way. The way I fixed the HC12 energy consumption issue was by using a MOSFET switch to toggle the GND of the liPo and complete the circuit. This way we could turn the HC12 on and off when we need it. Previously the plan was to directly wire pin 2 to the HC12 VCC, but the power coming from pin 2 was not sufficient to efficiently send signals, so I went with the MOSFET taking a smaller current to toggle the bigger current.
Sleep mode:
Originally I wanted to use a pin interrupt sleep mode to wake up the attiny, but usually the pin interrupt reacts to digital inputs like a button, not analog inputs like the photoresistor. The solution I came up with was to use a transistor to boost the current of the output analog value of the photoresistor and also to increase the resistance on the resistor circuit to increase current flow to the interrupt pin. Unfortunately it all became useless when I found out that you could not use pin interrupt and software serial together. The way I got around that problem was by using a native interrupt - the reset pin. The photoresistor would reduce resistance when exposed to light, and GND would flow to the reset pin. This reset the code and run a default sequence. The sequence would send a signal to the inside module and then go back to sleep.
To clarify: the module has an initial start up and sends a signal to the receiver module inside. Then it goes to sleep indefinitely. What wakes it up is the reset pin on the attiny, not any usual wake up protocol. This is how we can have a pin interrupt with software serial.
#include <avr/sleep.h>
#include <SoftwareSerial.h>
#define KEEP_RUNNING 10000
#define BODS 7 //BOD Sleep bit in MCUCR
#define BODSE 2 //BOD Sleep enable bit in MCUCR
SoftwareSerial HC12(0, 1);Here all thats happening is we are declaring the sleep and Software serial libraries, and a few things we would need for the sleep mode.
void setup(void)
{
pinMode(3, OUTPUT);
digitalWrite(3, HIGH);
delay(5000);
HC12.begin(9600);
}
In the setup we declare GPIO 3 as an output and write it to high(GPIO 3 controls the HC12 and we need it on to transmit). We also begin the HC12 software serial.
void loop(void)
{
delay(1000);
HC12.println("yo");
delay(KEEP_RUNNING);
digitalWrite(3, LOW);
goToSleep();
}
In the loop we just send a message "yo" to the receiver module. After that we turn off the HC12 module and send the attiny to sleep mode.
void goToSleep(void)
{
byte adcsra, mcucr1, mcucr2;
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
MCUCR &= ~(_BV(ISC01) | _BV(ISC00)); //INT0 on low level
GIMSK |= _BV(INT0); //enable INT0
adcsra = ADCSRA; //save ADCSRA
ADCSRA &= ~_BV(ADEN); //disable ADC
cli(); //stop interrupts to ensure the BOD timed sequence executes as required
mcucr1 = MCUCR | _BV(BODS) | _BV(BODSE); //turn off the brown-out detector
mcucr2 = mcucr1 & ~_BV(BODSE); //if the MCU does not have BOD disable capability,
MCUCR = mcucr1; // this code has no effect
MCUCR = mcucr2;
sei(); //ensure interrupts enabled so we can wake up again
sleep_cpu(); //go to sleep
//sleep_disable(); //wake up here
//ADCSRA = adcsra; //restore ADCSRA
}
//external interrupt 0 wakes the MCU
ISR(INT0_vect)
{
GIMSK = 0; //disable external interrupts (only need one to wake up)
}All of this code just takes care of making the attiny sleep. You may notice that I commented out the lines that disable sleep mode. This is so the only thing taking it out is the reset on the attiny.
With this code, every time the reset pin gets activated a signal is sent. The delays in the loop and setup aren't necessary, and cause a delay between when the mailbox is opened and when you get the signal. If needed, you can remove them.
Here is the full code:
Receiver Module: The code for the inside module is ridiculously simple, and takes no time or understanding at all. Therefore I will just paste the code and give a brief description.
void setup() {
Serial.begin(9600);
pinMode(3 , OUTPUT);
}
void loop() {
while (Serial.available()) {
if(Serial.read() == "yo") {
digitalWrite(3 , HIGH);
delay(1000);
digitalWrite(3 , LOW);
}
}
}Because we wired the Rx and Tx directly to the HC12 Rx and Tx, there is no need for a software serial because we are using the built in serial port. All we do is check that if there is an input "yo", then we activate the buzzer on GPIO 3. If this code doesn't work, you can also try replacing "read()" with "readString()".
To conclude, this module is how we can instantly get our mail the second it arrives. It can also alert us if someone unwanted opens our mailbox by sending a signal we can respond to. This project took a good amount of time and effort to work, but it was definitely worth it!
Preferably you wouldn't want a delay in a scenario like this, but I added it into my code for testing reasons. Full disclosure, this was a friend, but if it wasn't I would be glad to catch the perpetrator!
Edit: After making the project for a few days I realized that a better option would be to use a PIR digital output motion detection module instead of the photoresistor. We would have the output trigger the reset pin, and everything in the code would stay the same, but it would work more efficiently and in the night as well as the day. You could also install it at the very back of the mailbox, so it would be less obtrusive. If i coul make this again, I would definitely use the PIR vs the photoresistor!



Comments