md
New Hardware: Micro SD Cards, ReSpeaker 2-Mics Pi HAT and Xiaomi 3G Router
March 13, 2018
Update: March 22, 2018

This post is just like a ubiquitous YouTube "mailbag" video only without a video feed and without a sound track. In the space of a few days, I have received, from far, far away, five 8G micro SD cards, two ReSpeaker 2-Mics Pi HATs and a Xiaomi Mi WiFi 3G router. Here are my first impressions.

Table of Contents

  1. Micro SD Cards
  2. ReSpeaker 2-Mics Pi Hat
  3. Xiaomi 3G Router

  1. Micro SD Cards
  2. image of card Recently I tested some Verbatin 16G micro SD cards and was disappointed with the results. The information found on the web, when searching for test software, made it sound like the market was flooded with cheap cards of dubious quality which did not reach the advertised read and write speeds. Worse, some cards apparently did not even have the stated capacity. I felt a bit sheepish because I had just ordered cheap "off brand" 8G cards. I was prepared to write off this purchase thinking that I deserved what I got for trying to pinch a few pennies.

    Here are representative results of the F3 write and read tests as performed on all five cards.

    michel@hp:~$ sudo .local/bin/f3write "/media/michel/SD Card" F3 write 7.0 Copyright (C) 2010 Digirati Internet LTDA. This is free software; see the source for copying conditions. Free space: 7.49 GB Creating file 1.h2w ... OK! Creating file 2.h2w ... OK! Creating file 3.h2w ... OK! Creating file 4.h2w ... OK! Creating file 5.h2w ... OK! Creating file 6.h2w ... OK! Creating file 7.h2w ... OK! Creating file 8.h2w ... OK! Free space: 0.00 Byte Average writing speed: 11.64 MB/s michel@hp:~$ sudo .local/bin/f3read "/media/michel/SD Card" F3 read 7.0 Copyright (C) 2010 Digirati Internet LTDA. This is free software; see the source for copying conditions. SECTORS ok/corrupted/changed/overwritten Validating file 1.h2w ... 2097152/ 0/ 0/ 0 Validating file 2.h2w ... 2097152/ 0/ 0/ 0 Validating file 3.h2w ... 2097152/ 0/ 0/ 0 Validating file 4.h2w ... 2097152/ 0/ 0/ 0 Validating file 5.h2w ... 2097152/ 0/ 0/ 0 Validating file 6.h2w ... 2097152/ 0/ 0/ 0 Validating file 7.h2w ... 2097152/ 0/ 0/ 0 Validating file 8.h2w ... 1032128/ 0/ 0/ 0 Data OK: 7.49 GB (15712192 sectors) Data LOST: 0.00 Byte (0 sectors) Corrupted: 0.00 Byte (0 sectors) Slightly changed: 0.00 Byte (0 sectors) Overwritten: 0.00 Byte (0 sectors) Average reading speed: 15.70 MB/s

    This is not as bad as I feared. There appears to be no capacity problem and these cards are truly class 10 although the read speed is definitely inferior to the Verbatim cards I have been using. Based on write speed, these BiNFUL cards would be better in a camera but I have not tested that. I am using one card in my Raspberry Pi 3 currently without problems.

    The cards come with SD card adapters. They felt more flimsy than the adapters that came with the Vertabim micro SD cards. However, the micro card fits snugly inside the adapter and the latter fits well in the SD card reader on my desktop computer. No complaints here either.

    Of course only usage over some time will tell if these cards are dependable. Nevertheless, I have ordered a few more 8G cards as well as some 16G cards from the same vendor and I am crossing my fingers hoping that this will work out.

    Product: BiNFUL 8GB Class 10 Micro SD Card
    Ordered: Jan. 30 2018
    Received: March 13 2018
    Cost: 5.48 $ CDN/piece free shipping
    Source: AliExpress Store BESTHINKING

    This does not constitute an endorsement. I just don't know enough. As I said, all five cards passed the test but the Verbatim cards were just as good initially but have now become unreliable.

  3. ReSpeaker 2-Mics Pi Hat
  4. The main source of information when I set up Google Assistant on an Orange Pi Zero was an article by CNXSoft. I was surprised that a USB microphone dongle was used instead of the built-in microphone which I found quite adequate. I should point out that CNXSoft gave instructions for using the built-in microphone. Later, when I wanted to do voice recognition on a Raspberry Pi, I decided to try the same type of microphone. I found the results wanting to say the least. So I turned to the ReSpeaker 2-Mics Pi HAT over at seeed, which seemed to offer an interesting solution. The Raspberry Pi Zero sized card has a reasonable price, but shipping was almost one and a half time more which seems way too much given that it took more than 7 weeks for the product to arrive. It took almost a month for the package to travel by air to Canada! The long three weeks to get to me within the country is probably down to my fault because there was an extraneous digit in the postal code.

    Installing the driver

    So after installing and updating Raspbian (Stretch, server version) on a new 8GB micro SD card, I followed the instructions on the seeed site to install the drivers.

    pi@rpi3:~ $ sudo apt install git ... pi@rpi3:~ $ git clone https://github.com/respeaker/seeed-voicecard.git pi@rpi3:~ $ cd seeed-voicecard pi@rpi3:~/seeed-voicecard $ sudo ./install.sh 2mic ... ------------------------------------------------------ Please reboot your raspberry pi to apply all settings Enjoy! ------------------------------------------------------ pi@rpi3:~/seeed-voicecard $ halt

    I then powered down the Raspberry Pi, connected the ReSpeaker hat and plugged in a powered set of speakers to the 3.5 mm jack on the hat and another set of powered speakers to the 3.5 mm jack on the Raspberry Pi.

    After powering up and starting an ssh session, it was then a simple matter to verify that the installation was done correctly by listing capture and playback devices.

    pi@rpi3:~ $ arecord -l **** List of CAPTURE Hardware Devices **** card 1: seeed2micvoicec [seeed-2mic-voicecard], device 0: bcm2835-i2s-wm8960-hifi wm8960-hifi-0 [] Subdevices: 1/1 Subdevice #0: subdevice #0 pi@rpi3:~ $ aplay -l **** List of PLAYBACK Hardware Devices **** card 0: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA] Subdevices: 8/8 Subdevice #0: subdevice #0 Subdevice #1: subdevice #1 Subdevice #2: subdevice #2 Subdevice #3: subdevice #3 Subdevice #4: subdevice #4 Subdevice #5: subdevice #5 Subdevice #6: subdevice #6 Subdevice #7: subdevice #7 card 0: ALSA [bcm2835 ALSA], device 1: bcm2835 ALSA [bcm2835 IEC958/HDMI] Subdevices: 1/1 Subdevice #0: subdevice #0 card 1: seeed2micvoicec [seeed-2mic-voicecard], device 0: bcm2835-i2s-wm8960-hifi wm8960-hifi-0 [] Subdevices: 1/1 Subdevice #0: subdevice #0

    There is only one capture device, the two microphones of the ReSpeaker, which is card 1. There are three playback devices. Two are on card 0 which is the audio output of the Raspberry Pi. They are the 3.5 mm analogue output (device 0) and the digital HDMI output (device 1). Card 1, the ReSpeaker, has one device, the WM8960 DAC connected to the 3.5 mm jack.

    If you do the suggested audio test

    pi@rpi3:~ $ arecord -f cd -D hw:1 | aplay -D hw:1
    move the speakers away from the microphones or else you will get a feedback loop, sort of the equivalent of an infinitely reflected image bouncing between two mirrors, only the sound gets louder and louder. It rather reminded me of the spy film and book IPCRESS File. I performed a more classical test first recording some sound in a wav file and then playing it back.

    pi@rpi3:~ $ arecord -f cd -d 10 -D hw:1 test.wav Recording WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo playback through the ReSpeaker audio output: pi@rpi3:~ $ aplay -D hw:1 test.wav Playing WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo playback through the Raspberry Pi built-in audio output: pi@rpi3:~ $ aplay -D hw:0 test.wav Playing WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
    For the latter, I had to adjust the playback volume using alsamixer in a parallel ssh session before hearing anything.

    I learned from Lex that the "... alsa configuration [file /etc/asound.conf] uses dmix plugin and dsnoop plugin to support multiple applications to play and record simultaneously." Here is the content of the file.

    # The IPC key of dmix or dsnoop plugin must be unique # If 555555 or 666666 is used by other processes, use another one pcm.!default { type asym playback.pcm "playback" capture.pcm "capture" } pcm.playback { type plug slave.pcm "dmixed" } pcm.capture { type plug slave.pcm "array" } pcm.dmixed { type dmix slave.pcm "hw:1,0" ipc_key 555555 } pcm.array { type dsnoop slave { pcm "hw:1,0" channels 2 } ipc_key 666666 }

    As can be seen, card 1, the ReSpeaker, is defined as both default capture device and default playback device. So the -D hw:1 command line parameter was not necessary in the arecord and aplay examples above.

    Testing the Onboard LEDS

    There are 3 RGB leds, type APA102, on the card. These are controlled over an SPI bus. To test them, I enabled the SPI bus with raspi-config and then installed another git repository from seeed and the Python SPI bus bindings.

    pi@rpi3:~ $ git clone https://github.com/respeaker/mic_hat.git Cloning into 'mic_hat'... remote: Counting objects: 28, done. remote: Total 28 (delta 0), reused 0 (delta 0), pack-reused 28 Unpacking objects: 100% (28/28), done. pi@rpi3:~ $ cd mic_hat pi@rpi3:~/mic_hat $ mkvenv venv creating virtual environment /home/pi/mic_hat/venv updating virtual environment /home/pi/mic_hat/venv pi@rpi3:~/mic_hat $ ve venv (venv) pi@rpi3:~/mic_hat $ pip install spidev Collecting spidev Downloading https://www.piwheels.org/simple/spidev/spidev-3.2-cp35-cp35m-linux_armv7l.whl Installing collected packages: spidev Successfully installed spidev-3.2 (venv) pi@rpi3:~/mic_hat $ python pixels.py get out of the loop with CtrlC ^C(venv) pi@rpi3:~/mic_hat $

    The command mkvenv creates and updates a Python 3 virtual environment, while ve activates it. This is documented in a previous post: Python 3 virtual environments.

    Working with Google Assistant

    One of the developers working on Raspberry Pi based Google Assistant (GA) was rather negative about using ReSpeaker hats back in December of last year. I think that was rather too pessimistic. I managed to get GA running. As before, I will not go into the tedious details of creating a project and getting the appropriate credentials. For one thing, this is a moving target as Google is constantly changing the GA SDK and the required steps in registering and then accessing projects. Suffice it to say that I followed the instructions at Configure a Developer Project and Account Settings. Here is the information about the project I created on the site:

    Project name: ga-Respeaker2
    Project ID: ga-respeaker2
    Product name : mics
    Manufacturer name : mycomp (never used)
    Device type: Light (skip defining traits)
    Device model ID: ga-respeaker2-mics-cab8un
    It is weird that our DIY Google Home like device has to be given a device type that can only correspond to an actuator. That is one of the new things in this newest version of the SDK. The Device model ID was proposed by the project console and is clearly composed of the Project ID, the Product name and a random code. I did not bother trying to change it. The two items in bold are needed later on.

    A couple of packages (development libraries) have to be installed in the system before the Python libraries are added to the Python virtual environment.

    pi@rpi3:~ $ sudo apt-get install portaudio19-dev libffi-dev libssl-dev Reading package lists... Done ... After this operation, 13.8 MB of additional disk space will be used. Do you want to continue? [Y/n] y .. pi@rpi3:~ $ cd mic_hat pi@rpi3:~/mic_hat $ ve venv (venv) pi@rpi3:~/mic_hat $ pip install --upgrade google-assistant-library ... (venv) pi@rpi3:~/mic_hat $ pip install --upgrade google-assistant-sdk[samples] ... (venv) pi@rpi3:~/mic_hat $ pip install --upgrade google-auth-oauthlib[tool] ... (venv) pi@rpi3:~/mic_hat $ google-oauthlib-tool --scope https://www.googleapis.com/auth/assistant-sdk-prototype \ > --save --headless --client-secrets credentials.json Please visit this URL to authorize this application: https://accounts.google.com/o/oauth2/auth?response_type... Go to the very long link, log into your Google account and then copy the displayed authorization code Enter the authorization code: 4/XXXX............7776 credentials saved: /home/pi/.config/google-oauthlib-tool/credentials.json

    That should complete the setup; it is now possible to try to use Google Assistant. Note that a local .asoundrc file was not created. To be candid, I did make one following the SDK instruction, but that only resulted in no audio output. It took a while to figure out that I had to get rid of that configuration file. What finally helped me was trying to run the program googlesamples-assistant-audiotest. As can be seen below, nothing was working when the configuration file was in place.

    (venv) pi@rpi3:~/mic_hat $ googlesamples-assistant-audiotest Traceback (most recent call last): File "/home/pi/mic_hat/venv/bin/googlesamples-assistant-audiotest", line 11, in ... sounddevice.PortAudioError: Error opening RawStream: Unanticipated host error [PaErrorCode -9999]: 'Device or resource busy' [ALSA error -16]

    I removed the file and rebooted to be sure and then the program worked.

    (venv) pi@rpi3:~/mic_hat $ googlesamples-assistant-audiotest INFO:root:Starting audio test. INFO:root:Recording samples. talk for 5 seconds INFO:root:Finished recording. INFO:root:Playing back samples. listen to your recorded voice for 5 seconds INFO:root:Finished playback. INFO:root:audio test completed.

    Once the googlesamples-assistant-audiotest is passed, I tested two of the applications installed: google-assistant-demo which uses hotword detection (OK Google) to start a conversation and googlesamples-assistant-pushtotalk where the conversation is launched by pressing the Enter key.

    (venv) pi@rpi3:~ $ google-assistant-demo --device_model_id ga-respeaker2-mics-cab8un \ > --project_id ga-respeaker2 device_model_id: ga-respeaker2-mics-cab8un device_id: 0DB103C82FBA0EBB21E1DA840C646DA9 https://embeddedassistant.googleapis.com/v1alpha2/projects/ga-respeaker2/devices/0DB103C82FBA0EBB21E1DA840C646DA9 200 ON_MUTED_CHANGED: {'is_muted': False} ON_START_FINISHED "ok google" ON_CONVERSATION_TURN_STARTED quelle heure est-il ? ON_END_OF_UTTERANCE ON_RECOGNIZING_SPEECH_FINISHED: {'text': 'quelle heure est-il'} ON_RESPONDING_STARTED: {'is_error_response': False} "il est 18 heures 47" ON_RESPONDING_FINISHED ON_CONVERSATION_TURN_FINISHED: {'with_follow_on_turn': False} "ok google" ON_CONVERSATION_TURN_STARTED "what time is it?" ON_END_OF_UTTERANCE ON_RECOGNIZING_SPEECH_FINISHED: {'text': 'what time is it'} ON_RESPONDING_STARTED: {'is_error_response': False} "il est 18 heures 47" ON_RESPONDING_FINISHED ON_CONVERSATION_TURN_FINISHED: {'with_follow_on_turn': False} get out of the loop with CtrlC (venv) pi@rpi3:~/mic_hat $ googlesamples-assistant-pushtotalk --device-model-id ga-respeaker2-mics-cab8un \ > --project-id ga-respeaker2 INFO:root:Connecting to embeddedassistant.googleapis.com INFO:root:Using device model ga-respeaker2-mics-cab8un and device id 14a074a6-27c9-11e8-9fb7-b827ebff56fd Press Enter to send a new request... Enter INFO:root:Recording audio request. WARNING:root:SoundDeviceStream read overflow (3200, 6400) "Quelle heure est-il?" INFO:root:Transcript of user request: "tell". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "tell". INFO:root:Playing assistant response. INFO:root:End of audio request detected INFO:root:Transcript of user request: "tell him". INFO:root:Playing assistant response. INFO:root:Finished playing assistant response. Press Enter to send a new request... Enter INFO:root:Recording audio request. "What time is it?" INFO:root:Transcript of user request: "what". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "what time". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "what time is". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "what time is it". INFO:root:Playing assistant response. INFO:root:End of audio request detected INFO:root:Transcript of user request: "what time is it". INFO:root:Playing assistant response. "It is 7:26" INFO:root:Finished playing assistant response. Press Enter to send a new request... INFO:root:Recording audio request. get out of the loop with CtrlC

    As can be seen, both worked albeit slightly differently. First of all google-assistant-demo is obviously linked with my Google Home account which explains why the output was in French. I was surprised that I could query GA in either English or French and get a correct answer. That prompted me to check, and it turns out that the same thing is true of my Google Home mini. I had never tried but it does answer my English language queries in French. Furthermore, my IFTTT rules can be invoked (see Google Home Mini with Domoticz using IFTTT) with google-assistant-demo but, of course, only in the language in which the rules are written.

    In the original version of the post, I misrepresented the language capabilities of googlesamples-assistant-pushtotalk. As the following shows, it is also multilingual.
    March 22, 2018

    By default, googlesamples-assistant-pushtotalk did not pick up the language settings of my Google Home account as can be seen above. However if I specify a language parameter then it behaves more like google-assistant-demo.

    (venv) pi@rpi3:~/mic_hat $ googlesamples-assistant-pushtotalk --device-model-id ga-respeaker2-mics-cab8un \ > --project-id ga-respeaker2 --lang fr-CA INFO:root:Connecting to embeddedassistant.googleapis.com INFO:root:Using device model ga-respeaker2-mics-rcl7xe and device id 91b7128e-2dd1-11e8-a78f-b827ebaa03a8 Press Enter to send a new request... Enter INFO:root:Recording audio request. "Quelle heure est-il ?" INFO:root:Transcript of user request: "quelle". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "quelle heure". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "quelle heure est-il". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "quelle heure est-il". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "quelle heure est-il". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "quelle heure est-il". INFO:root:Playing assistant response. INFO:root:End of audio request detected INFO:root:Transcript of user request: "quelle heure est-il". INFO:root:Playing assistant response. "Il est 10 heures 38" INFO:root:Finished playing assistant response. Press Enter to send a new request... Enter INFO:root:Recording audio request. "Quelle heure est-il ?" INFO:root:Transcript of user request: "ouais". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "what". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "WhatsApp". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "what time". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "what time is". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "what time is it". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "what time is it". INFO:root:Playing assistant response. INFO:root:Transcript of user request: "what time is it". INFO:root:Playing assistant response. INFO:root:End of audio request detected INFO:root:Transcript of user request: "what time is it". INFO:root:Playing assistant response. "Il est 10 heures 38" INFO:root:Finished playing assistant response. Press Enter to send a new request... get out of the loop with CtrlC or CtrlZ

    Again I could invoke IFTTT rules that I had set up for my use with my Google Home Mini.

    For unfathomable reasons, both applications have the same command line model and project id, there is an exchange of underscores and dashes in their names:

                     google-assistant-demo: --device_model_id --project_id
        googlesamples-assistant-pushtotalk: --device-model-id --project-id

    This is a good beginning. I think it will be possible to create something useful with this device. Since I bought two hats (to amortise the shipping costs), there is enough cash expended on them to motivate me to use them.

    Product: ReSpeaker 2-Mics Pi HAT v1.0
    Ordered: Jan. 17 2018
    Received: March 9 2018
    Cost: US$ 9.90 x 2 + US$ 14.08 shipping = CDN$ 43.37
    Source: seeed

  5. Xiaomi 3G Router
  6. Some time ago, I replaced the firmware of an old Rosewill 300M Wireless N Router (a rebranded TP-Link TL-WR841N/ND v7) with OpenWrt 15.05.1. Later I updated to LEDE 17.01.4 (which was then a fork but is now merged back into OpenWrt). At the time, I was musing about running Domoticz on the router. I more or less gave up when I realised that there was just not enough flash memory.

    When I saw that the Xiaomi 3G Router has 128MB of flash memory and 256MB of RAM and noticed that some had managed to replace its Chinese language firmware with OpenWrt, I decided to purchase one with the ultimate goal of trying to run Domoticz on it.

    The long and the short of it is that the home automation software is not installed even though, I managed to replace the firmware with OpenWrt. While work is going on to add a Domoticz/Open-ZWave package to OpenWrt but it is not yet available for installation. I will wait a bit before continuing on this project.

    If you are trying to install OpenWrt on the router or even just trying to set it up, I suggest using Google's web browser, Chromium, because of its built-in translation mechanism (or install something equivalent in your favourite web client). Also, you will find that the Android app is in English, and presumably so is the IOS app.

    Product page (Chinese)
    Product FAQ (Chinese)
    Hardware Device Wiki
    How to Flash Xiaomi Mi WiFi 3G Router Firmware
    LEDE - MiWiFi 3G - UniFi Ready
    LEDE Project Forum - Xiaomi WiFi Router 3G
    OpenWrt - Xiaomi Mi WiFi R3G
    OpenWrt - Image files for the ramips/mt7621 target

    I followed the instruction found in the above references. Here is some additional information that could be useful. At one point, you have to download the developer version of the router firmware. The instructions say to look for it at http://www.miwifi.com/miwifi_download.html but it now seems to be found on http://www1.miwifi.com/miwifi_download.html. Here are direct links to the firmware from Xiaomi:

        ROM for R3G stable version
        Version 2.26.3 (updated on November 8
        http://bigota.miwifi.com/xiaoqiang/rom/r3g/miwifi_r3g_firmware_0a271_2.26.3.bin
    
        ROM for R3G development version
        Version 2. 25. 122 (August 24 update
        http://bigota.miwifi.com/xiaoqiang/rom/r3g/miwifi_r3g_firmware_c2175_2.25.122.bin

    I had a hard time in getting another needed file: miwifi_ssh.bin. I am not too sure how I managed it. But it is necessary to open an account (using the Android/IOS app) and I think it was necessary to use the router itself to connect to the web. As I recall, I was using both Chromium and Firefox at the same time. Perhaps things would be simpler on a Windows computer.

    Since LEDE has been merged back into OpenWrt the two files making up the firmware to flash on the router have been renamed:

        lede-ramips-mt7621-mir3g-squashfs-kernel1.bin 
          ==>  openwrt-ramips-mt7621-mir3g-squashfs-kernel1.bin
        lede-ramips-mt7621-mir3g-squashfs-rootfs0.bin 
          ==>  openwrt-ramips-mt7621-mir3g-squashfs-rootfs0.bin

    I found that the radios were not enabled and not even defined once the OpenWrt firmware had been flashed. Although there are instructions on how to go about defining the interfaces and enabling the radios, the easiest solution turned out to be installing LuCI and then upgrading the OpenWrt firmware. It is a simple point and click procedure in the router admin web GUI at http://192.168.1.1. The upgrade file is named openwrt-ramips-mt7621-mir3g-squashfs-sysupgrade.tar. Do not worry that it is not named *-sysupgrade.bin. As confirmed in upgrading from a sysupgrade.tar the sysupgrade utility will handle the tar archive correctly.

    Product: Xiaomi MiWiFi 3G Router
    Ordered: Feb. 21 2018
    Received: March 1 2018
    Cost: US$ 45,67 with shipping = CDN$ 59,73
    Source: Gearbest, Banggood, AliExpress.