takuocean’s diary

備忘録がメインなので、説明が足りないことも多い。もう少し詳しくという人はコメントをお願いします。

pythonでC言語のprintfのようなことをするには

やりたいこと

C言語で演算結果や文字列をログを吐きたいとき、

int num = 100;
printf("num = %d", num);

のような記述をすると思います。

pythonでの記述

pythonでも同様な記述で

num = 100
print("num= %d" % num)

ログを出力できます。 また、2つ以上の数字や文字を挿入したい場合は、

num_str = "num"
num = 100
print("%s = %d" % (num_str, num))

のように書きます。

Bluetoothモジュール(HC-6)の名前の変え方 with Arduino

やりたいこと

HC-6というBluetoothモジュールの名前を変えたい。
以下の順で名前変更指示をする。
PC → Arduino Nano → Bluetoothモジュール
そのために
PC、Arduino間はハードウェアシリアル
ArduinoBluetooth間はソフトウェアシリアル
で接続する。

参考サイト

www.google.com

前提

Arduino IDEがインストールされていること。
www.arduino.cc

材料

これは純正のArduinoではなく、中華製なのでドライバのインストールが必要。
このページを参考に。
qiita.com

TODO

  1. まずは配線
  2. Arduinoプログラムの作成
  3. ビルド&書き込み
  4. 名前変更

1. まずは配線

f:id:takuocean:20190403235905j:plain

+ ArduinoとPCがつながっていること

2. Arduinoプログラムの作成

#include <stdio.h>
#include <stdlib.h>
#include <SoftwareSerial.h>

#define PIN_BLUETOOTH_TX  10  // Bluetooth TX
#define PIN_BLUETOOTH_RX  11  // Bluetooth RX

/* Bluetoothモジュールと通信をするためのソフトウェアシリアル */
SoftwareSerial mySerial(PIN_BLUETOOTH_RX, PIN_BLUETOOTH_TX); // TX, RX

void setup() {
  Serial.begin(9600); //ハードウェアシリアルの初期化
  mySerial.begin(9600); // ソフトウェアシリアルの初期化
  }

void loop() {
  while( Serial.available() ) {
    char c = Serial.read();
    mySerial.print(c);
    delay(5);
  }

  while( mySerial.available() ) {
    char c = mySerial.read();
    Serial.print(c);
    delay(5);
  }
}

3. ビルド&書き込み

「ツール」→「シリアルポート」をクリックし、接続したArduinoのポートを選択する。
f:id:takuocean:20190405234853p:plain

マイコンボードに書き込む」をクリック。
これによりビルドされ、書き込みまで行われる。
f:id:takuocean:20190405233532p:plain

4. 名前変更

Arduino IDEの右上の虫眼鏡ボタンをクリックしてコンソールを表示。
f:id:takuocean:20190405235359p:plain

Arduino IDEのコンソールで以下を入力。

AT+NAME:好きな名前

OKと表示されれば入力した名前に変更されているので、実際にBluetoothを検索してみて指定した名前が見つかれば成功。

RaspberryPiとGoogle AssistantのIFTTTを使った連携(2/2)

これの続き takuocean.hatenablog.com

ToDo

以下の順で指示が経由されるようにする。
GoogleAssistant → IFTTT → beebotte → RaspberryPi
今回は
「GoogleAssistant → IFTTT → beebotte」
を構築していく。

1. 新しいAppletの作成

右上にある「New Applet」をクリック。 f:id:takuocean:20190324223144j:plain

2 「Google Assistant → IFTTT」の設定

IFTTTでは、トリガーとそれに応じた処理を設定できる。
例えば、「Googleカレンダの予定3日前」になったら「Lineで通知」する、みたいな。 ここではトリガーとなる部分を設定していく。

2.1 「This」をクリック。

f:id:takuocean:20190324223226j:plain

2.2 サービスを選択

