This is also published on the MakeItZone forum website.
Our rough requirements for the LockBox/Safe software are:
- There will be an admin mode that allows the mentor running the session to adjust the number of PuzzleBits being used.
- The lock-master awaits messages from the PuzzleBits that indicate they have been solved. When all PuzzleBits are solved, the servo is activated and the lock-box unlocked.
- Prevent (obvious) cheating by checking the serial number sent from each MicroBit
I implemented this as a basic state machine, with the following key states:
Reset (starting point): initialize variables and set servo to a specified rotation.
Configuring: Allow the user to enter the number of unique PuzzleBits required to send an unlock message to fully open the latch. Entry is via the A and B buttons. The A+B keys exit this state.
Running: When an unlock message arrives via radio, and it's from a PuzzleBit we haven't had an unlock from, rotate the lock 1/(number of puzzle bits) towards being opened. A PuzzleBit can also send a lock radio message that will remove it from the list of known PuzzleBits and rotate the lock 1/(number of puzzle bits) towards being closed. Can be moved back to the reset state by pressing the A+B keys.
Unlocked: The lock is open- hooray! Displays a success animation.
Override: There is a "Konami code" (A, B, B, A) that can be entered in the running state. This will open the lock without resetting the current completion state. Useful if you need to check on what's hidden in the lockbox. Can be escaped, moving the lock back to it's previous level of "unlock"-edness by pressing A+B.
It's too complicated for beginners to look at, but can be a good thing to review at the end, once they have made some PuzzleBit applications.
Here are versions you can manipulate/copy/read:
- there are minAngle and maxAngle variables in the onStart callback that will need to be tweaked to your servo. They represent the lock being fully closed and fully open.
These are the core of the exercise: the PuzzleBits are MicroBits that are running an application that provides the end user with a problem to solve. When the puzzle is solved, it sends an Unlock message to the LockBox.
The coding participants are given the task of creating the puzzle applications.
Template PuzzleBit Application
Links to source code you can manipulate/copy/read:
This application is both a test tool for the LockBox, and a simple template to be used as the basis for participants. For beginners I may not explain what `functions` are, but just from the visual construction, many "just get it" before being presented a formal description.
It simply waits for button presses and sends an `unlock` message when button `A` is pressed, and `lock` when button `B` is pressed.
- by default MicroBits don't send a unique ID with radio packets. So the lock can identify each PuzzleBit we need to enable the sending of the device unique ID with radio packets. The radio set transmit serial number command is in the radio...more sub menu.
Example Compass & Button PuzzleBit
And finally, a very simple example puzzle application that uses a sensor, a button, and introduces Boolean logic:
Links to source code:
The puzzle: turn the MicroBit to the correct orientation and then press the A key to trigger sending the unlock radio message.
Some notes discovered while creating this and showing it to some beginners:
- the event-callback system is very intuitive, but dealing with syncing state between blocks of code, using variables, is far more complicated than explaining and implementing a polling loop.
- onStart is not guaranteed to complete before any forever blocks. Explaining random startup glitches (eg holding a button after reset and having that handler start before onStart has finished) is complicated and frustrating. Implementing guard states/variables is a giant leap, and adds a lot of boilerplate code all over the place.
- Instead of call-backs and variables you can test the state of buttons and the compass bearing
- There is a bug with the accelerometer gestures if you don't use callbacks. They'll never trigger. You have to kick the accelerometer framework and get it running so that there is input data flowing into the gesture recognizer. I found that assigning an acceleration measurement to a dummy variable in the onStart callback is enough.
Now we have the physical and software building blocks needed to run a session. The next blog post will cover how we set up and ran sessions.