STEAM DISCOVERY LAB
  • About
  • Tools
  • Projects
  • Resources
  • About
  • Tools
  • Projects
  • Resources
Search

Micro:Bit Bubble Level

Picture

​Lesson Objectives:
  1. Students will learn about conditionals and functions
  2. Students will learn about trigonometry
  3. Students will learn to use micro-controllers

Materials:
  • BBC micro:bit
  • Laptop with Mu Software 
Picture

Let's Get Started!
​
A bubble level, like the one in the picture above, is used to tell whether a surface is flat. If you put a level on a flat surface, the bubble will rest in the middle. If the surface is tilted, the bubble will move to the highest side, indicating visually that there is a slope.
​
You can use accelerometer values to determine whether the micro:bit is on a flat surface or not and use images on the display to indicate a tilt.

​Goal:
Create a bubble level with your micro:Bit. The goal is to have the micro:Bit light up the center LED when the micro:Bit is roughly level. When it is not level, use the other LEDs to indicate the tilt. (The simplest version would use an arrow to display the direction of tilt or you could emulate a bubble level by lighting up an LED to indicate the direction and magnitude of the tilt.

Step 1: Read accelerometer values from micro:bit
To start, let's make a script that reads accelerometer values from the microbit and prints them to the REPL in Mu.
In order to have your code repeatedly take samples, put it inside a while True loop. While loops will be explained more in future lessons, but for now just know that the syntax looks like this:

    
Every line indented below the loop header will now repeat in order forever until the micro:bit is unplugged or restarted.

Inside this while loop, we need to first read the accelerometer values and then print them. We want to be able to read the output so let’s also add a sleep of 100 ms at the end of the loop. Information on how to read accelerometer values and sleep can be found in the microbit documentation. Excerpts are including in the References section below.  The code for this is shown below.
​
Flash your micro:bit and then open REPL and you should see the accelerometer values printing every tenth of a second. You may need to press the restart button on the micro:bit after opening REPL for the values to print. ​
Step 1 Code
Step 1 Code

    
​​Step 2: Calculate Angle from accelerometer values
Now that we have the accelerometer values, we can use trigonometry to determine the micro:bit’s orientation.
You may find this article helpful for understanding how to calculate the tilt of the board. You can either use 2-axis tilt calculations, which will only work for small amounts of tilt, or you can use 3-axis tilt calculations that will handle larger angles better. The 3-axis calculations are shown below.
Picture
While X, Y, and Z change position within the equations, the two equations are still fundamentally identical. We could write the equation twice in the body of our script. However, since this section of code is repeated, this is the perfect time to create a function. 

Let’s create a function called calculate_3D_tilt(a, b, c) that takes 3 accelerometer values (a, b, c) as inputs. ‘a’ is the value for the axis for which we wish to calculate the angle and ‘b’ and ‘c’ are the other 2 values. This function should perform the above calculation and return the result. You will need to use functions from the math library to perform this calculation. 

The angles this function calculates are in radians, so let’s create another function called degree_from_radians(radians) to convert radians to degrees. This function takes an angle in radians as an input and returns that angle in degrees. The conversion is degrees = radians * 180/pi. 

Now, instead of printing the 3 accelerometer values, print the x angle and y angle. You can also view the data graphically using the Mu Plotter. The code for this step is shown below. 

Step 2 Code
Step 2 Code

    
Using Mu Plotter
Read the instructions (https://codewith.mu/en/tutorials/1.0/plotter) for using the MU Plotter.

You will notice that the plotter can only use a TYPE of value called a TUPLE. The tuple is a collection of values that are contained in parentheses and separated by commas. (1,2) is a tuple, as is (“apple”, “banana”, “orange”). However, (4) is not a tuple, it is just a 4 in parentheses, to tell python that it is a single value tuple you must write (4,) in the case of the plotter example for a single digit you would write:  print((random.randint(0, 100),))
Step 3: Display image to micro:bit
Now, we will use conditional statements to display the level indication on the micro:bit itself. We will do this by creating one void function that takes two arguments, X and Y tilt (in degrees) and uses conditional statements to change the micro:bit display.
Let's start by considering what we want to display and when. 
  • If the micro:bit is within 5 degrees of flat, we want to display a SMALL_SQUARE or SMILE (or anything else you feels make sense). 
    • We consider within 5 degrees to be flat because, as you can see in REPL, when you run the code from step 2, python stores floating-point numbers with a lot of significant figures, so it is very unlikely that the angle calculations will equal 0 even when the micro:bit is flat to the human eye. For our purposes, 5 degrees is close enough, though you can test different values once your program works.
  • If the angle is more than 5 degrees in any direction, we want to display an arrow pointing towards the high side of the micro:bit. If both the x and y direction are tilted we want to display a diagonal arrow in the appropriate direction. 
First, write down on paper what all of the cases are and the corresponding arrow. There should be 9 cases total. Then write the boolean expressions and operators you will use to determine what side is highest. It will be helpful to test out your current functions using the REPL and plotter to see what tilt angles indicate what direction of tilt. The arrow should always point towards the highest part of the micro:bit.

You will find the instructions for displaying images on the micro:bit in the documentation here 

Once that is working, consider the limitations of this design vs a real bubble level. One limitation is that it does not tell us how much tilt there is (e.g., the severity or magnitude of the tilt). There are several ways you can address this including: 
  • Adjust the intensity of the LED’s based on the severity of the tilt.
  • Make your display show a single lit up LED that moves around in imitation of a real bubble level.
Step 3 Code
Step 3 Code

    
References
The following functions (documentation copied from Python math documentation and microBit microPython) documentation may be helpful.

The full documentation may be found here:
  • https://microbit-micropython.readthedocs.io/en/latest/microbit_micropython_api.html
  • https://docs.python.org/3/library/math.html​
Useful Functions
math.pi
the ratio of a circle’s circumference to its diameter

math.atan2(y, x)
Return atan(y / x), in radians. The result is between -pi and pi. The vector in the plane from the origin to point (x, y) makes this angle with the positive X axis. The point of atan2()  is that the signs of both inputs are known to it, so it can compute the correct quadrant for the angle. For example, atan(1) and atan2(1, 1) are both pi/4, but atan2(-1, -1) is -3*pi/4

microbit.accelerometer.get_x()
Get the acceleration measurement in the x axis, as a positive or negative integer, depending on the direction. The measurement is given in milli-g. By default the accelerometer is configured with a range of +/- 2g, and so this method will return within the range of +/- 2000mg.

microbit.accelerometer.get_y()
Get the acceleration measurement in the y axis, as a positive or negative integer, depending on the direction. The measurement is given in milli-g. By default the accelerometer is configured with a range of +/- 2g, and so this method will return within the range of +/- 2000mg.

microbit.accelerometer.get_z()
Get the acceleration measurement in the z axis, as a positive or negative integer, depending on the direction. The measurement is given in milli-g. By default the accelerometer is configured with a range of +/- 2g, and so this method will return within the range of +/- 2000mg.

microbit.display.scroll(value)
Scrolls value horizontally on the display. If value is an integer or float it is first converted to a string using str().
Picture
200 Boston Ave, Medford, MA 02155
steamdiscoverylab@gmail.com
Center for Engineering Education and Outreach
​Tufts University
About
Tools
Projects
Resources
​
Contact
LEGO®, the LEGO® logo, the Brick, MINDSTORMS®, and the Minifigure are trademarks of ©The LEGO® Group. On some parts of this site  you will get access to so-called “developer software”, which offers documentation on different ways to operate the LEGO® Education SPIKE™ Prime Hub and technology. Whatever use you make of the developer software, bear in mind that the results are not experiences that the LEGO Group endorses, is with or will be liable for. No rights in or to trademarks of the LEGO Group are implied or given, and you may not apply to or register any protection anywhere in the world for intellectual property or industrial rights or similar in respect of any developer software, derivative or other result achieved through its use. The developer software is made available “as is” and, to the extent possible, no warranties or representations are implied or given in relation to it by the LEGO Group. It’s your responsibility to ensure all uses that you make and enable others to make comply with all applicable laws and best practices. By accessing the developer software, you acknowledge that the terms and conditions set out above and in LEGO Education’s terms of use for SPIKE Prime apply.
  • About
  • Tools
  • Projects
  • Resources