If you want to catch someone in the act snooping at your secret hollow book safe, you can build a small motion or light detecting alarm using a Circuit Playground Express (CPX) and MakeCode.

When the CPX detects motion or light, meaning the book has been moved or opened, you can have it sound an alarm. Then, you can rush into the room and catch the spy red handed!

What if you're not around, and the spy resets the alarm? You can program the equivalent of the proverbial "hair taped across a door frame" trick by setting a color pattern in advance that changes if the CPX is disturbed. The spy will never know that they've left evidence of their misdeeds!

Motion Detection

First, let's build a motion detection alarm.

If you aren't familiar with using Make Code to create programs for your Circuit Playground Express, take a look at this excellent getting started guide. Once you're comfortable writing and uploading programs to your CPX, return to this page.


We'll use the built-in accelerometer on the CPX to detect when the book is taken off the shelf laid on it's "back" to be opened. The accelerometer can tell it's orientation relative to the Earth's gravitational pull. When the CPX is laid "face up", for example, the accelerometer will report a strong pull value on the negative Z-axis. 

In Make Code we'll use the accelerometer input block (found initially in the input category as "on shake") to check orientation. By switching the dropdown to "face up", it will run whenever the board is on its back with the positive Z-axis facing up, away from the ground.

No alarm sounds in this orientation
Z-axis facing up, alarm sounds!

The rest of the code is necessary to "flip a switch" with a variable named "alarm" when the CPX is face up. By setting the "alarm" variable's value to 1 when the board is set face up, we can then have the siren continue to sound even when the board orientation changes. This means the spy snooping at your safe can't turn it off just by re-placing the book on the shelf!

You can download the code from the window below, and then place it on your CPX to test it out! Once you're annoyed by the sound, you can reset the CPX to stop it.

Silent Detection

The motion alarm works great if you're nearby and can catch your spy in action. But, what about an alarm that will let you know later if your book safe has been opened, without alerting the spy? Perhaps you've planted some counter-intelligence or misinformation you want the spy to see, and just want to know for certain that it's been accessed.

We'll use a light detector as the input, and then, a secret pattern of LEDs to know when the book has been opened. The sneakiest part is this: even if the spy resets or turns off and on the alarm, you'll know about it!

This program is a little bit more involved than the motion detector, but mostly because it needs to keep track of a few different states.

Here's the basic flow:

  • Turn on the CPX
  • Two NeoPixels will turn red
  • Arm it by flipping the switch right and pressing button A
  • The NeoPixels all turn off
  • You have two seconds to close it in the book to keep light off of the light detector
  • When the book is opened for the first time, light will trip the "alarm", turning on all NeoPixels to a light blue for two seconds, then switch to just two yellow NeoPixels -- this is how you know someone's been snooping!

If you check the book alarm and see it turn blue and then yellow, you know that nobody else has tripped it yet. If you check and the lights are already yellow, then it has already been tripped.

And, if the spy freaks out and tries to reset the alarm or turn it off and on, you'll know it, because the lights will be red. Only by entering the secret switch/button combination can you re-arm the alarm!

Tracking State

Once you've worked out the logical flow, the implementation comes down to creating variables that keep track of the various states, inputs that change these variables, and if-else statements that change the NeoPixels depending on the states of the various variables. These are:

  • armed 
  • switchCode
  • buttonCode
  • tripped
  • firstTrip

You will then create inputs, such as "on button A click" to switch the "buttonCode" variable from to when pressed.


You will then create inputs, such as "on button A click" to switch the "buttonCode" variable from to when pressed. These are:

  • on button A click
  • on button B click
  • on switch moved right
  • on switch moved left
  • on light bright

If-Else Comparisons

Based upon the established logical flow, the comparisons used in the if-else statements are:

  • if the system hasn't been tripped (tripped == 0), check the button and switch states
    • if buttonCode == 0 and/or switchCode == 0, the system is unarmed, two NeoPixels are lit red
    • if buttonCode == 1 and switchCode == 1, set the NeoPixels black, wait 2 seconds, arm the system
      • if the system is armed and the light sensor is triggered by light, set the tripped state to 1, and set the buttonCode to 0 and switchCode to 0, so they won't keep re-arming things over and over
  • if the system has been tripped and it is the firstTrip, set all NeoPixels blue, pause 2 seconds, then switch the firstTrip state to 0
  • if the system has been tripped, but it is not the firstTrip,  set two NeoPixels to yellow

This guide was first published on Feb 14, 2018. It was last updated on Feb 14, 2018.

This page (Building the Alarm) was last updated on Feb 12, 2018.

Text editor powered by tinymce.