ラズベリーパイ2にコマンドボタンをつけてみた

ラズベリーパイにスイッチをつけて、GPIOからシャットダウンしたり、リブートしたりしている人がいる。
確かに、リモートで接続していると、接続が切れてしまったりすると、どうしようもなくなって、やむなく、”えいっ!”っと、電源スイッチを切るのだけど、気の小さい僕には、精神衛生上、はなはだ、よろしくない。
と、言うわけで、シャットダウンスイッチをつけてみた。
せっかくなので、同時に、アプリケーションをスタートしたり、ストップしたりするコマンドボタンも作ってみた。
このコマンドボタンは、監視カメラ用に走らせている、motion のプログラムを起動したり、停止させたりするために利用している。 まぁ、コマンドスイッチ自体は、Python のプログラムしだいで、どのようにも利用できる。
ボタンは、前回のRTCの基盤のあいたところにスイッチを並べてみた。LED点灯用のピンも設定したが、途中で面倒になり、実装は、していない。 /^^;)

スイッチは、前回のRTCモジュールを組んだときの基板のあいたところにヘッダピンとともに並べてみた。
f:id:manpukukoji:20160723214957j:plain
Paithonのスクリプトは、以下のような感じで組んでみた。

#!/usr/bin/python
#coding: UTF-8
import time
import RPi.GPIO as GPIO
import os

System_Reboot=5
System_Shutdown=6
Monitor_Start=13
Monitor_Stop=19
pin_out=21

def SysRBoot_callback(gpio_pin):

	GPIO.output(pin_out, True)
	print "Reboot now!"
	os.system("sudo shutdown -r now")

def SysShut_callback(gpio_pin):

	GPIO.output(pin_out, True)
	print "Shutdown now!"
	os.system("sudo shutdown -h now")

def MStart_callback(gpio_pin):

	if os.path.exists("/var/run/motion/motion.pid"):
		time.sleep(1)
	else:
		os.system("sudo service motion start")
		print "motion start"

def MStop_callback(gpio_pin):

	if os.path.exists("/var/run/motion/motion.pid"):
		os.system("sudo service motion stop")
		print "motion stop"