虫眼鏡の検索欄に「google」と入力し、 検索された「Google Assistant」をクリック。 f:id:takuocean:20190324223231j:plain

2.3 トリガーとなる形式を選択

いくつか形式があるが、今回は「Say a simple phrase」をクリック。 f:id:takuocean:20190324223234j:plain

2.4 トリガーとなる詳細を記述

ここではトリガーとなるGoogleAssistantへの命令を記述。 f:id:takuocean:20190325220202j:plain
What do you want to say?: morning music
 トリガーとなる言葉
What do you want the Assistant to say in response?: OK, play morning music
 GoogleAssistantの応答
Language:English
 言語
スマホのGoogleAssistantを英語設定にしているので。

記述できれば「Create Trigger」をクリック。

3 「IFTTT → beebotte」の設定

3.1 「That」を選択

f:id:takuocean:20190324223253j:plain

3.2 サービスを選択

GoogleAssistantの命令に対応するサービスを指定していく。 虫眼鏡の検索欄に「web」と入力し、 検索された「Webhooks」をクリック。 f:id:takuocean:20190324223258j:plain

3.3 実行形式を選択

「Make a web request」をクリック。 f:id:takuocean:20190324223302j:plain

3.4 実行することの詳細を記述

ここではGoogleAssistantで命令されたことに対して実行することの詳細を記述。 f:id:takuocean:20190325222221j:plain
URL: http://api.beebotte.com/v1/data/publish/MySmartHome/PlayMusic?token=YourToken
 YourTokenはbeebotteで作成したプロジェクトのトーク
Method: POST
 HTTPのPOST
Content Type (optional): application/json
 データの形式
Body (optional): { "data": [{"room":"living","device": "music"}]}
 実際に送るデータ

記述できれば「Create Action」をクリック。

3.5 IFTTT上に記載される説明を確認

説明文がよければ、「Finish」をクリック。
ちなみに、動作には特に影響なし。
f:id:takuocean:20190325222225j:plain

3.6 作成完了画面

f:id:takuocean:20190324223325j:plain

4 動作確認

RaspberryPiにスピーカを装着し、 実際にスマホ、またはGoogleのスマートスピーカでGoogleAssistantを立ち上げて(OK, Googleと言って)、「morning music」と命令。
音楽が流れば完了。

RaspberryPiとGoogle AssistantのIFTTTを使った連携(1/2)

やりたいこと

RaspberryPiとGoogle AssistantをIFTTTを使って連携させる。
「音楽かけて」といったらRaspberryPiから音楽がながれるような感じ。

参考URL

qiita.com

ToDo

以下の順で指示が経由されるようにする。 GoogleAssistant → IFTTT → beebotte → RaspberryPi
今回は
「beebotte → RaspberryPi 」
を構築していく。

前提

・RaspberryPiの「/home/pi」に再生したい音楽を置く(今回はsample.mp3)
・↑を再生するアプリが入っている(今回はmpg321)

1. beebotteのセットアップ

1.1. 新しいChannelの作成

左のメニューバー上部にあるChannelsをクリックし、表示された画面で右上部にある「Create New」をクリックする。 f:id:takuocean:20190224232102j:plain

1.2. Channel名、Resource名を登録

f:id:takuocean:20190224233414j:plain ここでは Channel名:MySmartHome
Resource名:PlayMusic

入力ができたら、「Create Now」をクリックする。

1.3. トークン取得

「Create Now」をした直後にホーム画面でChannel名が表示される。
Channel名「MySmartHome」をクリックする。 f:id:takuocean:20190224234223j:plain

アクセストークンが取得することができる。 f:id:takuocean:20190224234833j:plain

1.4. beebotteの動作確認

左のメニューバーで「Account Settings」を選択し、表示された画面で「Access Management」タブをクリックする。
Secret keyをコピーする。 f:id:takuocean:20190303211337j:plain

