We'll be using CircuitPython for this project. Are you new to using CircuitPython? No worries, there is a full getting started guide here.

Adafruit suggests using the Mu editor to edit your code and have an interactive REPL in CircuitPython. You can learn about Mu and its installation in this tutorial.

First Some Theory

The way we can tell when the acceleometer (i.e. the Circuit Playground Express) is tilted with respect to an axis (X in our case) is to track the value for that axis.

Gravity at the Earth's surface is nominally about 9.8 m/s2.  So when the Circuit Playground Express is level, the value of Z will be ~9.8 and X will be 0. This is show in the lefthand half of the figure below.

When the Circuit Playground express is tilted 45 degrees, the force toward the center of the earth will still be 9.8, but it will be divided now between the X and Z axis, as show to the right below they will each be ~6.9 (9.8 * sin(45) ). Tilt it the other way and X will have a negative value.

By monitoring the value of X we can therefore tell how far along that axis the Circuit Playground Express is tilted.

The Code

While the hardware for this project is the same, the code is completely different and much simpler than the sound activated ears.

After setting up the interfaces to the accelerometer and servos, the loop continually monitors the X component of the accelerometer data (ignoring Y and Z). 1 G is ~9.8 m/s2 so a comparison value of 5.0 m/s2 is reasonable. That's a bit less than a 45 degree tilt, as shown above.

One thing to notice is that while X of over 5.0 (or below -5.0) will cause the top ear to perk up, it doesn't go back down until the absolute value of X is below 4.0. The range between 4.0 and 5.0 has no effect on the ear. This is generally called hysteresis and is used here to avoid jitter. If the ear went up when X was over 5.0 and down when it was below, it would jitter when the head tilt put X close to 5.0 since you can't hold your head that still, so X would be going back and forth over 5.0. This behavior is typically undesirable, hence the use of hysteresis. The ears go down well below the point at which they go up. The result is nice clean movement.

"""
Circuit Playground Express head-tilt activated ears.

Adafruit invests time and resources providing this open source code.
Please support Adafruit and open source hardware by purchasing
products from Adafruit!

Written by Dave Astels for Adafruit Industries
Copyright (c) 2018 Adafruit Industries
Licensed under the MIT license.

All text above must be included in any redistribution.
"""

import time
import busio
import board
import adafruit_lis3dh
import pulseio
from adafruit_motor import servo


# Setup accelerometer
i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)
sensor = adafruit_lis3dh.LIS3DH_I2C(i2c, address=0x19)

# Setup servos
left_pwm = pulseio.PWMOut(board.A1, frequency=50)
right_pwm = pulseio.PWMOut(board.A2, frequency=50)

left_ear = servo.Servo(left_pwm)
right_ear = servo.Servo(right_pwm)

#initialize things
left_ear.angle = 0
right_ear.angle = 0

while True:
    x, _, _ = sensor.acceleration
    if x < -5.0:
        left_ear.angle = 90
    elif x > 5.0:
        right_ear.angle = 90
    elif abs(x) < 4.0:
        left_ear.angle = 0
        right_ear.angle = 0
    time.sleep(0.1)
This guide was first published on Sep 18, 2018. It was last updated on Sep 18, 2018. This page (Code) was last updated on Dec 02, 2019.