Here's another fun way to use your animatronic hand -- it can count up to the number 15 (and say the numbers out loud)! How's this possible with only four active fingers? By using a modified finger binary counting method.

Finger binary is a counting method where each finger is assigned a 0 (down) and 1 (up) state, each with a different power of two.

These will be the powers of two and values of each finger of our modified, four-finger binary counting system:

• Index is 20, in binary `0001`, or a value of 1
• Middle is 21, in binary `0010`, or a value of 2
• Ring is 22, in binary `0100`, or a value of 4
• Pinky is 23, in binary `1000`, or a value of 8

By holding up the Index (1) and Middle (2) fingers, the binary representation is `0011`. We add their values, 1 + 2, therefore we indicate the number 3.

Here's another one: Pinky(8) + Ring(4) is `1100` in binary, or a value of 12.

So, here's the pattern for counting from 1 to 15 on four fingers:

• 1 = Index `0001`
• 2 = Middle `0010`
• 3 = Index, Middle `0011`
• 4 = Ring `0100`
• 5 = Ring, Index `0101`
• 6 = Ring, Middle `0110`
• 7 = Ring, Middle, Index `0111`
• 8 = Pinky `1000`
• 9 = Pinky, Index `1001`
• 10 = Pinky, Middle `1010`
• 11 = Pinky, Middle, Index `1011`
• 12 = Pinky, Ring `1100`
• 13 = Pinky, Ring, Index `1101`
• 14 = Pinky, Ring, Middle `1110`
• 15 = Pinky, Ring, Middle, Index `1111`

CPX Setup

Below is the CircuitPython code we'll use to count in binary on the fingers.

You'll still want all 4 servos attached. But now you'll also want a speaker on the speaker port!

Audio Files

The CRICKIT is a terrific board for animatronics projects, particularly audio-animatronics projects, because it can play back audio as well as control servos and motors. Download this .zip file and uncompress it to get a collection of audio .wav files we'll use during number counting.

We'll use an external speaker to hear things loud an clear. Screw the leads of your 4Ω or 8Ω speaker to the two speaker terminals on the CRICKIT -- orientation does not matter, so either wire can go to either terminal.

Once you've uncompressed the .zip file, drag the .wav files onto your CIRCUITPY drive. The files can live at the root level of the CPX.

For more on audio playback with CRICKIT, check out this guide.

CircuitPython Code

Download this code and paste it into Mu. Then, save the file as main.py or code.py to your Circuit Playground Express. Make sure the CPX switch is to the left and sit back to watch and listen as your CRICKIT-powered animatronic hand counts in binary!

```#  Animatronic Hand
#  Binary Counting on four fingers up to 15
import time
from digitalio import DigitalInOut, Direction, Pull
import audioio
import audiocore
import board

#################### CPX switch
# use the CPX onboard switch to turn on/off (helps calibrate)
switch = DigitalInOut(board.SLIDE_SWITCH)
switch.direction = Direction.INPUT
switch.pull = Pull.UP

#################### Audio setup
print("Let's count in binary.")
wavfiles = ("one.wav", "two.wav", "three.wav", "four.wav", "five.wav", "six.wav",
"seven.wav", "eight.wav", "nine.wav", "ten.wav", "eleven.wav",
"twelve.wav", "thirteen.wav", "fourteen.wav", "fifteen.wav")
introfile = "intro.wav"

cpx_audio = audioio.AudioOut(board.A0)
def play_file(wavfile):
with open(wavfile, "rb") as f:
wav = audiocore.WaveFile(f)
cpx_audio.play(wav)
while cpx_audio.playing:
pass

#################### 4 Servos!
servos = (crickit.servo_1, crickit.servo_2, crickit.servo_3, crickit.servo_4)
for servo in servos:
servo.angle = 180 # starting angle, open hand

# Which servos to actuate for each number
counting = (
[3],
[2],
[3, 2],
[1],
[1, 3],
[1, 2],
[3, 2, 1],
[0],
[0, 3],
[0, 2],
[0, 3, 2],
[0, 1],
[0, 3, 1],
[0, 2, 1],
[0, 3, 2, 1]
)

play_file(introfile)

while True:
if not switch.value:
continue

# the CPX switch is on, so do things
for servo in servos:  # close the fist
servo.angle = 0  # close the fingers
print("Servo %d angle = 0" % (servos.index(servo)+1) )
time.sleep(.2)

time.sleep(1)  # pause a moment

for i in range(len(counting)):
# close all the counting fingers between numbers
for servo in servos:
servo.angle = 0  # close
print("\t\tServo #%d angle 0" % (servos.index(servo)+1))
time.sleep(0.3)

print("Number #%d \tfingers: %s" % (i+1, counting[i]))

# open just the indicated fingers when counting
for finger in counting[i]:
servos[finger].angle = 180  # open
print("\t\tServo #%d angle 180" % (finger+1))
time.sleep(0.3)
# say it!
play_file(wavfiles[i])
# hold for a bit of time
time.sleep(0.3)
print("...")
```

