Baking Pi’s 2: Touch HAT

In the “Baking Pi’s” series of posts, I describe my adventures with the Raspberry Pi embedded computer. Each segment describes a specific setup. This series is fairly technical and is meant to be used to create digital prototypes.

Screen Shot 2016-02-10 at 7.03.48 PM

Raspberry Pi with Touch Hat and Fruit!

In this post, I will describe my experience using Raspberry Pi with a touch sensor to create an interactive sound box. This post assumes that you have a Raspberry Pi B+ setup and connected (either to a monitor or running in headless mode). See my previous post or the official Raspberry Pi website on how to setup your Pi.

Using Pi to create an interactive sound box

A really fun activity is playing music using fruit and other conductive things (even humans)! You can do this by connecting the fruit to a computer using a touch sensor that in effect treats them as a key on the keyboard, making it possible to activate sounds when they are touched.  Some examples of how to do this easily is using a Makey Makey board or a Bare Conductive touch board. In the past, we connected an MPR121 Capacitive touch sensor to a Raspberry Pi to create TalkBox, a DIY communication board for non-verbal users. One of the challenges of putting together TalkBoxes was to connect all the wires from the MPR121 breakout board to the Raspberry Pi. Recently, capacitive touch HATs designed specifically for Raspberry Pi have become available that make it much easier to create an interactive sound box with the Raspberry Pi.

Screen Shot 2016-02-10 at 7.04.05 PM

Preparing the Touch HAT

For this project, you need a Raspberry Pi (already setup with a Linux distribution system and connected to the Internet, see above) and Adafruit’s capacitative touch HAT. You have to do a bit of soldering of a 2×20 solder header (included in the kit) to the touch HAT which makes it fit perfectly on top of the Raspberry Pi B+ (for older Raspberry Pi’s you need to solder a different taller solder header, see here).

Screen Shot 2016-02-10 at 7.03.55 PM

Pi wearing its new HAT!

One you have soldered the header and placed the HAT on the Pi, you need to install software following instructions here. The one thing that is missing from the tutorial is that you also have to enable the I2C protocol so that the Raspberry Pi can talk to the HAT. To do this use sudo raspi-config and choose Advanced Options. Here, you can enable I2C support and set it to load by default. Once you reboot, the libraries should be loaded.

Following is an example of code that runs a simple version of TalkBox (with a small set of constant sounds):

# Copyright (c) 2016 Foad Hamidi
# Author: Foad Hamidi based on code originally written by Tony Dicola from Adafruit Industries
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import sys
import time
import pygame.mixer

import Adafruit_MPR121.MPR121 as MPR121


print 'TalkBox Test'

# Create MPR121 instance.
cap = MPR121.MPR121()

# Initialize communication with MPR121 using default I2C bus of device, and 
# default I2C address (0x5A).  On BeagleBone Black will default to I2C bus 0.
if not cap.begin():
    print 'Error initializing MPR121.  Check your wiring!'
    sys.exit(1)

#Initialize the sound system, and create empty lists of channels and sounds
pygame.mixer.init(48000, -16, 1, 1024)
soundChannelList = [None] * 12
soundList = [None] * 12

