Absolute Acceleration

You can get the equivalent of the MakeCode acceleration strength block with a tiny bit of math in CircuitPython. The key is to take the square root of the sum of the squares of x, y, and z, similar to the hypotenuse of a triangle but in three dimensions. In vector math, it is getting the magnitude of the acceleration in 3D.

The following CircuitPython code will get the readings from the accelerometer and calculate the absolute acceleration and print it on the serial monitor and plot it in Mu.

import time
from math import sqrt
from adafruit_circuitplayground.express import cpx

def show_value(val):            # Show value 0-9 on CPX NeoPixels
    for i in range(val):
        cpx.pixels[i] = (50, 0, 0)  # Red
    for i in range(val, 10):
        cpx.pixels[i] = (0, 0, 0)

# Main loop gets x, y and z axis acceleration, gets the absolute
# acceleration, then a normalized value to the number of Gees
# prints the values, and displays on NeoPixels

Normalize_To = 9.8 * 2   # Normalize to 2 Gs, change 2 to 1, 4, 8, etc.

while True:
    x, y, z = cpx.acceleration        # Get acceleration from board
    abs = sqrt(x*x + y*y + z*z)       # Get absolute acceleration
    abs = min(abs, Normalize_To)      # Normalize to max acceleration
    normalized = abs / Normalize_To   # Get fractional normalized accel
    print((abs,normalized))           # Print to Mu Serial

    show_value(int(normalized * 10))  # Show on NeoPixels on CPX
    time.sleep(0.5)                   # Wait a bit then do again

Now shake the accelerometer. Mu will show you the absolute acceleration and the normalized acceleration, here to 2g although you can change this to any value you want, usually 1, 2, 4, 6, 8, 16, etc.

Press the Plotter button and you get a plot. The screen below shows shaking in various directions.

Color Glow Accelerometer

You can use the acceleration values to make a fun light up project with the NeoPixels. There are three acceleration values, and the LEDs have three color values. Let's see what we can do with that!

Copy the following to a file named code.py and save to your Circuit Playground Express CIRCUITPY drive.

    from adafruit_circuitplayground.express import cpx
# Main loop gets x, y and z axis acceleration, prints the values, and turns on
# red, green and blue, at levels related to the x, y and z values.
while True:
    if cpx.switch:
        print("Slide switch off!")
        cpx.pixels.fill((0, 0, 0))
        R = 0
        G = 0
        B = 0
        x, y, z = cpx.acceleration
        print((x, y, z))
        if x:
            R = abs(int(x))
        if y:
            G = abs(int(y))
        if z:
            B = abs(int(z))
        cpx.pixels.fill((R, G, B))

Move the slide switch to the right if it isn't already. Lights! Now move the board in different directions to see the colors change!

Let's take a look at the code. First we import the adafruit_circuitplayground.express library as cpx.

Inside the while True: loop, the program checks to see if the switch is to the left. If it is, we print Slide switch off! and turn off all the LEDs. This creates an "off switch" for the project in case you'd like to leave it sitting around but not have the lights on. continue tells the code to keep checking the switch until the state changes, i.e. you move the switch to the right. Once that happens, the code moves on.

Next is the else block. First, three variables, R, G and B are created. These will be used to set the colors. They are assigned 0 to start. Then, the code assigns x, y, z = cpx.accelerationand prints the values. If you look at the serial output, you'll see how fast the values are scrolling. This is why one typically includes a time.sleep() in the code, to slow those values down to a readable speed. However, this project works best without a sleep, so it has been left out.

The next section has three parts. Each do the same thing but for a different axis. It is time to take the acceleration values, and use them to represent color values. Begin with x.

The value of x is modified a little with abs(int(x)). This returns the absolute value of the whole number value of x. Absolute values are explained here. Since color values are all whole numbers,  use int(x) to return only the nearest whole number value of x, instead of a long decimal which is often what acceleration returns. Since color values are all positive, take the absolute value of int(x) to remove any potential negative numbers from the mix.

Then take abs(int(x)) and assign it to R. Now we have our R value to use for red! Then we do the same thing for y and z, except abs(int(y)) is assigned to G and abs(int(z)) is assigned to B. This gives us three color values!

We then set cpx.pixels.fill((R, G, B)) to set all the pixels to these color values. As you move the board around, the acceleration values change, and that causes each of our color values to be different. Now, depending on what angle you hold the board, you'll get a different color combination!

Remember the earlier example, where we explained that if the board is laying flat, the returned values are (0, 0, 9.8). This means, if the board is laying flat, facing up, while this code is running, the color values are (0, 0, 9.8). So, you'll see if it's laying flat on your desk, it's blue!

If you hold it so the USB cable is on the top and pointed downwards, the values are, (0, 9.8, 0), so the LEDs are green.

If you hold it so the USB cable is sideways, pointing left or right, the values are (9.8, 0, 0) so the LEDs are red.

As you move the board around at different angles, you'll find every color between!

We also explained that if you shake the board, you'll get back higher values from the accelerometer. This means that the LEDs will be brighter if you shake it. Give it a try!

This guide was first published on Sep 12, 2018. It was last updated on Mar 08, 2024.

This page (More CircuitPython) was last updated on Mar 08, 2024.

Text editor powered by tinymce.