Code Explainer

Take a look at the code to get a sense of how it works. After importing libraries and setting up the CPX switch, we have an audio setup section.

First, we create a variable list called `wavfiles` that stores the names of all the counting audio files we'll use. We also make a variable called `introfile` that has the filename of the intro audio wav file.

Then, we instantiate the `audioio` command and define a process called `play_file` to open, play, and close the audio files specified.

What follows are partial code snippets from the full program above, you cannot run they by themselves, they're here just for explanation
```#################### Audio setup
print("Let's count in binary.")
wavfiles = ["one.wav", "two.wav", "three.wav", "four.wav", "five.wav", "six.wav",
"seven.wav", "eight.wav", "nine.wav", "ten.wav", "eleven.wav",
"twelve.wav", "thirteen.wav", "fourteen.wav", "fifteen.wav"]
introfile = "intro.wav"

cpx_audio = audioio.AudioOut(board.A0)
def play_file(wavfile):
with open(wavfile, "rb") as f:
wav = audiocore.WaveFile(f)
cpx_audio.play(wav)
while cpx_audio.playing:
pass```

Servo Counting

Next, we set up the four servos, and create a variable list of lists called `counting`. This specifies which finger or set of fingers is to be raised up for each number that we're counting. You can see, for example, that the number 1 raises the index finger only, while 15 raises all four fingers.

```#################### 4 Servos
servos = (crickit.servo_1, crickit.servo_2, crickit.servo_3, crickit.servo_4)
for servo in servos:
servo.angle = 180 # starting angle, open hand

# Which servos to actuate for each number
counting = [
[3],
[2],
[3, 2],
[1],
[1, 3],
[1, 2],
[3, 2, 1],
[0],
[0, 3],
[0, 2],
[0, 3, 2],
[0, 1],
[0, 3, 1],
[0, 2, 1],
[0, 3, 2, 1]
]```

Counting Time

The final bit of setup is to play the intro wav file and then get into the main loop. Here we check the CPX switch and only proceed if it is set to the left position.

Then, we close all the fingers down into a fist and pause a moment.

```play_file(introfile)

while True:
if not switch.value:
continue

# the CPX switch is on, so do things
for servo in servos:  # close the fist
servo.angle = 0  # close the fingers
print("Servo %d angle = 0" % (servos.index(servo)+1) )
time.sleep(.2)

time.sleep(1)  # pause a moment```

Finally, we run through the `counting` list one item at a time and open only the fingers specified per entry in that list.

After all of the fingers needed for a particular number have been raise, we play back the appropriate wav file so the audio-animatronic can speak!

```    for i in range(len(counting)):
# close all the counting fingers between numbers
for servo in servos:
servo.angle = 0  # close
print("\t\tServo #%d angle 0" % (servos.index(servo)+1))
time.sleep(0.3)

print("Number #%d \tfingers: %s" % (i+1, counting[i]))

# open just the indicated fingers when counting
for finger in counting[i]:
servos[finger].angle = 180  # open
print("\t\tServo #%d angle 180" % (finger+1))
time.sleep(0.3)
# say it!
play_file(wavfiles[i])
# hold for a bit of time
time.sleep(0.3)
print("...")```

This guide was first published on May 23, 2018. It was last updated on May 23, 2018.

This page (Audio-Animatronic Binary Counting) was last updated on Nov 17, 2021.