#Populate your list of sounds and channels, there are only 7 channels, so you
#will have to reuse some channels. Channels are used so that sounds can be played
#simultaneously.
#I'm using some semi-random voice samples from a previous project. 
sound1 = pygame.mixer.Sound("/home/pi/Music/Feeling/happy.wav")
soundChannel1 = pygame.mixer.Channel(1)
soundList[0] = sound1
soundChannelList[0] = soundChannel1
sound2 = pygame.mixer.Sound("/home/pi/Music/Feeling/excited.wav")
soundChannel2 = pygame.mixer.Channel(2)
soundList[1] = sound2
soundChannelList[1] = soundChannel2
sound3 = pygame.mixer.Sound("/home/pi/Music/Feeling/feeling.wav")
soundChannel3 = pygame.mixer.Channel(3)
soundList[2] = sound3
soundChannelList[2] = soundChannel3
sound4 = pygame.mixer.Sound("/home/pi/Music/Feeling/proud.wav")
soundChannel4 = pygame.mixer.Channel(4)
soundList[3] = sound4
soundChannelList[3] = soundChannel4
sound5 = pygame.mixer.Sound("/home/pi/Music/Feeling/sad.wav")
soundChannel5 = pygame.mixer.Channel(5)
soundList[4] = sound5
soundChannelList[4] = soundChannel5
sound6 = pygame.mixer.Sound("/home/pi/Music/Feeling/sick.wav")
soundChannel6 = pygame.mixer.Channel(6)
soundList[5] = sound6
soundChannelList[5] = soundChannel6
sound7 = pygame.mixer.Sound("/home/pi/Music/Feeling/tired.wav")
soundChannel7 = pygame.mixer.Channel(7)
soundList[6] = sound7
soundChannelList[6] = soundChannel7
sound8 = pygame.mixer.Sound("/home/pi/Music/Feeling/good_morning_f.wav")
soundChannel8 = pygame.mixer.Channel(1)
soundList[7] = sound8
soundChannelList[7] = soundChannel8
sound9 = pygame.mixer.Sound("/home/pi/Music/Feeling/goodbye_f.wav")
soundChannel9 = pygame.mixer.Channel(2)
soundList[8] = sound9
soundChannelList[8] = soundChannel9
sound10 = pygame.mixer.Sound("/home/pi/Music/Feeling/need_break.wav")
soundChannel10 = pygame.mixer.Channel(3)
soundList[9] = sound10
soundChannelList[9] = soundChannel10
sound11 = pygame.mixer.Sound("/home/pi/Music/Feeling/thank_you_f.wav")
soundChannel11 = pygame.mixer.Channel(4)
soundList[10] = sound11
soundChannelList[10] = soundChannel11
sound12 = pygame.mixer.Sound("/home/pi/Music/Feeling/sunny.wav")
soundChannel12 = pygame.mixer.Channel(5)
soundList[11] = sound12
soundChannelList[11] = soundChannel12
print "Soundboard Ready."

# Main loop to print a message and play a sound every time a pin is touched.
print 'Press Ctrl-C to quit.'
last_touched = cap.touched()
while True:
    current_touched = cap.touched()
    # Check each pin's last and current state to see if it was pressed or released.
    for i in range(12):
        # Each pin is represented by a bit in the touched value.  A value of 1
        # means the pin is being touched, and 0 means it is not being touched.
        pin_bit = 1 << i
        # First check if transitioned from not touched to touched.
        if current_touched & pin_bit and not last_touched & pin_bit:
            print '{0} touched!'.format(i)
            soundChannel = soundChannelList[i-1] 
            sound = soundList[i-1]
            soundChannel.play(sound)
            print'Sound played'
        # Next check if transitioned from touched to not touched.
        if not current_touched & pin_bit and last_touched & pin_bit:
            print '{0} released!'.format(i)
    # Update last state and wait a short period before repeating.
    last_touched = current_touched
    time.sleep(0.1)

    # Alternatively, if you only care about checking one or a few pins you can 
    # call the is_touched method with a pin number to directly check that pin.
    # This will be a little slower than the above code for checking a lot of pins.
    #if cap.is_touched(0):
    #    print 'Pin 0 is being touched!'
    

Finally, adjust the volume of the speakers using the following command at the terminal prompt:

amixer  sset PCM,0 90%

which will adjust the volume by the indicated percentage of its total capacity (e.g., 90% in the above example).

Here’s a video of the setup used to make two pieces of fruit have a conversation:

Note: If you are getting weird static sounds out of the speaker connected to your analog audio output, it’s probably because of the power source. Try different ones and hopefully you will find one that doesn’t’ affect the audio performance too much. Another possibility is that you have not plugged in your speaker properly. Check it again before giving up on your speakers!

Finally, if you want this code to be loaded at startup, follow these instructions.

 

 

Advertisements