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

  • Raspberry Pi 3B+ (Compatible on: Raspberry Pi Zero and Zero W, Raspberry Pi B+, Raspberry Pi 2 B, Raspberry Pi 3 BRaspberry Pi 3 B+, Raspberry Pi 3 A+)

  • ReSpeaker 2-Mics Pi HAT
  • 
    
  • Speaker (or Headset) with 3.5mm Audio Jack
  •  

      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