It’s that magical time of the year again when being nice really pays off! After all, you never know who might be watching through the window…
Story
Living just a few sleigh rides away from the Arctic Circle and the legendary Korvatunturi—Santa’s real home—we Finns are no strangers to his elves (or even Santa himself) peeking through our windows to check on our behavior. Typically we never see them in action, but instead only notice tracks in the snow or some fur hair from reindeers the morning after the visit.
But what if we could outsmart them with some clever tech? Well, now we can get alerts when Santa’s crew is sneaking around!
Solution
The solution? Build a device that peers out the window, detects if someone’s looking in, and sends an alert only when it recognizes Santa. No false alarms here—your neighbors, friends, and even foes won’t trigger it!
One way is to use a camera connected to a microcontroller or computer and use a machine learning model trained to recognize Santa. The drawback is that you might need to spend up to $100 for a good enough camera and microcontroller and spend hours of building a ML model.
An even more elegant—and budget-friendly—approach is to use a Particle Photon 2 and a Person Sensor from Useful Sensors. At the time of writing both of them are priced below $10! Depending on how you want to get alerted, through a notification or some more mechanical way, you might need to spend a few more dollars at hardware.
Since I still had a previous project setup that used the M2 SoM Evaluation Board and a B524 SoM, I decided to use the same setup, but there’s nothing to stop you from using other Particle boards like the Photon 2 instead. In this project physical bells are jingled with the help of the servo motor when Santa is detected.
How does it work?
From a user perspective, the process is straightforward:
- The sensor continuously checks for faces in its view.
- If a face is detected:
- It checks whether the face matches one of the eight identities it has been calibrated to recognize.
- If a matching face (= Santa) is found, the Particle device signals the servo accordingly.
- A mobile notification is sent via Pushover to let you know Santa’s in town!
Below a GIF-video demonstrating the behavior, here’s a short video clip with sound. The Person Sensor indicates with its green LED (barely visible in the Youtube video) that there are faces visible in its view, but the program acts only when it recognizes Santa. The Person Sensor is almost touching the window to reduce glaring from the window glass.
Bill of materials
- B524, it has cellular and Bluetooth connectivity (no Wi-Fi), but if you want Wi-Fi instead of cellular connectivity, a Photon 2 dev board can be used and is more cost effective
- Optional, but recommended
- separate power source for the servo or actuator, especially if the latter is power hungry or under load
- Optional
- LiPo battery, some options
- Linear actuator kit, you can replace this with any servo, push rod, or larger linear actuator
- Qwiic Cable – Grove Adapter (100mm), this if you want an easy way of connecting the Person Sensor to the Grove port on the M.2 SoM Eval Board, another option is to use separate jumper wires.
Skills & tools required
For this project, you’ll need
- A Particle account and basic understanding of the Particle platform’s capabilities.
- Particle-flavored, Arduino-style, C++ development.
- No soldering required
- Optional but strongly recommended:
- 3D-printed case for the linear actuator, this can be fastened on any standard camera tripod or the gooseneck I used
- 3D-printed enclosure and back plate for the Person Sensor
Assembly
Only a few steps are needed to assemble the system:
- Attach the B524 to the Eval Board
- Connect the cellular antenna to the Eval Board (the Bluetooth antenna can be left unconnected for this project).
- Connect the Person Sensor to the Eval Board, ensuring that you connect it to the I2C Grove port, not the analog port!
- Optional:
- Connect a battery
- If using a 6V servo or actuator like in this project, it can be powered temporarily from the Eval Board. For long-term use, a separate power source is recommended.
- In following images following wire colors are used: white = signal, black = ground, red = power
- Connect the servo signal wire to PWM0 (D4 in the program)
- Connect the ground wire to GND on the board
- Connect the power wire to VCC on the board
- Power the B524 using the SOM power switch
- Connect the Eval board to your computer via an USB-cable
- If using a battery, charge it using the BAT POWER switch
Software apps and online services
- Visual Studio Code with the Particle Workbench extension installed
- Optional if you want to get an electronical Santa notification in addition to the mechanical
- Particle’s Webhook Integration for sending notifications to your mobile
- Twilio, Pushover, or similar services for sending SMS or notifications
- The complete program can be found here
Set up a Webhook integration to Pushover
This assumes you are using the Pushover service, but the overall principle is similar, regardless of chosen service.
Pushover service
- Create an account at Pushover (or similar service, e.g. Twilio)
- Create an application in Pushover
- Take a note of the User Key and API token
- Also install the Pushover app on your mobile device to get notifications
User key field in Pushover
API Token/key in Pushover
Particle Webhook
- In the Particle console, Go to
Integrations
- Add a new integration
- Scroll down and select
Custom Webhook
- Select ´Custom template`
- Paste in the code below
- Replace the
token
anduser
in the code with the ones from your chosen service event
– in this case “face_detected” – should be same event as you are publishing from your code- Test the integration, if everything is set up correctly, you should get a notification on your mobile device
- If you use Pushover, the notification on your mobile is received through the Pushover service, not as a SMS.
{ "name": "Identified as person: ", "event": "face_detected", "responseTopic": "{{PARTICLE_DEVICE_ID}}/hook-response/{{PARTICLE_EVENT_NAME}}", "disabled": false, "template": "webhook", "url": "https://api.pushover.net/1/messages.json", "requestType": "POST", "noDefaults": true, "rejectUnauthorized": true, "unchunked": false, "dataUriResponseEvent": false, "form": { "token": "token to selected service", "user": "user id at selected service", "title": "Door opened by person ", "message": "{{{PARTICLE_EVENT_VALUE}}}" } }
Calibrate the Person Sensor
The idea with the Person Sensor is that it should behave similarly as any other sensor, i.e. send data back to the calling device. It is pre-programmed with algorithms that detect nearby faces, and return information over a simple I2C interface. It is designed to be used as an input to a larger system and be treated like any other sensor where power and information are provided through the I2C interface.
All this means that apart from a few configurations options, the sensor can’t be programmed, which also makes it extremely tamperproof (100 %?). But how do we then get it to not only recognize if a face is seen, but also to identify the face? The solution here is called calibration.
Calibration
While calibration can technically be done stand-alone, it’s much more practical to connect a computer. This way you can verify the functionality via the terminal window:
- Position the person whose face you want to store in front of the sensor. When the face is detected, the green LED will light up.
- Within ~200 ms, press the
Mode
button on the Eval Board to store the face’s features and assign it an ID in the sensor’s EEPROM. Up to eight faces can be stored, with IDs ranging from 0 to 7. - Repeat this for each face you’d like to store.
Below the function which is reacting on the button event. The “magic” happens in this code line – person_sensor_write_reg(NEXT_ID_REGISTER, nextFaceID);
– which stores the face’s features and corresponding ID into EEPROM.
void button_clicked(system_event_t event, int param)
{
int times = system_button_clicks(param);
faceIDs[nextFaceID] = nextFaceID; // Assign new ID to face
person_sensor_write_reg(NEXT_ID_REGISTER, nextFaceID);
Serial.printlnf("******** %d ********", nextFaceID);
nextFaceID++;
}
Mode button
Verify facial identification
Both during the calibration process and under normal use you can follow what the program is doing via the terminal window. To open this, open the Command Palette (Ctrl+Shift+P) and search for Particle: Serial Monitor
. If you want to redo the calibration, just recycle power to the device and start the calibration again.
Apart from verification and troubleshooting purposes, you should also take a note of which face is having which ID. E.g. if your face were registered with ID 1, and Santa’s with ID 4, you need to remember this for next step.
Set up the Santa detection alarm
If you want the servo to react to specific faces, you need to change this code (around line 156): (face-> id == 4)
to include the face or faces you want to be able to unlock the door. In this case Santa has id #4, and while other faces like the president of Finland and Mona Lisa are identified by the Person Sensor, we don’t take any actions on them.
Depending on the mechanical alarm device you’ve created, you might want to change how many times the servo is moving back and forth, in this case with the variable jingles
, or the end positions and speed of the servo in the santa
-function.
#ifdef santa if (face-> id == 4) { int jingles = 6; for (int jingle = 0; jingle < jingles; jingle++) santa(); } #else void santa() { int speed = 5; for(servo_pos = 0; servo_pos < 175; servo_pos += speed) // goes from 0 degrees to xxx degrees { // in steps of 1 degree myservo.write(servo_pos); // tell servo to go to position in variable 'pos' delay(5); // waits for the servo to reach the position } delay(200); for(servo_pos = 175; servo_pos>=1; servo_pos -= speed) // goes from xxx degrees to 0 degrees { // in steps of 1 degree myservo.write(servo_pos); // tell servo to go to position in variable 'pos' delay(5); // waits for the servo to reach the position } }
CONCLUSION
The Santa Detector worked even better than I expected—especially given the three layers of glass in the windows.
As you’ve seen from the video and still pictures, the Person Sensor can distinguish between different faces and react accordingly. A further improvement to the program would be to utilize the confidence score reported by the sensor, e.g. only taking actions if the confidence is > 80 %. Another practical improvement is to use longer wires to the sensor and the servo so they can easier be placed further away from the Particle board.
Feel free to clone my Github repo to build your own Santa Detector!