Create an Electric Spirit Level
Use this spirit level to quickly and easily display the tilt of any object attached!
Created by Kaitlyn from Raffles Institution.
- Learn to use tilt readings from the micro:bit’s in-built accelerometer
- Learn to work with micro:bit’s 5x5 LED Display
Pre Coding: Connect your Micro:Bit
- Connect the BBC micro:bit to your computer using a micro USB cable.
Step 0: Code Flow
- Before we begin writing the code, we need to decide what we want to achieve with the program and in what order should each component run.
- For the electric spirit level, the steps that we will take in the code for each loop are:
- Read tilt readings from accelerometer
- Convert tilt readings to tilt levels to be displayed on LED matrix
- Check for change in tilt level readings from previous loop
- Create array of led coordinates for different tilt cases and directions
- Plot led coordinates onto micro:bit LED matrix
- A few additional functions we need to include are:
- Calibration for initial tilt position
- Returning to default tilt calibration
Step 1: Defining Variables
- We start off by defining variables needed as shown. A breakdown of a few of the variables are:
- tiltList: Array that stores extent of tilt from values 0-4 in the order [Left, Right, Forward, Backward]
- tiltBoundary: Boundary of the first tilt level between 0 (no tilt) and 1 (slight tilt)
- prevState: Array that stores the tilt values of the micro:bit from a previous loop in the same format as tiltList, used to check for a change in tilt between iterations
- ledPlotList: Array of arrays of led coordinate to be plotted in the form (x, y). To define an array of arrays, we use the type number to indicate a nested array of variables of type: number.
Step 2: Convert tilt values to levels
- As the 5x5 LED matrix can only display so much information, the actual tilt values will not be useful for display
- Instead, a function tiltExtent() takes the parameter num, which refers to the tilt value from the accelerometer, and converts these tilt values (num) to tilt levels from 0 to 4. 0 indicates no tilt in the given direction and 4 indicates very large tilt, while -1 is returned when there is an error.
- Here, tiltBoundary and tiltSensitivity are used as the boundary values between tilt levels.
Step 3: Compile tilt levels
- The two functions checkRoll() and checkPitch() write the tilt levels obtained from tiltExtent() into tiltList for the roll (left-right) and the pitch (forward-backward) axes respectively.
- Before using the tilt values, we calibrate them using a zeroed value for both pitch (zeroPitch) and roll (zeroRoll), obtained from a calibration function written later.
- As the accelerometer readings are negative for both left and forward tilt, we need to use the Math.abs() function to obtain the modulus of the negative value to be given to the tiltExtent() function as a parameter for these two directions.
Step 4: Write LEDPlotList Functions
- Having obtained the tilt levels in tiltList we can now write the led plotting functions for the different cases that can arise, namely
- plotSingle(): Tilt only in a single direction , taking extent of tilt in given direction as parameter
- plotDiagonal(): Tilt in two directions of the same magnitude, taking extent of tilt in either direction as parameter
- plotUnequal(): Tilt in two directions of different magnitudes, taking extent of tilt in each direction as parameter. Uses plotDiagonal() first and adds on to ledPlotList array afterwards
- These plotting functions write an array of led coordinates to ledPlotList to be plotted later on.
Step 5: Plot LED Matrix for Each Case
- Using the plotting functions from the three cases in step 4, we can now plot the actual LED matrix for the different possible combinations of tilt levels. As the three functions in step 4 do not discriminate with direction, we need to adjust the coordinate values passed to the LED matrix to plot the LEDs in the right directions.
- PlotResult() contains multiple if conditions that check the kind of tilt and plots the LED matrix accordingly using led.plot(x, y). The possible combinations of tilt are:
Single direction: Left Only or Right Only
Single direction: Forward Only or Backward Only
Two directions: Forward-left or Backward-left
Two directions: Forward-right or Backward-right
- Note: For tilt in two directions, each combination can have the same or differing magnitude (checked by comparing maxX and maxY), and hence plotted using plotDiagonal() or plotUnequal() respectively
Step 6: Write Calibration Functions
- Having completed the bulk of the code, we now add in the calibTilt() and the resetTilt() functions.
- calibTilt() allows users to tare the tilt to zero at the micro:bit’s current position
- resetTilt() resets the calibration of the board to its original state
Step 7: Write State Function
- We add a simple function checkState() to check whether the tilt levels have changed from a previous iteration.
- If there is no change in tilt levels from a previous iteration i.e. stateChange == 0, we can directly move on to the next iteration and skip the plotting of the LED matrix, reducing computation needed.
Step 8: Putting it All Together Part 1!
- Now we can finally place all the necessary functions into the micro:bit’s infinite loop to have it run repeatedly.
- We first set the buttons A and B on the micro:bit to the calibTilt() and resetTilt() functions respectively using input.onButtonPressed(), and plot a tick on the LED matrix when the calibration is complete.
Step 9: Putting it All Together Part 2!
- We then run the necessary functions according to our code flow in Step 0 and check for a state change (meaning that there has been a change in the tilt of the micro:bit since the last iteration).
- If there is a change in tilt levels i.e. stateChange == 1, the code will update prevState to the new tilt levels and set stateChange back to 0 for the next iteration, and plot the updated tilt levels on the LED matrix using PlotResult().
- Have fun with your electric spirit level! And while you’re at it, why not try extending the capabilities of the tilt sensor or even turn it into a game?