The controller code continually reads the 3 axes of the accelerometer and, based on those readings, sends the appropriate code via the IR transmitter.

Since accelerometers can detect gravity, they're great for calculating the tilt of your hand. But sometimes it hard to visualize what the motion translates to X-Y-Z values. For that, we recommend using the CircuitPython plotter

Check our our motion-plotting guide and video to see how you can read the x, y, and z accelerations and get values for use in detecting tilt.

There are three primary hand positions that correspond to stop, forward, and reverse:

1. palm down: z is a high negative value,
2. hand up with palm facing away from you: y has a high positive value, and
3. hand down with palm facing toward you: y has a high negative value.

For each of these three hand positions, wrist rotation adds a turn to the basic stop/forward/reverse motion: rotating in place if the robot is stopped, or veering left/right if the robot is moving forward or reversing. The X component of the accelerometer reading indicates wrist rotation: a large negative value for a counterclockwise rotation, and a large positive value for clockwise rotation.

After configuring the hardware and libraries, the main loop reads the accelerometer and a 2 level conditional decides what should be sent to the robot.

Below is the code for the control glove. Save it to the Circuit Playground Express on the glove as `code.py`.

```# SPDX-FileCopyrightText: 2018 Dave Astels for Adafruit Industries
#

import time
import busio
import board
import pulseio

# Control debug output: it takes time so don't unless you're debugging
DEBUG_LOG = False

# Control codes
STOP = 0x01
ROTATE_LEFT = 0x02
ROTATE_RIGHT = 0x03
FORWARD = 0x04
FORWARD_LEFT = 0x05
FORWARD_RIGHT = 0x06
REVERSE = 0x07
REVERSE_LEFT = 0x08
REVERSE_RIGHT = 0x09

TRANSMIT_DELAY = 0.1

# Setup accelerometer
i2c = busio.I2C(board.ACCELEROMETER_SCL, board.ACCELEROMETER_SDA)

# Create a 'pulseio' output, to send infrared signals on the IR transmitter @ 38KHz
pulseout = pulseio.PulseOut(board.IR_TX, frequency=38000, duty_cycle=2 ** 15)

# Create an encoder that will take numbers and turn them into IR pulses
one=[560, 1700],
zero=[560, 560],
trail=0)

def log(s):
"""Optionally output some text.
:param string s: test to output
"""
if DEBUG_LOG:
print(s)

while True:
x, y, z = sensor.acceleration
log("{0: 0.3f} {1: 0.3f} {2: 0.3f}".format(x, y, z))
if z < -5.0 and abs(y) < 3.0:         # palm down
if x < -5.0:                      # tipped counterclockwise
log("ROTATE_LEFT")
encoder.transmit(pulseout, [ROTATE_LEFT] * 4)
elif x > 5.0:                     # tipped clockwise
log("ROTATE_RIGHT")
encoder.transmit(pulseout, [ROTATE_RIGHT] * 4)
else:                             # level
log("STOP")
encoder.transmit(pulseout, [STOP] * 4)
elif y > 5.0:                         # palm facing away
if x < -5.0:                      # tipped counterclockwise
log("FORWARD_LEFT")
encoder.transmit(pulseout, [FORWARD_LEFT] * 4)
elif x > 5.0:                     # tipped clockwise
log("FORWARD_RIGHT")
encoder.transmit(pulseout, [FORWARD_RIGHT] * 4)
else:                             # straight up
log("FORWARD")
encoder.transmit(pulseout, [FORWARD] * 4)
elif y < -5.0:                        # palm facing toward (hand down)
if x < -5.0:                      # tipped counterclockwise
log("REVERSE_RIGHT")
encoder.transmit(pulseout, [REVERSE_RIGHT] * 4)
elif x > 5.0:                     # tipped clockwise
log("REVERSE_LEFT")
encoder.transmit(pulseout, [REVERSE_LEFT] * 4)
else:                             #straight down
log("REVERSE")
encoder.transmit(pulseout, [REVERSE] * 4)

time.sleep(TRANSMIT_DELAY)
```

This guide was first published on Aug 08, 2018. It was last updated on Jul 18, 2024.