Shake the box to find what you get in this magic 8-ball styled Christmas gift game.
|1||XC4410||Arduino Uno Compatible Board|
|1||XC3728||1.3" Monochrome OLED|
|1||XC3732||Tri Axis Digital Tilt Sensor|
|1||WC6028||Plug Socket Leads|
|1||PH9251||Battery DC Lead|
|UNO||OLED screen||Tilt sensor|
The wiring for this is fairly simple as we only have to connect up two modules. The OLED screen is an SPI device so we connect it up through the SPI ports with some extra digital pins for signaling (
The Tri-axis tilt sensor is a standard
i2c device with
SCL. It does have interrupt pins but we don't need to worry about them for now as we are just waiting for the device to talk, rather than getting the device to tell us when it can talk.
For this shake the box present, you'll probably want to tape or hot glue the connections to the arduino so they don't come undone when you shake the box too hard. You'll effectively be mounting everything in the box as shown.
When doing something like the OLED connections, it's eaiser to keep all of the wires attached to each other from a fresh pack of WC6028.
It also makes it easier when poking through any present-styled box if you aim to put this in. For our purposes we used the box from the duinotech starter kit.
Once it's all mounted in the box, you can decorate it however you want like a small present.
For this project you will need to use the arduino library manager to download some libraries:
Usually it is quicker and easier to first draw the images in MS Paint, as they have the handy shapes and lines that we can use to make the picture how we want.
Edit the file properties so that it is a black and white image of size 128 x 64. For instance, we are going to go with something like this: (zoom in 800% so it's easier to see while working)
Once you have made your image, select all (
Ctrl-A) and copy (
Ctrl-C) to paste into gimp (
In gimp, there's a few extra tools, such as 360 degree rotation, and other things.
Firstly download and run GIMP.
If you did not create an image with MS paint, you can create a new image of size 128x64 pixels as shown in the picture below:
or otherwise get your image and reduce it in size to 128 x 64 via
Image -> Canvas Size.
As the OLED screen we are using only has 1 bit data (ie: on or off) we must change the image mode to be similar 1-bit sized.
Firstly go to
Image -> Mode -> Indexed.. And set the colormap to the
The filetype we want for the OLED is actually an
XBM filetype; Go to
File -> Export As and choose XBM with the "Select File Type (By Extension)"
you can name the file something easy to remember, such as
Once you have exported the file as XBM, you can then rename it to
santa.h file. This is so the arduino IDE can pick it up and include it normally. XBM is an old file format used in the early days of computers which were just straight
C code, such as what's seen below:
We've managed to fit 2 images into the program this way, but space is limited so it might not be a good idea to fit a 3rd image unless you get something big and chunky like the XC3812 SAMD12 board.
The basis of this is using the XC3732 Tri Axis tilt sensor to detect the magnitude of acceleration that the box is going under
We use Pyagrath's Theorem to find the total magnitude, and use a Rolling, or Simple Moving Average to smooth out spikes in the data, so a sharp knock will not trip the shake counter (as the spike in data will be smoothed out). If you want to see this in action, uncomment the
RAW_LOG define near the top of the code.
After about 5 shakes, we show another image on the OLED, and after 10 shakes, we generate a random number and "roll" to the gift that the person gets.
There's very limited memory on the ATMEGA 328P chip, which isn't made any easier with the variety of feature-full libraries that are available through the library manager. For this project, the memory space very quickly ran out of room trying to manage both the accelometer and oled objects, causing a reboot once it reaches to a certain point in the program.
To overcome this we used some resource allocation in our core methods:
Here, each method creates the object that it is managing. For instance, the
draw() function creates the
U8g2lib object, draws things on the screen, and then deletes the object, thus freeing the memory. Similarly, the
measureShake() will create the accelerometer management object, take readings, and store it in the buffer to be averaged later, before deleting the accelometer object again.
In many applications this is slow to do, but for our purposes, it actually functions fine and utilises more of the speed that is available for us via the ATMEGA328P.