ReSpeaker 2-Mics Pi HAT with Raspberry PI

Overview

A ReSpeaker 2-Mics Pi HAT is a dual-microphone expansion board for Raspberry PI. This means you can build a portable project that integrates Amazon Alexa Voice Service, Google Assistance, can be use also as voice recognition, voice recording, and many more

This post is a tutorial on how to use multiple features of the ReSpeaker 2-Mics Pi HAT expansion board. These features are record audio using dual-microphone, using 3.5mm audio jack connected to speaker or headphone to output audio, interface user button, and interface 3 APA102 RGB LEDs.

 

Hardware

 

    Software

     

    Application Discussion

    A ReSpeaker 2-Mics Pi HAT is a dual-microphone expansion board for Raspberry PI. The board is developed based on WM8960, is a low power, high quality stereo CODEC designed for portable digital audio applications. 

    ReSpeaker 2-Mics Pi Hat Expansion Board:

    Other than its audio feature, here are the other components included on the board.

    ReSpeaker 2-Mics Pi Hat components:

    • Dual Microphones(Left and right microphones)
    • WM8960: a low power stereo codec
    • POWER: Micro USB port for powering the ReSpeaker 2-Mics Pi HAT, power the board for providing enough current when using the speaker.
    • User Button (Connected to RPI GPIO17)
    • RGB LED (3 APA102 RGB LEDs, connected to SPI interface)
    • 3.5mm Audio Jack (Connecting headphone or speaker with Audio plug)
    • Raspberry Pi 40-Pin Headers: support Raspberry Pi Zero, Raspberry Pi 1 B+, Raspberry Pi 2 B , Raspberry Pi 3 B and Raspberry Pi 3 B+
    • JST 2.0 Speaker out (Connecting speaker with JST2.0 connector)
    • I2C Grove Interface (Connected to RPI I2C-1)
    • GPIO12 Grove interface (Connected to RPI GPIO12 & GPIO13)

     

    Set-up the Hardware   

    Connect the ReSpeaker 2-Mics Pi HAT to Raspberry PI and connect it like this.

    Raspberry PI Connection

    Raspberry PI Zero Connection

      Set-up the Software

      Install ReSpeaker 2-Mics Pi HAT Driver:

      • Install the seeed voice card drivers by using RPI Terminal.
      sudo apt-get update
      sudo apt-get upgrade
      git clone https://github.com/respeaker/seeed-voicecard.git
      cd seeed-voicecard
      sudo ./install.sh
      reboot 
      • Check that the sound card name matches the source code seeed-voicecard by command aplay -l and arecord -l.
      pi@raspberrypi:~ $ aplay -l
      **** List of PLAYBACK Hardware Devices ****
      card 0: b1 [bcm2835 HDMI 1], device 0: bcm2835 HDMI 1 [bcm2835 HDMI 1]
        Subdevices: 4/4
        Subdevice #0: subdevice #0
        Subdevice #1: subdevice #1
        Subdevice #2: subdevice #2
        Subdevice #3: subdevice #3
      card 1: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
        Subdevices: 4/4
        Subdevice #0: subdevice #0
        Subdevice #1: subdevice #1
        Subdevice #2: subdevice #2
        Subdevice #3: subdevice #3
      card 2: seeed2micvoicec [seeed-2mic-voicecard], device 0: bcm2835-i2s-wm8960-hifi wm8960-hifi-0 [bcm2835-i2s-wm8960-hifi wm8960-hifi-0]
        Subdevices: 1/1
        Subdevice #0: subdevice #0
      pi@raspberrypi:~ $ arecord -l
      **** List of CAPTURE Hardware Devices ****
      card 2: seeed2micvoicec [seeed-2mic-voicecard], device 0: bcm2835-i2s-wm8960-hifi wm8960-hifi-0 [bcm2835-i2s-wm8960-hifi wm8960-hifi-0]
        Subdevices: 1/1
        Subdevice #0: subdevice #0
      pi@raspberrypi:~ $
      • Test speaker and mic by command " arecord -f cd -Dhw:(card #) | aplay -Dhw: (card #)". Replace the card # as corresponding to your device card number as shown as example here "card 2: seeed2micvoicec [seeed-2mic-voicecard]"
      pi@raspberrypi:~ $ arecord -f cd -Dhw:2 | aplay -Dhw:2

      Configure sound settings and adjust volume with alsamixer:

      • alsamixer is a graphical mixer program for the Advanced Linux Sound Architecture (ALSA) that is used to configure sound settings and adjust the volume.
        pi@raspberrypi:~ $ alsamixer
        • For adjusting sound on ReSpeaker 2-Mics Pi HAT press F6 then select sound card. Select seeed-2mic-voicecard. Now you can configure sound and adjust volume as shown below.
          The Left and right arrow keys are used to select the channel or device and the Up and Down Arrows control the volume for the currently selected device. Quit the program with ALT+Q, or by hitting the Esc key.
           
          Use on board RGB APA102 LEDs:
          Each on-board APA102 LED has an additional driver chip. The driver chip takes care of receiving the desired color via its input lines, and then holding this color until a new command is received.
          • To test using ReSpeaker mic hat library, input these commands on terminal.
          sudo pip install spidev
          cd ~/
          git clone https://github.com/respeaker/mic_hat.git
          cd mic_hat
          python pixels.py
          • Or for manual control of each LEDs use Thonny Python IDE or any other python programming IDE on RPI. First install its driver
          pi@raspberrypi:~ $ sudo pip3 install apa102-pi
          •  Then test this code rgb_led.py or copy below code.
          from apa102_pi.driver import apa102
          import time
          
          # Initialize the library and the strip
          strip = apa102.APA102(num_led=3, global_brightness=20, mosi=10, sclk=11,
                                order='rbg')
          
          # Turn off all pixels (sometimes a few light up when the strip gets power)
          strip.clear_strip()
          
          # Prepare a few individual pixels
          # strip.set_pixel_rgb(LED #, Color Value)
          strip.set_pixel_rgb(0, 0xFF0000)  # Red
          strip.set_pixel_rgb(1, 0xFFFFFF)  # White
          strip.set_pixel_rgb(2, 0x00FF00)  # Green
          
          # Copy the buffer to the Strip (i.e. show the prepared pixels)
          strip.show()
          
          # Wait a few Seconds, to check the result
          time.sleep(20)
          
          # Clear the strip
          strip.clear_strip()
          strip.cleanup()
          • Run it and you can see the APA102 LEDs change color as red, white, and green.

           

          Use on board User Button (Connected to GPIO17):

          • Install driver by using this command on terminal.
            sudo pip install rpi.gpio
            import RPi.GPIO as GPIO
            import time
            
            # Print Start of test
            print("ReSpeaker 2-Mic Pi Button test")
            
            # User button pin
            BUTTON = 17
            # User button setup
            GPIO.setmode(GPIO.BCM)
            GPIO.setup(BUTTON, GPIO.IN)
            
            # Save previous state
            previousState = GPIO.input(BUTTON)
            
            # Unending Loop (main)
            while True:
                # Get button state
                currentState = GPIO.input(BUTTON)
                # Check if any difference
                if currentState != previousState:
                    # Store current state as previous
                    previousState = currentState
                    # Check the current state of the button
                    if currentState:
                        # Print if button is not clicked
                        print("Button is not clicked")
                    else:
                        # Print if clicked
                        print("Button is clicked")
            • Run it and it should display on the terminal like these.
            ReSpeaker 2-Mic Pi Button test
            Button is clicked
            Button is not clicked
            Button is clicked
            Button is not clicked
            Button is clicked
            Button is not clicked
            Button is clicked
            Button is not clicked

            Voice Recording using ReSpeaker 2 Mic Pi Hat:

            • Install driver by using this command on terminal.
              sudo pip install pyaudio

              import pyaudio
              import wave
              import numpy as np
              from subprocess import call
              
              class RecordAudio:
                  '''
                      Audio Recording
                  '''
                  # Initialize PyAudio
                  pyaud = pyaudio.PyAudio()
              
                  
                  def record(self, rate, channels, width, deviceIndex,
                          chunk, recordSeconds, fileName, extractChannel):
                      '''
                          Record Audio
                      '''
                      
                      # Record settings
                      stream = self.pyaud.open(
                                  rate=rate,
                                  format= self.pyaud.get_format_from_width(width),
                                  channels=channels,
                                  input=True,
                                  input_device_index=deviceIndex)
              
                      # Print start of recording
                      print("Recording audio")
                      
                      # Get audio data and save as frame buffer.
                      frames = []
                      for i in range(0, int(rate / chunk * recordSeconds)):
                          # Audio data
                          data = stream.read(chunk)
                          # For extracted channel
                          if extractChannel is not None:
                              # Get data for extracted channel
                              a = np.frombuffer(data,dtype=np.int16)[extractChannel::channels]
                              frames.append(a.tostring())
                          # For using both channels
                          else:
                              # Get audio data from channels
                              frames.append(data)
                      
                      # Close recording
                      stream.stop_stream()
                      stream.close()
                      self.pyaud.terminate()
              
                      # Print end of recording
                      print("Done recording, now saving file...")
                      
                      # Saving file
                      wf = wave.open(fileName, 'wb')
                      if extractChannel is not None:
                          wf.setnchannels(1)
                      else:
                          wf.setnchannels(channels)
                      wf.setsampwidth(self.pyaud.get_sample_size(self.pyaud.get_format_from_width(width)))
                      wf.setframerate(rate)
                      wf.writeframes(b''.join(frames))
                      wf.close()
              
                      print("Done recording and file being saved.")
                  
                  def getAudioDeviceInfo(self):
                      '''
                          Audio Device Info
                      '''
                      # Settings to get device audio info
                      info = self.pyaud.get_host_api_info_by_index(0)
                      numdevices = info.get('deviceCount')
               
                      for i in range(0, numdevices):
                              if (self.pyaud.get_device_info_by_host_api_device_index(0, i).get('maxInputChannels')) > 0:
                                  print("Input Device id ", i, " - ", self.pyaud.get_device_info_by_host_api_device_index(0, i).get('name'))
              
                  def playAudio(self, fileName):
                      '''
                          Play Audio through aplay
                      '''
                      call(["aplay", fileName])
              
              # Print Start of test
              print("ReSpeaker 2-Mic Pi Audio test")
              
              # Test of audio recording
              recordAudio = RecordAudio()
              
              # Audio Settings
              RESPEAKER_RATE = 16000
              RESPEAKER_CHANNELS = 2 
              RESPEAKER_WIDTH = 2
              CHUNK = 1024
              RECORD_SECONDS = 5
              WAVE_OUTPUT_FILENAME = "recorded_audio.wav"
              # Refer to input device ID by running recordAudio.getAudioDeviceInfo()
              RESPEAKER_INDEX = 0
              # Extract data for specific channel. 
              # Channel 1 set it to 0
              # channel 2 set it to 1
              # If no extracted channel set it to None
              EXTRACT_CHANNEL = None
              
              # Run get audio device infos.
              # recordAudio.getAudioDeviceInfo()
              
              # Run record audio
              recordAudio.record(RESPEAKER_RATE,RESPEAKER_CHANNELS,RESPEAKER_WIDTH, 
              RESPEAKER_INDEX, CHUNK, RECORD_SECONDS, 
              WAVE_OUTPUT_FILENAME, EXTRACT_CHANNEL)
              
              print("Playing recorded audio..")
              
              # Play recorded audio
              recordAudio.playAudio(WAVE_OUTPUT_FILENAME)

              • Run the python code, check if you encounter this error:
                OSError: [Errno -9998] Invalid number of channels

                • If you encounter above error, change the value of RESPEAKER_INDEX = 0 to your own device ID. Sample shown below:
                  Input Device id  0  -  seeed-2mic-voicecard: bcm2835-i2s-wm8960-hifi wm8960-hifi-0 (hw:2,0)

                  • Run code again. Audio recording is successful when you see similar terminal output below, and your recorded audio is played.
                    ReSpeaker 2-Mic Pi Audio test
                    Input Device id  0  -  seeed-2mic-voicecard: bcm2835-i2s-wm8960-hifi wm8960-hifi-0 (hw:2,0)
                    Input Device id  4  -  capture
                    Input Device id  6  -  array
                    Input Device id  8  -  default
                    Recording audio
                    Done recording, now saving file...
                    Done recording and file being saved.
                    Playing recorded audio..
                    Playing WAVE 'recorded_audio.wav' : Signed 16 bit Little Endian, Rate 16000 Hz, Stereo

                    • To extract data by channel, you can edit this part of the python code:
                    # Extract data for specific channel. 
                    # Channel 1 set it to 0
                    # channel 2 set it to 1
                    # If no extracted channel set it to None
                    EXTRACT_CHANNEL = None

                    Libraries Used

                    https://github.com/respeaker/seeed-voicecard.git

                    https://github.com/respeaker/mic_hat.git

                    https://github.com/tinue/apa102-pi

                    https://github.com/createlabz/createlabz-public/blob/main/raspberry/respeaker/2-mic-pi-hat/

                     

                    Conclusion

                    This device is useful in multiple ways. It can be as a voice recorder, voice recognition for security, as Alexa or Google Assistance, and many more. There are multiple ideas that this device can be used. 

                     

                    References

                    https://wiki.seeedstudio.com/ReSpeaker_2_Mics_Pi_HAT/

                    2-mic-piAlexaGoogle assistantRaspberry piRespeakerRpiVoice

                    Leave a comment

                    All comments are moderated before being published