When working with sensors, displays, or any system where you need to convert values from one range to another, two essential techniques come into play: mapping and clamping.
Mapping allows us to translate values from one range to another, such as converting sensor readings to display coordinates.
Clamping, on the other hand, ensures that values stay within a desired range, preventing errors or unexpected behavior in our programs.
These techniques are crucial in many programming scenarios, especially in projects involving microcontrollers like the micro:bit. In this lesson, we'll explore how to implement mapping and clamping, understand their importance, and see how they can be applied in real-world programming situations
We are going to make a program that displays a dot on the LED matrix that moves based on how you tilt the micro:bit.
First, let's try to understand the sensor data:
from microbit import *
while True:
print(accelerometer.get_x())
sleep(50)
📖 Complete this section in your workbook.
The purpose is to understand the how the sensors work, the type of data they collect and the range of values.
Now, let's dispay a dot on the LED screen based on the X and Y tilt of the accelerometer.
The micro:bit function display.set_pixel(x, y, brightness) has 3 parameters:
x: the x-coordinate of the LED pixel, 0 to 4
x: the x-coordinate of the LED pixel, 0 to 4
brightness: the brightness of the pixel, 0 to 9
How will we map the range of our accelerometer to these values?
Mapping is the process of converting values from one range to another. The general formula is:
Shift the input range to start at 0
Scale to the Output Range
Multiply by the number of steps in our output range
Divide by by the number of steps in our input range
E.g. If I had a sensor that gives a range from -128 to +127 and I wanted to map it to a range of 0-10:
Shift the input range to start at 0: Add 128 to give a range of 0 to 255
Multiply by the number of steps in our output range: Multiply the variable by 10
Divide by by the number of steps in our input range: Divide the variable by 255
output = (input + 127) * 10 // 254
Using the // operator gives us integer division, to ensure we get a whole number and effectively rounds down.
📖 Complete the mapping section in your workbook.
Test this out on your microbit, and adjust the numbers so that it works correctly for the accelerometer:
from microbit import *
SHIFT = 128
OUTPUT_RANGE = 10
INPUT_RANGE = 255
while True:
output = (accelerometer.get_x() + SHIFT) * OUTPUT_RANGE // INPUT_RANGE
print(output)
sleep(50)
Finally, the sensor data may fall a little above or below the expected range. To fix this we can clamp it with minimum and maximum values:
To do this we use Python's min and max functions:
max returns the item with the highest value, so we can use this to ensure we stay above the MIN threshold
min returns the item with the lowest value, so we can use this to ensure we stay below the OUTPUT_RANGE threshold
On first glance it may seem backwards, but it works! Nesting them together clamps our values between that range
from microbit import *
SHIFT = 128
OUTPUT_RANGE = 10
INPUT_RANGE = 255
MIN = 0
while True:
output = (accelerometer.get_x() + SHIFT) * OUTPUT_RANGE // INPUT_RANGE
output_clamped = min(max(output, MIN), OUTPUT_RANGE)
print(output_clamped)
sleep(50)
Your challenge is now to use what you have learned to read, map and clamp both axis of the accelerometer.
Use this along with display.set_pixel(x, y, 9) to make the dot move around the screen.
from microbit import *
while True:
# Read, map and clamp the accelerometer x-axis
# Read, map and clamp the accelerometer y-axis
display.clear()
display.set_pixel(x, y, 9)
sleep(50)
Try modifying this program to:
Change the sensitivity of the dot's movement
Make the dot's brightness change based on the z-axis