GPIO.setmode(GPIO.BCM)
#GPIO.cleanup()
GPIO.setup(System_Reboot,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(System_Shutdown,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(Monitor_Start,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(Monitor_Stop,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(pin_out,GPIO.OUT)
GPIO.add_event_detect(System_Reboot,GPIO.RISING)
GPIO.add_event_detect(System_Shutdown,GPIO.RISING)
GPIO.add_event_detect(Monitor_Start,GPIO.RISING)
GPIO.add_event_detect(Monitor_Stop,GPIO.RISING)
GPIO.add_event_callback(System_Reboot,SysRBoot_callback)
GPIO.add_event_callback(System_Shutdown,SysShut_callback)
GPIO.add_event_callback(Monitor_Start,MStart_callback)
GPIO.add_event_callback(Monitor_Stop,MStop_callback)

try:
	while True:
		time.sleep(1)
except KeyboardInterrupt:
	GPIO.cleanup()

RasPi2にRTC(RX-8564) をつけてみる

f:id:manpukukoji:20160723215217j:plainラズベリーパイ2は、時計を持っていないので、シャットダウンすると再立ち上げの際に時刻をセットしなおさないと最後にシャットダウンした時間からの時刻になってしまう。 もちろん、インターネットに接続されていると、ネットワークからNTPで時刻をセットするので問題ないのだけれども、スタンドアロンで使うときには、毎回時刻をセットしなければ正しい時刻が得られない。
と、言うわけで、電源を落としても時刻を保持できるようにRTCモジュールを接続した。
すでに、RTCの接続については、沢山のサイトで説明されているので、あちこち参考にさせていただいた。
今回、僕が使ったのは、マルツで売っている MRX-8564 といいうモジュールでエプソンのRX-8564LC というICが乗っかっている。 これに、ボタン電池をくっつけて、ラズパイにI2Cで接続。
基盤作成は、コマンド起動用のスイッチとあわせて、こんな感じで作ってみた。
f:id:manpukukoji:20160723212535j:plain

じつをいうと、最初、ラズパイの電源からのラインにダイオードを入れてなかったので、RTCをつなぐと、いきなりラズパイのLEDが点灯したので、ラズパイが起動したのかと思って、びっくりした! さすがにボタン電池では、起動するところまでは行かなかったみたいだけど、LEDくらいは、点くんだね。 まぁ、当たり前っちゃ、あたりまえ何だけど・・・。
あわてて、こちらにもダイオードを追加したしだいです。

ラズベリーパイの設定は、以下のサイトを参考にさせてもらった。
http://tomosoft.jp/design/?p=5812
http://news.mynavi.jp/articles/2014/08/21/raspberry-pi4/002.html
http://wp.developapp.net/?p=3362

これらのサイトに詳しく説明されているので改めて説明するまでも無いけど、
僕の場合、最後の rc.local を編集して、自動起動するところで、ひっかかった。
確かに、設定をしてあるのだけれども、シャットダウンしてしばらくしてから立ち上げると、正しい時刻が設定されていない。 が、マニュアルで設定して、hwclock を表示させると、正しい時刻を表示するので、RTC自体は、ちゃんと動いているみたい。
つまり、立ち上げのときにちゃんと設定されていないみたいなので、もう一度、rc.local を良く見てたら、ちゃんと、以下のように書いてある。
“In order to enable or disable this script just change the execution bits.
By default this script does nothing”
「このスクリプトを有効/無効にするには、実行ビットを書き換えてね。
デフォルトでは、このスクリプトは、なんにもせんからね。」
と、いうことで、
$ sudo chmod +x /etc/rc.local
と、やったら、ちゃんと立ち上がりで時刻がRTCから設定されるようになった。

ラズパイも、ハードもOSもどんどんアップデートされているので、先にやった人のときは、必要なかった事が必要になってたり、逆に、必要だったことが必要なかったり、編集すべき設定ファイルが変わっていたりで、なかなか、簡単にはいかないもんですね…。

ネスカフェバリスタとラズベリーパイで顔を認識したら、ナンパするバリスタ君にしてみた

ネスカフェバリスタラズベリーパイを接続してUSBカメラからキャプチャーした画像をOpenCVを使ったPythonプログラムで顔認識させ、人の顔が認識されたら、”コーヒー飲まない?”と、お誘いするバリスタ君にしてみた。
youtu.be
 
バリスタとラズパイ以外の使用機材は、以下のようなもの
  USBカメラ:iBUFFALO BSW20KM15
  WiFiアダプタ:WLI-UC-GNU2
  セルフパワーのUSBハブ
ラズベリーパイには、Python用のOpenCVをインストール。
以下のサイトを参考にさせていただいた。
Raspberry Piで画像処理ライブラリ”OpenCV”使って”顔認識”試してみた: EeePCの軌跡

上記の参考サイトを見ながら、OpenCVとサンプルをインストール

 $ sudo apt-get install libopencv-dev
 $ sudo apt-get install python-opencv

サンプルは、上記参考サイトにあるように、face.xmlとfacedetect.py をコピーし、まずは、顔認識をテストしてみる。
が、以前にも書いたが、これまで使っていたtightVNCserver では、うまく表示させることができなかったので、x11VNC というソフトをインストール。 ( $ sudo apt-get install x11vnc )
が、そのままでは、解像度が低く、VNCで画面の一部しか表示されなかったので、

 $ sudo nano /boot/config.txt
以下の部分を修正(#をはずす)
  #framebuffer_width = 1280
    #framebuffer_height = 720

と、設定を少しいじくる。
これで、なんとか顔認識ができるようになった。
いろいろなサイトで紹介されているようにモニター画面に映った顔の部分に赤い四角で枠が入るあれ、です。
このサンプルをもとに、顔が認識されたら、シリアル通信でAquesTalkPicoという音声合成ICにメッセージを送ってお話させます。
シリアル通信で発声させるのは、前回
ラズベリーパイからシリアル通信で音声合成ICを発声させてみた - 満腹居士 七転八倒の記
でも書いたが、ラズパイのPin#01, 06, 08 からICにつなぐ。
プログラムは、facedetect.py のオリジナルの部分も含めて、以下のようにした。

#!/usr/bin/python
"""
This program is demonstration for face and object detection using haar-like features.
The program finds faces in a camera image or video stream and displays a red box around them.

Original C implementation by:  ?
Python implementation by: Roman Stanchak, James Bowman
"""
import sys
import cv2.cv as cv
from optparse import OptionParser
import time
import serial
# Parameters for haar detection
# From the API:
# The default parameters (scale_factor=2, min_neighbors=3, flags=0) are tuned
# for accurate yet slow object detection. For a faster operation on real video
# images the settings are:
# scale_factor=1.2, min_neighbors=2, flags=CV_HAAR_DO_CANNY_PRUNING,
# min_size=<minimum possible face size

min_size = (20, 20)
image_scale = 2
haar_scale = 1.2
min_neighbors = 2
haar_flags = 0
count_facecheck = 0

con=serial.Serial('/dev/ttyAMA0', 9600, timeout=10)

def detect_and_draw(img, cascade):
    global count_facecheck
    # allocate temporary images
    gray = cv.CreateImage((img.width,img.height), 8, 1)
    small_img = cv.CreateImage((cv.Round(img.width / image_scale),
                               cv.Round (img.height / image_scale)), 8, 1)

    # convert color input image to grayscale
    cv.CvtColor(img, gray, cv.CV_BGR2GRAY)

    # scale input image for faster processing
    cv.Resize(gray, small_img, cv.CV_INTER_LINEAR)

    cv.EqualizeHist(small_img, small_img)

    if(cascade):
        t = cv.GetTickCount()
        faces = cv.HaarDetectObjects(small_img, cascade, cv.CreateMemStorage(0),
                                     haar_scale, min_neighbors, haar_flags, min_size)
        t = cv.GetTickCount() - t
        # print "detection time = %gms" % (t/(cv.GetTickFrequency()*1000.))
        if faces:
            for ((x, y, w, h), n) in faces:
                # the input to cv.HaarDetectObjects was resized, so scale the
                # bounding box of each face and convert it to two CvPoints
                pt1 = (int(x * image_scale), int(y * image_scale))
                pt2 = (int((x + w) * image_scale), int((y + h) * image_scale))
                cv.Rectangle(img, pt1, pt2, cv.RGB(255, 0, 0), 3, 8, 0)
                print "detection time = %gms" % (t/(cv.GetTickFrequency()*1000.))
            print count_facecheck
            count_facecheck += 1
            if count_facecheck == 5:
              con.write("? ko-hi'- nomima/se'nka?\r")

            elif count_facecheck == 50:
              con.write("? ne'e ne'e, ko-hi'- nomo'uyo\r")

            elif count_facecheck == 100:
              con.write("ko-hi'- noma'naika na'-\r")

            elif count_facecheck == 300:
              count_facecheck = 0

        else:
                count_facecheck = 0

    cv.ShowImage("result", img)

if __name__ == '__main__':

#    global count_facecheck
    parser = OptionParser(usage = "usage: %prog [options] [filename|camera_index]")
    parser.add_option("-c", "--cascade", action="store", dest="cascade", type="str", help="Haar cascade file, default %default", default = "../data/haarcascades/haarcascade_frontalface_alt.xml")
    (options, args) = parser.parse_args()

    cascade = cv.Load(options.cascade)

    if len(args) != 1:
        parser.print_help()
        sys.exit(1)

    input_name = args[0]
    if input_name.isdigit():
        capture = cv.CreateCameraCapture(int(input_name))
    else:
        capture = None

    cv.NamedWindow("result", 1)

    width = 320 #leave None for auto-detection
    height = 240 #leave None for auto-detection

    if width is None:
        width = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_WIDTH))
    else:
        cv.SetCaptureProperty(capture,cv.CV_CAP_PROP_FRAME_WIDTH,width)

    if height is None:
        height = int(cv.GetCaptureProperty(capture, cv.CV_CAP_PROP_FRAME_HEIGHT))
    else:
        cv.SetCaptureProperty(capture,cv.CV_CAP_PROP_FRAME_HEIGHT,height)

    if capture:
        frame_copy = None

        while True:

            frame = cv.QueryFrame(capture)
            if not frame:
                cv.WaitKey(0)
                break
            if not frame_copy:
                frame_copy = cv.CreateImage((frame.width,frame.height),
                                            cv.IPL_DEPTH_8U, frame.nChannels)

#                frame_copy = cv.CreateImage((frame.width,frame.height),
#                                            cv.IPL_DEPTH_8U, frame.nChannels)

            if frame.origin == cv.IPL_ORIGIN_TL:
                cv.Copy(frame, frame_copy)
            else:
                cv.Flip(frame, frame_copy, 0)

            detect_and_draw(frame_copy, cascade)

            if cv.WaitKey(10) >= 0:
                break
    else:
        image = cv.LoadImage(input_name, 1)
        detect_and_draw(image, cascade)
        cv.WaitKey(0)

    cv.DestroyWindow("result")

発声部分のプログラムは、簡単なのですぐわかると思うが、
顔を認識した回数をカウントして、何回かになると発声するようにしている。
最初は、「コーヒー飲みませんか?」 と、お誘いする。
2回目は、「ねぇ、ねぇ、コーヒー飲もうよ!」と、ちょっと、うざい感じで・・・。
3回目は、「コーヒー飲まないかなぁ~?」と、ちょっと、未練たらしく・・・。

3回発声すると、リセットされて、しばらく間をとる。3回の間に顔認識がはずれた時にも、リセットされて、また、一回目の発声からはじまる。
てな、具合。

別に、バリスタなくても良いんじゃないかって?
あっ、気付いちゃった?
まぁ、そうなんだけど、コミュニケーションとるのに、何か、それなりのネタがいるじゃないですか。
だから、バリスタで入れるコーヒーをネタにナンパをしかけるという作戦で・・・。

これまでの一連の試みで、人が近くに来たのを認識し、「コーヒーはいかが?!」と、声をかけて、音声認識で返事を受け取って、コーヒーを入れる。と、いう、サービスがほぼ自動化できるようになった。
これに、手足をつけてロボット化すると、給仕ロボットができちゃいそうですね。

ラズベリーパイからシリアル通信で音声合成ICを発声させてみた

これまで、音声合成IC(Aques talk pico)で発声させるのにプリセットのメッセージをラズパイのGPIOからコントロールしていたが、ラズパイから直接シリアル通信で発生させるようにセットしてみた。
f:id:manpukukoji:20160306114053j:plain
プリセットメッセージを使うと、メッセージ数にもよるが、GPIOのピンを3つ、4つ使うことになるけどシリアル通信で直接メッセージを送ると、送信だけで良いのでGPIO14のピン1本で事足りるので節約になるね。
シリアル通信のための設定は、いろいろなサイトで説明してくれているが、なんと、今回、僕の環境では、何もしなくてもそのまま通信できちゃったよ???

これまでのWebの情報だとシリアル通信するためには、以下の3つが必要だそうです。
1.シリアルコンソールのdisable化
2./boot/cmdline.txt の編集
3./etc/inittab の編集

僕の環境は、
Raspberry Pi2
NOOBS ver. 1.7.0. (Raspbian Kernel 4.1.17)
になっているが、上記の設定をしなくてもできちゃうみたい・・・?!

ちなみに、NOOBSのバージョンは、もう、1.8.0になっていた。
で、現在の/boot/cmdline.txt は、以下のようになっていた。
/etc/inittab は、そもそも、はじめから見つからなかった。

pi@raspberrypi:~$ cat /boot/cmdline.txt
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

ラズパイとATP3011との接続は、電源用の3.3VとGround、ラズパイのTxd Pin#08(GPIO14) の3本で接続
回路図は、こちら
f:id:manpukukoji:20160306113408j:plain
写真では、IR受信用のセンサとリモコンコード解読用のPICが付いているが、今回は、使わないので回路図からは、はずしてある。

簡単な発声プログラムは、Pythonで以下のようなプログラムを書いてみた。

pi@raspberrypi:~ $ cat wrserial.py
import serial
import time

def main():
    con=serial.Serial('/dev/ttyAMA0', 9600, timeout=10)
    print con.portstr
    time.sleep(1)
    str="? ohayo-\r\n"
    con.write(str)

if __name__ == '__main__':
    main()

これで、

 $sudo python wrserial.py

と、やると、”おはよー”と挨拶してくれるはず・・・。

OpenCVとTightvncサーバー

前回ラズパイのOSのバージョンアップをやって、無事USBカメラが映るようになったのだが、いまいち動きがおかしい。
で、ラズベリーパイのダウンロードサイトに行ってみてみると、NOOBSのバージョンも1.7.0になっている。
この際だから、これまでの設定をチャラにしてもう一度、最新のNOOBSでJessieのインストールのやり直しをしてみた。
microSDカードをフォーマットしてインストールを完了し、日本語フォントをインストールし、
tightvncserver, guvcview, libopencv-dev, python-opencv などをインストールしたところで、ディスクの使用量が3Gちょいとなった。
もちろん、tightVNC経由でguvcviewもちゃんとUSBカメラの画面が表示されている。
気を良くして、OpenCVPythonのプログラムを拾ってきて走らせて見ると、なんかエラーになる。

pi@raspberrypi:~$ python PythonCamera.py
Xlib:  extension "RANDR" missing on display ":1.0".

(camera:1600): GdkGLExt-WARNING **: Window system doesn't support OpenGL.

と、出る。
で、直接、HDMIのディスプレーにつないで同様にやってみると、問題なく映っている。
ちなみに、sudo権限でやってみると

pi@raspberrypi:~$ sudo python PythonCamera.py
Client is not authorized to connect to Server
(camera:1620): Gtk-WARNING **: cannot open display: :1.0

と、メッセージが変わるけどやっぱり映らん。
いろいろ調べていたら、あるサイトで、tightVNCをやめて、x11VNCというのを使うと映ったという記述があったので、即、まねすることにして。

$ sudo apt-get install x11vnc
$ sudo apt-get install xinetd

と、やって、x11VNCをゲット。
これで、もう一度実行すると、なんとか映るようになった。
f:id:manpukukoji:20160227120801j:plain
が、このままだと、デスクトップの画面サイズが変なので、気持ち悪い。
なかなか、修正できなかったんだけど、なんとか、以下のようにすれば良くなるということがわかった。

$ sudo nano /boot/config.txt

以下の部分を修正 (#をはずす)
    #framebuffer_width = 1280
    #framebuffer_height = 720

さて、これでなんとか使えそう。

Webカメラ BSW20KM15 をラズベリーパイで使ってみる

iBUFFALOのWebカメラ、BSW20KM15 というのをラズベリーパイにつないでguvcviewで見てみた。
すると、認識はしているようなのだけど、画面は真っ黒。
f:id:manpukukoji:20160224070937j:plain
一応、UVC対応ということなんだけど・・・。 ラズベリーパイでUSBカメラを使っているサイトをみてみても、だいたい、UVC対応のカメラなら使えるという記述が多かったんだけどなぁ~。
とりあえず、WindowsのPCにつないでみたら、当たり前のように映った。 
で、ほんじゃ、Ubuntu のPCでためしてみたら、おっ! これも問題なく映った。
で、別のラズパイにつないでみると、
ありゃりゃ?! 映ってる!

2つのラズパイ、何が違うかというと、
前にも書いたが、ひとつは、NOOBS v1.4.1 でインストール、もうひとつは、NOOBS v1.5.0
この二つがRaspbianで実際にどう違うのか確認してみた。
こちらを参考に、
raspbian(Raspberry Pi)のバージョン確認方法 | Check!Site

 $ lsb_release -a

と、やると、
NOOBS v1.4.1 は、

pi@raspberrypi ~ $ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 7.8 (wheezy)
Release:        7.8
Codename:       wheezy

NOOBS v1.5.0 は、

pi@raspberrypi:~ $ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 8.0 (jessie)
Release:        8.0
Codename:       jessie

つまり、古いほうは、Version 7.8 の Wheezy で、後のほうは、Version 8.0 のJessie だった。
ちなみに、Wheezy のほうは、lsb_release のコマンドもインストールしないと使えなかった。
おそらく、このカメラ、Wheezyでもちゃんと設定してやれば、使えるのだろうけど、僕のオツムでは、ちょいちょいと設定して使えるほどの知識はない。
いちおう、確認した範囲では、
以下のような感じ

pi@raspberrypi ~ $ lsusb
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 0411:01ee BUFFALO INC. (formerly MelCo., Inc.) WLI-UC-GNM2 Wireless LAN Adapter [Ralink RT3070]
Bus 001 Device 005: ID 05e3:0608 Genesys Logic, Inc. USB-2.0 4-Port HUB
Bus 001 Device 006: ID 0411:0261 BUFFALO INC. (formerly MelCo., Inc.)

pi@raspberrypi ~ $ ls /dev/video0
/dev/video0

pi@raspberrypi ~ $ ls /dev/v4l/by-id
usb-Novatek_BUFFALO_BSW20KM15_USB_Camera-video-index0

いろいろ調べてみるけど、よくわからん。 直接ディスプレーをつないで見てもだめだった。
う~ん、この際、今後のこともあるだろうから、WheezyをJessieにアップデートしちゃうか?
で、こちらを参考にやってみた。
Raspberry Piのアップデート(Wheezy → Jessie) | あっかぎのページ

なんか、現在の設定ファイル更新されているので、このまま使うか、新しい設定ファイルを上書きしてアップデートするかどうか、何回か聞いてきたけど、よくわからん。 とりあえず、今の問題をひきずるのもいやなので、すべて、新しくしてしまった。
で、リブートしたら、

pi@raspberrypi ~ $ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 8.0 (jessie)
Release:        8.0
Codename:       jessie

と、なって、Jessieにアップデートされた。
で、肝心のguvcview
これも、無事映るようになった。
f:id:manpukukoji:20160224171612j:plain

やれやれ・・・。

ネスカフェ バリスタを音声コントロール

ネスカフェ バリスタを使って、"ツイッター投稿"、"スマホでコントロール" に、続いて第3弾。
今度は、音声認識を使って、バリスタのスイッチをコントロールしてみた。

ネスカフェ バリスタを音声コントロール
ハードウェアの方は、USBマイクをつける以外は、"スマホでコントロール"の時と同じで、今回は、ソフトウェアの設定が主になる。
音声認識は、Juliusというシステムを使わせていただいた。
Juliusについてもたくさんの参考サイトが説明してくれているので、非常に助かる!

以下、その詳細。
では、まず、USBマイクを接続して、認識されていることと、優先順位が最初に来ているかを確認

$ sudo lsusb
Bus 001 Device 004: ID 0411:01ee BUFFALO INC. (formerly MelCo., Inc.) WLI-UC-GNM2 Wireless LAN Adapter [Ralink RT3070]
Bus 001 Device 005: ID 0d8c:013c C-Media Electronics, Inc. CM108 Audio Controller
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

$ sudo cat /proc/asound/modules
 0 snd_usb_audio
 1 snd_bcm2835

私の場合、USBには、BUFFALOのWiFIドングルのWLI-UC-GNM2 と、USBマイクのBSHSMO5BKというのが刺さっている。
上記リストのうちC-Media というのがマイクで、ちゃんと認識されていた。
優先順位のほうは、0のほうが優先順位が高いそうなのだが、そのままだと、SND_BCM2835のほうが優先になっていた。
で、順位を変更するのだけれど、ラズパイのOSのバージョンによって少し、動きが違っていた。
NOOBS v1.4.1 をインストールしたときは、"/etc/modprobe.d/alsa-base.conf" を編集すれば上記のようなったのだけど、NOOBS v1.5.0 をインストールしたときは、そもそも、この"alsa-base.conf"というファイル自体が見つからなかった。
で、いろいろググって見ると、こちらのサイトで助けられた。
簡単にできる!音声認識と音声合成を使ってRaspberrypiと会話 - Qiita

v1.4.1のときは、だいたい、以下のサイトに習って設定すればうまくいった。
Raspberry Piで音声認識 - Qiita

上記のサイトを参考にさせてもらって、Juliusのインストールとテストまでは、問題なく進んだ。
インストールできたら、自分に必要なワードの辞書を作成して辞書ファイルに変換。
以下のサイトも大変参考になる。
ラズパイで音声認識をしてみる | うしこlog
私の場合は、以下のように辞書ファイル作成

~$ nano word.yomi

ブラックにして  ぶらっくにして
ラテにして      らてにして
カプチーノにして        かぷちーのにして
エスプレッソにして      えすぷれっそにして
マグにして      まぐにして
コーヒーいれて  こーひーいれて
バリスタくん    ばりすたくん
おしまい        おしまい

$ cd ~/julius-4.3.1/gramtools/yomi2voca
$ iconv -f utf8 -t eucjp ~/word.yomi | ./yomi2voca.pl > ~/julius-kits/dictation-kit-v4.3.1-linux/word.dic

辞書ファイルができたら、上記サイトを参考に設定ファイルを作成

$ nano ~/julius-kits/dictation-kit-v4.3.1-linux/word.jconf

うまく認識されていることを確認。

認識できることが確認されたら、認識した文字でバリスタのスイッチをコントロールするプログラムをPythonで作成。
その前に、先ほどの”Word.jconf”のファイルの最後に "-module" という行を追加して、Julius をモジュールモードで実行するように設定
Pythonのプログラムは、以下のサイトを参考にさせていただいた。
Raspberry Pi

こちらのサイトの2015/08/30の記事のPythonプログラムをベースに下記のように、自分用にアレンジした。

~$ nano barista01.py

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

'''
  ファイル名 : barista01.py
  起動方法
  (1) Julius をモジュールモードで起動
      julius -C julius-kits/dictation-kit-v4.3.1-linux/word.jconf 

  Julius(フリーの高性能音声認識ソフトウェア)

  ・TCP/IP で認識結果を受信し認識結果を表す<RECOGOUT>...</RECOGOUT> 部分を抽出する

  参考 URL
    http://moosoft.jp/index.php?option=com_content&view=article&id=99&Itemid=134
    http://julius.osdn.jp/
    http://kuhjaeger.co.jp/laboratory/raspberrypi/julius/
'''

import threading
import RPi.GPIO as GPIO
import socket
import time
import sys

# モジュールトップレベル変数設定 Start
SOCK      = None      # TCP/IP ソケット
ENCODING  = 'utf-8'  # codec

# GPIO ピン番号設定
# GPIO.setmode(GPIO.BOARD) P1 ヘッダ上のピン番号を用いる
RELAY_1   = 24        # コーヒー   GPIO8 = 24 ピン
RELAY_2   = 11        # ブラック   GPIO17 = 11 ピン
RELAY_3   = 12        # マグ     GPIO18 = 12 ピン
RELAY_4   = 13        # エスプレッソ  GPIO27 = 13 ピン
RELAY_5   = 15        # カプチーノ    GPIO22 = 15 ピン
RELAY_6   = 16        # ラテ   2   GPIO23 = 16 ピン
P0 = 18               # Aques bit0
P1 = 22               # Aques bit1
P2 = 19               # Aques bit2

HOST_NAME = 'localhost'
PORT_NUM  = 10500
BUF_SIZE  = 4096
DELIM_STR = '.\n'
START_STR = '<RECOGOUT>'
END_STR   = '</RECOGOUT>'
FIND_STR0 = ['コーヒー'  , 'いれて']
FIND_STR1 = ['ブラック', 'にして']
FIND_STR2 = ['マグ', 'にして']
FIND_STR3 = ['エスプレッソ', 'にして']
FIND_STR4 = ['カプチーノ', 'にして']
FIND_STR5 = ['ラテ', 'にして']
FIND_STR6 = ['バリスタ','くん']
FIND_STR7 = ['おし', 'まい']

# モジュールトップレベル変数設定 End

# GPIO 初期化
def gpio_init():
    try:
        GPIO.setwarnings(False)                 # Warning 表示停止
        #GPIO.setmode(GPIO.BCM)                 # GPIO ピン番号を用いる
        GPIO.setmode(GPIO.BOARD)                # P1 ヘッダ上のピン番号を用いる
        GPIO.setup(RELAY_1,GPIO.OUT)
        GPIO.setup(RELAY_2,GPIO.OUT)
        GPIO.setup(RELAY_3,GPIO.OUT)
        GPIO.setup(RELAY_4,GPIO.OUT)
        GPIO.setup(RELAY_5,GPIO.OUT)
        GPIO.setup(RELAY_6,GPIO.OUT)
        GPIO.setup(P0,GPIO.OUT)
        GPIO.setup(P1,GPIO.OUT)
        GPIO.setup(P2,GPIO.OUT)
        GPIO.setup(RELAY_1,                     # SW 1
                   GPIO.OUT,
                   pull_up_down=GPIO.PUD_DOWN)
        GPIO.setup(RELAY_2,                     # SW 2
                   GPIO.OUT,
                   pull_up_down=GPIO.PUD_DOWN)
        GPIO.setup(RELAY_3,                     # SW 3
                   GPIO.OUT,
                   pull_up_down=GPIO.PUD_DOWN)
        GPIO.setup(RELAY_4,                     # SW 4
                   GPIO.OUT,
                   pull_up_down=GPIO.PUD_DOWN)
        GPIO.setup(RELAY_5,                     # SW 5
                   GPIO.OUT,
                   pull_up_down=GPIO.PUD_DOWN)
        GPIO.setup(RELAY_6,                     # SW 6
                   GPIO.OUT,
                   pull_up_down=GPIO.PUD_DOWN)
        GPIO.setup(P0,                     # Bit0
                   GPIO.OUT,
                   pull_up_down=GPIO.PUD_UP)
        GPIO.setup(P1,                     # Bit1
                   GPIO.OUT,
                   pull_up_down=GPIO.PUD_UP)
        GPIO.setup(P2,                     # Bit2
                   GPIO.OUT,
                   pull_up_down=GPIO.PUD_UP)
    except Exception as e:
        print('gpio_init:{0}'.format(e))

# 受信解析 SW ON 制御クラス
class tcp_recv(threading.Thread):

    # コンストラクタ
    def __init__(self):
        threading.Thread.__init__(self)
        self.daemon = True               # デーモンスレッド

    # 受信解析 SW ON 制御
    def run(self):
        global SOCK

        try:
            SOCK = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            SOCK.connect((HOST_NAME, PORT_NUM))
            rv_str = ''
            while SOCK is not None:
                rv = SOCK.recv(BUF_SIZE).decode(ENCODING)
                rv_str += rv
                if DELIM_STR in rv:                               # '.\n' : メッセージの区切り
                    s0 = rv_str.find(START_STR)                   # '<RECOGOUT>'
                    s1 = rv_str.find(END_STR)                     # '</RECOGOUT>'
                    if (s0 > -1) and (s1 > -1):
                        rec = rv_str[s0 : s1 + len(END_STR) + 1]  # 文字列抽出
                        print(rec)

                        if FIND_STR0[0] in rec:                   # Start SW
                            if FIND_STR0[1] in rec:
                                isON = "1.000" in rec
                            GPIO.output(P0, False)            # コーヒー入れて
                            GPIO.output(P1, False)            # Aques
                            GPIO.output(P2, False)
                            time.sleep(1)
                            GPIO.output(P0, True)
                            GPIO.output(P1, True)
                            GPIO.output(P2, True)
                            time.sleep(2)
                            GPIO.output(RELAY_1, isON)        #スイッチON
                            time.sleep(1)
                            GPIO.output(RELAY_1,False)

                        if FIND_STR1[0] in rec:               #ブラック
                            isON = FIND_STR1[1] in rec
                            GPIO.output(P1, False)            # Aques
                            GPIO.output(P2, False)
                            time.sleep(1)
                            GPIO.output(P1, True)
                            GPIO.output(P2, True)
                            GPIO.output(RELAY_2, isON)        # ブラックSet
                            time.sleep(1)
                            GPIO.output(RELAY_2,False)

                        if FIND_STR2[0] in rec:               # マグ
                            isON = FIND_STR2[1] in rec
                            GPIO.output(RELAY_3, isON)        # マグSet
                            GPIO.output(P0, False)            # Aques
                            GPIO.output(P2, False)
                            time.sleep(1)
                            GPIO.output(P0, True)            
                            GPIO.output(P2, True)            
                            GPIO.output(RELAY_3,False)

                        if FIND_STR3[0] in rec:               # エスプレッソ
                            isON = FIND_STR3[1] in rec
                            GPIO.output(P2, False)            # Aques
                            GPIO.output(RELAY_4, isON)        # エスプレッソSet
                            time.sleep(3)
                            GPIO.output(P2, True)
                            GPIO.output(RELAY_4,False)

                        if FIND_STR4[0] in rec:               # カプチーノ
                            isON = FIND_STR4[1] in rec
                            GPIO.output(RELAY_5, isON)        # カプチーノSet
                            GPIO.output(P0, False)            # Aques
                            GPIO.output(P1, False)            # Aques
                            time.sleep(1)
                            GPIO.output(RELAY_5,False)
                            GPIO.output(P0, True)            # Aques
                            GPIO.output(P1, True)            # Aques

                        if FIND_STR5[0] in rec:               # ラテ
                            isON = FIND_STR5[1] in rec
                            GPIO.output(RELAY_6, isON)        # ラテSet
                            GPIO.output(P1, False)            # Aquos
                            time.sleep(1)
                            GPIO.output(RELAY_6,False)
                            GPIO.output(P1, True)            # Aques

                        if FIND_STR6[0] in rec:               # バリスタくん
                            isON = FIND_STR6[1] in rec
                            GPIO.output(P0, False)            # Aques
                            time.sleep(1)
                            GPIO.output(P0,True)

                        if FIND_STR7[0] in rec:               # おしまい
                           # isON = FIND_STR7[1] in rec
                           if FIND_STR7[1] in rec:
                              if SOCK is not None:
                                   SOCK.shutdown(socket.SHUT_RDWR)
                                   SOCK.close()
                              GPIO.output(RELAY_1, GPIO.LOW)       # SW OFF
                              GPIO.output(RELAY_2, GPIO.LOW)       # SW OFF
                              GPIO.output(RELAY_3, GPIO.LOW)       # SW OFF
                              GPIO.output(RELAY_4, GPIO.LOW)       # SW OFF
                              GPIO.output(RELAY_5, GPIO.LOW)       # SW OFF
                              GPIO.output(RELAY_6, GPIO.LOW)       # SW OFF
                              GPIO.output(P0, GPIO.HIGH)       # Bit OFF
                              GPIO.output(P1, GPIO.HIGH)       # Bit OFF
                              GPIO.output(P2, GPIO.HIGH)       # Bit OFF
                              GPIO.cleanup()
                              sys.exit()                            # exit

                    rv_str = ''
        except Exception as e:
            if SOCK is not None:
                SOCK.shutdown(socket.SHUT_RDWR)
                SOCK.close()
                SOCK = None
            print('run:{0}'.format(e))

# メインループ
def main():
    try:
        gpio_init()                          # GPIO 初期化
        tcp_recv().start()                   # 受信解析クラス
        while True: time.sleep(1000)
    except KeyboardInterrupt:
        if SOCK is not None:
            SOCK.shutdown(socket.SHUT_RDWR)
            SOCK.close()
        GPIO.output(RELAY_1, GPIO.LOW)       # SW OFF
        GPIO.output(RELAY_2, GPIO.LOW)       # SW OFF
        GPIO.output(RELAY_3, GPIO.LOW)       # SW OFF
        GPIO.output(RELAY_4, GPIO.LOW)       # SW OFF
        GPIO.output(RELAY_5, GPIO.LOW)       # SW OFF
        GPIO.output(RELAY_6, GPIO.LOW)       # SW OFF
        GPIO.output(P0, GPIO.HIGH)       # Bit OFF
        GPIO.output(P1, GPIO.HIGH)       # Bit OFF
        GPIO.output(P2, GPIO.HIGH)       # Bit OFF
        GPIO.cleanup()
        raise
    except Exception as e:
        print('main:{0}'.format(e))

# ============================================== #
if __name__ == '__main__':
    main()

続いて、音声認識コントロールを開始するためのスクリプトを作成

$ nano barista.sh

#!/bin/sh
amixer sset Mic 10
julius -C /home/pi/julius-kits/dictation-kit-v4.3.1-linux/word.jconf &
sleep 3
sudo python3 barista01.py &

exit 0

これで、実行するときは、

$ sudo bash barista.sh

と、やれば、音声認識コントロールが開始される。

誤認識もあるけど、期待した以上の精度でスイッチがコントロールできる。 ただ、音声合成で発声しているのだけど、この音をマイクがひろってしまい、ループしてしまうことがあるので、センテンスをひろったら、しばらくマイクのレベルをゼロにするとか何かの対策が必要かも・・・。
もう少し、改良のポイントは、あるかもね・・・。