左のメニューバーで「Console」を選択し、先ほどコピーしたSecret KeyをこのページのSercret Key入力エリアに入力する。 されに SubscribeのChannelとResourceに、先ほど登録した"MySmartHome"と"PlayMusic"を入力し、Subscribeボタンを押下する。 f:id:takuocean:20190303211343j:plain

以下のコマンドをPC上のコンソールで入力する。

curl -i -H "Content-Type: application/json" -X POST -d '{"data":"Hello World"}' http://api.beebotte.com/v1/data/publish/MySmartHome/PlayMusic?token=[Channelのトークン]

Messageエリアに指定したペイロードが表示される。

2 RaspberryPiの準備

2.1. RaspberryPiの受信プログラムの作成

指令を受けると音楽を再生するプログラム(sample.py)は以下の通り。

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

import paho.mqtt.client as mqtt
import json
import subprocess
import os

_TOKEN = 'Your Token' #IFTTTに設定したものと同じChannel Tokenを設定
HOSTNAME = 'api.beebotte.com'
PORT = 1883 #SSLの場合は8883
TOPIC = 'smart_home/music' #トピック名/リソース名 の形で設定

# 接続中の処理を記載→subscribeする
def on_connect(client, userdata, flags, respons_code):
    print('status {0}'.format(respons_code))
    client.subscribe(TOPIC)

# メッセージ受信時の処理を記載
def on_message(client, userdata, msg):
    print(msg.topic + ' ' + str(msg.payload))
    data = json.loads(msg.payload.decode("utf-8"))["data"][0]
    # Google Assistantの側でTextFiledの前後に半角スペースが入ることがあるのでstripして削除
    #data = {key:value.strip() for key, value in data.items()}
    if "room" in data.keys():
        # 「証明を」と言ってしまった際に「を」が入ってTextFieldに入ってくることがあるので削除
        #if data["device"].endswith("を"):
            #data["device"] = data["device"][:-1]
        # 日本語の表記ゆれに併せて、IFTTTのTextFieldをlightに修正
        if data["device"] != "music":
            print("unkown device")
            return
        subprocess.call(['mpg321', '/home/pi/sample.mp3'])

if __name__ == '__main__':
    client = mqtt.Client()
    #トークンを使って認証
    client.username_pw_set("token:%s"%_TOKEN)

    client.on_connect = on_connect
    client.on_message = on_message

    client.connect(HOSTNAME, port=PORT, keepalive=60)

    # 待ち受け状態にする
    client.loop_forever()

2.2. RaspberryPiの動作確認

RaspberryPiで指令がきたら音楽を再生するプログラムを実行する。

python sample.py

次に、以下のコマンドをRaspberryPiのコンソールで実行して、音楽が再生か確認。

curl -i -H "Content-Type: application/json" -X POST -d '{ "data": [{"room":"living","device": "music"}]}' http://api.beebotte.com/v1/data/publish/MySmartHome/PlayMusic?token=[Channelのトークン]

実行し音楽が流れ始めたらOK!

続き http://takuocean.hatenablog.com/entry/2019/03/25/225222

RaspbianでIPアドレスを固定する方法

1. /etc/dhcpcd.confを編集。

...

#固定したいインターフェース
interface eth0
#固定したいIPアドレス
static ip_address=192.168.xxx.xxx/24
#ルータのIPアドレス
static routers=192.168.xxx.xxx
#ここもルータのIPアドレス
static domain_name_servers=192.168.xxx.xxx

2. 再起動

sudo reboot

これで反映されます。

raspberry pi3とシリアル通信

raspberry pi3(OS: raspbian)のシリアルポートの指定で苦戦したのでメモ。

以前、CentOS同士でシリアル通信する時にscreenコマンドで通信したので 今回はも同じ引数でraspberry pi3も通信できると思ってたら違ってた。

利用したコマンド; screen

以前(CentOS

sudo screen /dev/ttyS0 115200

今回(Raspbian)

sudo screen /dev/serial0 115200