Adding a Warning Buzzer

What happens if your bot wanders away and gets stuck under the couch?  Will it sit there patiently waiting for someone to notice and rescue it? Let's give it a voice so it can at least call for help.

We could use the Circuit Playground Express's on board speaker to play a sound file or a tone. But that takes up a fair bit of memory, and is Circuit Playground Express specific. Part of the goal with this project is to focus on the CRICKIT, regardless of which model it is.

We could use the speaker output, but again that consumes memory for the waveform to play. The simplest solution that will address the problem (giving the bot a voice) is to use a drive output to switch on and off a buzzer. The one listed in the parts list is perfect for this: apply 5v and it outputs a steady, piercing 2kHz tone. The CRICKIT's drive outputs work at 5v. 

Parts Required

Buzzer 5V - Breadboard friendly

PRODUCT ID: 1536
Hey want to hear a really loud noise? Apply 3V to 5V to this buzzer module and you'll be rewarded with a loud 2KHz BEEEEEEEEEEEEEEEEEP. Unlike a
$0.95
IN STOCK

36-pin Stacking header - pack of 5!

PRODUCT ID: 3366
Headers are like the duct tape of electronics. They're great for connecting things together, soldering to perf-boards, sockets for wires or break-away header, etc. We go...
$5.95
IN STOCK

You can also solder some wires to the buzzer to make the pins longer instead of stacking header pins.

New Wiring Additions

The positive lead of the buzzer connects to the 5v connection in the drive section of the CRICKIT, and the other buzzer lead connects to one of the drive connections.

The leads on the buzzer line up nicely with the 5v and Drive 2 connectors, but are too short to reach. To solve this, you can use a 4-position long piece of stacking header. Pull out the middle 2 pins, leaving the outer two. This is just the right width for the buzzer leads. Bend the header pins as needed and secure them in the drive screw terminals as shown.

Now it's just a matter of inserting the buzzer pins into the header. Note the `+` pin on the buzzer. It has to be at the 5v connection on the CRICKIT.

Code

Adding the buzzer enables the bot to scream for help. The only additional code is at the very end. After exiting the loop and turning off the motors, the buzzer lets the bot call for help.

Download: file
while True:
    for _ in range(3):
        crickit.drive_2.fraction = 1.0
        time.sleep(0.1)
        crickit.drive_2.fraction = 0.0
        time.sleep(.2)
    time.sleep(10.0)

Setting drive 2's fraction property to 1.0 turns the buzzer on, and setting it to 0.0 turns it off. This code sounds three short beeps every ten seconds. Very simple, yet very effective.

Save the code below as code.py on the Circuit Playground Express.

import time
import random
from adafruit_crickit import crickit

LEFT = False
RIGHT = True

random.seed(int(time.monotonic()))
ss = crickit.seesaw

left_wheel = crickit.dc_motor_1
right_wheel = crickit.dc_motor_2

RIGHT_BUMPER = crickit.SIGNAL1
LEFT_BUMPER = crickit.SIGNAL2
CENTER_BUMPER = crickit.SIGNAL3

ss.pin_mode(RIGHT_BUMPER, ss.INPUT_PULLUP)
ss.pin_mode(LEFT_BUMPER, ss.INPUT_PULLUP)
ss.pin_mode(CENTER_BUMPER, ss.INPUT_PULLUP)

# These allow easy correction for motor speed variation.
# Factors are determined by observation and fiddling.
# Start with both having a factor of 1.0 (i.e. none) and
# adjust until the bot goes more or less straight
def set_right(speed):
    right_wheel.throttle = speed * 0.9

def set_left(speed):
    left_wheel.throttle = speed


# Uncomment this to find the above factors
# set_right(1.0)
# set_left(1.0)
# while True:
#     pass

# Check for bumper activation and move away accordingly
# Returns False if we got clear, True if we gave up
def react_to_bumpers():
    attempt_count = 0
    # keep trying to back away and turn until we're free
    while True:

        # give up after 3 tries
        if attempt_count == 3:
            return True

        bumped_left = not ss.digital_read(LEFT_BUMPER)
        bumped_right = not ss.digital_read(RIGHT_BUMPER)
        bumped_center = not ss.digital_read(CENTER_BUMPER)

        # Didn't bump into anything, we're done here
        if not bumped_left and not bumped_right and not bumped_center:
            return False

        # If the middle bumper was triggered, randomly pick a way to turn
        if bumped_center:
            bumped_left |= random.randrange(10) < 5
            bumped_right = not bumped_left

        # Back away a bit
        set_left(-0.5)
        set_right(-0.5)
        time.sleep(0.5)

        # If we bumped on the left, turn to the right
        if bumped_left:
            set_left(1.0)
            set_right(0.0)

            # If we bumped on the right, turn left
        elif bumped_right:
            set_left(0.0)
            set_right(1.0)

            # time to turn for
        time.sleep(random.choice([0.2, 0.3, 0.4]))
        attempt_count += 1


def tack(direction, duration):
    target_time = time.monotonic() + duration
    if direction == LEFT:
        set_left(0.25)
        set_right(1.0)
    else:
        set_left(1.0)
        set_right(0.25)
    while time.monotonic() < target_time:
        if not(ss.digital_read(LEFT_BUMPER) and
               ss.digital_read(RIGHT_BUMPER) and
               ss.digital_read(CENTER_BUMPER)):
            return react_to_bumpers()
    return False


while True:
    if tack(LEFT, 0.75):
        break
    if tack(RIGHT, 0.75):
        break


set_left(0)
set_right(0)

while True:
    for _ in range(3):
        crickit.drive_2.fraction = 1.0
        time.sleep(0.1)
        crickit.drive_2.fraction = 0.0
        time.sleep(.2)
    time.sleep(10.0)
This guide was first published on Jul 30, 2018. It was last updated on Jul 30, 2018. This page (Adding a Warning Buzzer) was last updated on Oct 18, 2019.