2015年12月3日木曜日

RaspberryPi で Huawei の HWD12 を使う方法

概要

過去に Yosemite で使えるようにした HWD12 ですが、今度は RaspberryPi (RPi) で使ってみました

環境

  • Raspberry Pi Type B Single Board Computer 512MB
  • Raspbian 8.0 (Jessie)
  • Kernel Version 4.1.7+

設定方法

とりあえず何も考えずに以下のコマンドを実行すれば使えるようになると思います

  • sudo apt-get install usb-modeswitch
  • sudo cp /etc/usb_modeswitch.conf{,.back}
  • sudo vim /etc/usb_modeswitch.conf
DefaultVendor=0x12d1
DefaultProduct=0x1f03

TargetVendor=0x12d1
TargetProduct=0x14db

MessageContent="55534243123456780000000000000a11062000000000000100000000000000"
  • sudo modprobe usbserial vendor=0x12d1 product=0x14db
  • sudo usb_modeswitch -c /etc/usb_modeswitch.conf

usb_modeswitch.conf は一番下に内容を追記すれば OK です

何をしているのか

usb_modeswitch というツールを使って、USBストレージとして認識されてしまった HWD12 を USBモデムとして認識させ直しています
最後の sudo usb_modeswitch -c /etc/usb_modeswitch.conf のあとで HWD12 のランプが紫になりインターネットに接続できることが確認できると思います

本来は USB を接続した際に VendorID が 0x12d1, ProductID が 0x14db として認識されなければいけないのに、それぞれ 0x12d1, 0x1f03 として認識されているせいで Wifi モデムとして動作していません

設定ファイル ( /etc/usb_modeswitch.conf ) に正しい ID 情報を記載して、usb_modeswitch コマンドを実行することで正しい ID として認識させます

本来正しく認識させなければいけない ID や MessageContentここ に記載されているものを使いました

Tips

  • IPv4 の IP アドレスを取得できない場合

以下のコマンドを試してみたください

sudo dhclient -4 -v usb0

RPi 自体で IPv4 を切る方法もありそうなのでそれを設定して再起動でもいいかもしれません
というのも今回の HWD12 を使えるようにする設定を行った後に RPi 自体を再起動すると HWD12 を挿してもうまくインターネットに接続できない現象が発生しました
自分の場合ですが、調べてみると USB はモデムとして認識されているものの IPv4 がうまく取得できていなかったようで、RPi を再起動するたびに dhclient のコマンドを実行していました
コマンドを 1 個実行するだけなのでそこまで大変ではないですが、そもそも IPv4 を切っておけば、そのコマンドすら実行する必要がなくなるのかなと思った感じです

  • そもそも他のネットワークがない人はどうすればいいか

今回のコマンドは一発目に apt-get コマンドがあります
つまりネットワークに繋がっていなければなりません
自分はスマホのテザリングを使って RPi をネットに繋いて実行しましたが、そもそもその環境すらない場合は詰んじゃうかもしれません

参考サイト

2015年12月2日水曜日

TinkerMode 試してみた

概要

Tinker Mode は IoT 用のクラウドサービスで Tinker Mode に接続しているデバイスをスマートフォンや PC から制御できるようにすることができます
シミュレータを使って制御することもできますが、せっかくなので RaspberryPi を使って Tinker Mode に接続しスマホから L チカしてみました

環境

  • TinkerMode 2015/12/01 時点
  • node 4.2.1
  • mode-device ( npm module ) 1.0.3
  • iPhone 6 ( iOS 9.1 )
  • Raspberry Pi Type B Single Board Computer 512MB
  • Raspbian 8.0 (Jessie)
  • Kernel Version 4.1.7+

サインアップ

まずはサインアップします
名前/パスワードとメールアドレスを入力して確認のメールが来たら記載の URL をクリックすれば登録完了です
signup_mode.png

登録できたら早速コントロールパネルにログインしてみましょう
https://console.tinkermode.com/console/

サンプルプロジェクトの作成

サンプルプロジェクトを作成します
ログインするとすでに「Sample Project」というプロジェクトが 1 つ存在していると思います
今回はこれを使っていきます

制御用のサンプルアプリ Lumos をダウンロードする

このアプリを使って最終的に RPi の L チカを制御します

App Store から「Lumos」というアプリをダウンロードしてください
検索すると Lumos という同じ名前の他のアプリがいろいろと出てきてしまうので MODE INC が公開者になっているアプリをダンロードしてください

ダウンロードしたら早速アプリを開きましょう
アプリを開くといきなりプロジェクト ID を入力させられます
先ほど確認したサンプルプロジェクトのプロジェクト ID を入力すれば OK です
プロジェクト ID はコントロールパネルの

Dashboard -> OVERVIEW -> Project ID

で確認することができます
プロジェクトを開いているのであれば URL にも番号があるのでそれでも OK です

次にプロジェクト内に存在するユーザを登録します ( これはサインアップしたユーザとは違うユーザになります )
登録には電話番号が必要になります
Name と Phone number を入力したら Next で登録処理に進みます
電話番号は国別コードから入力する必要があるので、日本で試している場合は「+8109xxxxyyyy」みたいな感じで入力してください
入力した電話番号に SMS メッセージが届きます
そこに記載されている PIN コードを入力すれば登録完了です

Tinker Mode ではユーザの認証に電話番号による SMS 認証を採用しています
電話番号に記載の PIN コードを入力することで認証することができます

ここの流れは Getting Started の Install the Sample App を見ると画像もあるので、やり方のイメージがつかみやすいと思います

Home を作成する

このまま Lums のアプリ上で作成します
Home はデバイスやユーザを管理するものです

アプリにログインすると初めは Home の一覧になるので何もないと思います
右上に「+」ボタンがあるのでそこから Home を追加しましょう
名前とタイムゾーンを決定すれば OK です

制御するデバイスを Home に登録する

コントロールパネルでデバイスシミュレータを開きます
Sample Project にはすでにデバイス ( デバイスクラス ) も登録されているのでそれを使います

Devices -> smart_light -> DEVICE LIST -> 適当なデバイスを選択 ->
Device Simulator -> LAUNCH SIMULATOR

でシミュレータを起動しましょう
起動すると別ウィンドウで開きます
シミュレータの左ペインに「CLAIM MODE」というボタンがあるのでクリックします
claim_code.png

すると 300 秒間のカウントに入ります
この間に再度 Lumos のアプリ上で Home にデバイスの登録を行います

作成しておいた Home を選択して Devices を開きます
Home 追加時同様に右上に「+」ボタンがあるのでタップしてデバイスを追加します
デバイスを追加するには「Claim Code」が必要になります
これはデフォルトだとランダムに発行される文字列になります ( スクリーンショットの Claim Code は自分で変更したものになります )
Claim Code の確認は開いているシミュレータ上でもできます
コントロールパネルのデバイス一覧からも行えます
Claim Code を 300 秒間の間に入力してアプリ上で Add しましょう
エラーが発生しなければ登録成功です

一覧に出てこない場合は一旦 back して再度 Home を選択してみてください
登録したデバイスが表示されるはずです
ここまでできれば一旦アプリ上での作業は完了です

RPi 側の準備

ここからは RPi 側の準備になります
OS のインストールやネットワークの設定は事前に済ませておいてください

node をインストールする

最新の node が必要になります

Tinkder Mode を操作する Javascript SDK をインストールします

エラーなくインストールされれば OK です
執筆時点での SDK のバージョンは 1.0.3 でした
https://www.npmjs.com/package/mode-device

ソースコードを修正する

取得した app.js を修正します
修正するといっても API 認証のための情報を書き換えるだけです

Tinker Mode の API をコールするためには Device ごとに割り振られている DeviceID と API Key が必要になります
プロジェクトごとではなくデバイスごとなので別のデバイスを制御したい場合は、別の DeviceID と API Key に書き換えてください

DeviceID と API Key の取得はコントールパネルから行えます

Devices -> smart_light -> DEVICE LIST -> 適当なデバイスを選択

get_id_and_key.png

取得できたらソースを修正していきます
修正する箇所は app.js の 10, 11 行目です

var DEVICE_ID = 1;
var API_KEY = 'v1.cccc.bbbbbbbbbbbbbbbbbb.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';

取得した Device ID と API Key に書き換えたら保存して終了しましょう

接続できるか試してみる

この状態で一旦 RPi から Tinker Mode に接続できるか試してみるといいと思います

  • node app.js

でスクリプトを起動しましょう

Connecting to wss://api.tinkermode.com:443/devices/1/command
Event is triggered
WebSocket Client Connected

となれば成功です
ほっておくと ping - pong のやり取りもはじまります

Lチカ用の配線をする

ブレッドボードを使って L チカ用の配線をしましょう
ここでは配線に関する詳細は省略します
Lチカ配線は過去にも紹介しているので参考にしてください
あとはググってもいろいろと情報がでてくると思います

一点だけポイントですが、GPIO は論理番号 4 番ピンを使ってください
app.js 内で 4 番 PIN を制御しているためです
もちろんスクリプトを修正して別の番号の PIN を制御するようにすれば別の PIN を使っても OK です

アプリシミュレータから LED を点灯させてみる

これで準備が整いました
では、アプリから LED を点灯させてみましょう
まずはアプリシミュレータを使って点灯させます
アプリも Sample Project 作成時に 1 つ存在するのでそれを使えば OK です

Apps -> controller_app -> App Simulator -> LAUNCH SIMULATOR

で別ウィンドウでシミュレータが起動します
スマホから Home を作成したと思うのですでにシミュレータ側にも Home があると思います
ないスマホで作成した方法と同様でいいので Home を作成してください

Home を選択すると右ペインに「Outgoing: Commands」というのが表示されます
これを使ってデバイス ( RPi ) に信号を送り LED をチカっとさせます
送信する信号の情報は以下の通りです
send_signal.png

Target のデバイス情報は Home に登録したデバイスがプルダウンで選択できるので、登録したデバイスを選択してください
プルダウンにデバイスが表示されない場合は、Home へのデバイス登録が失敗している可能性があります
再度 Claim Mode にして Claim Code を使って Home にデバイスを登録してください

情報が入力できたら「SEND COMMAND」で OK です
で、成功すると LED がチカっ光るはずです
なんかリモコンみたいな感じで初めは感動します
消灯する場合は送信する信号の Parameters を on : 0 にすれば OK です

Lumos アプリから LED を点灯させてみる

アプリの場合はトグルを ON/OFF するだけで LED が点灯したり消灯したりします
アプリにログインして Home を選択してデバイスの一覧を表示するとデバイスの右にトグルボタンが表示されていると思います
そのトグルを ON/OFF してみてください
LED がチカチカするはず、、、がしない

ちょっとだけソースを修正する必要があります
21, 22 行目で Tinker Mode から受け取る信号を if 文で切り分けている部分があります
そこを書き換えましょう
以下のようにすれば OK です

device.commandCallback = function(msg, flags) {
  if (msg['action'] == 'change') {
    var v = msg['parameters']['switch'] ? 1 : 0;
    led.writeSync(v);
  }
}

どうやら Lumos アプリから送信される信号は以下の JSON 情報のようでシミュレータから送られる情報とは異なるようです

{“action”:”change”, “parameters”:{“switch”:0}}

書き換えて再度 node app.js で起動して Lumos アプリからトグルを ON/OFF すればアプリから L チカを制御できるようになります

最後に

確かにおもしろいサービスだと思いました
おそろく制御の情報はすべて WebSocket でやり取りしているのでほぼリアルタイムに行えます
今回は GPIO の制御をしましたが、逆に言えば GPIO の制御ができるデバイスは全て Tinker Mode から制御できるということになります

参考サイト

Tips

iPhone アプリの「Lumos」で制御したい場合はプロジェクト配下にあるアプリ名が「controller_app」でなければなりません
一度プロジェクトを削除した場合などで Lumos を使いたい場合はアプリ名を必ず上記にしてください

2015年12月1日火曜日

RaspberryPi で CUI モード時にフォントサイズを大きくする方法

概要

CUI モードで起動した RaspberryPi ( 以下 RPi ) を起動しモニタに HDMI 接続のモニタ ( 例えばテレビなど ) を使っていると文字が小さすぎることがあります

環境

  • Raspberry Pi Type B Single Board Computer 512MB
  • Raspbian 8.0 (Jessie)
  • Kernel Version 4.1.7+

対応方法

1つ設定ファイルを編集し、再起動します

  • sudo vi /boot/config.txt

でコメントアウトされている以下の 2 つの設定をコメントインし再起動します

hdmi_group=1
hdmi_mode=4
  • sudo reboot

でいい感じのサイズの綺麗なフォントが映るはず

参考サイト

2015年11月30日月曜日

BL600 で RSSI の強度を上げる方法

概要

前回の記事で nrf51822 で RSSI の強度を上げる方法を紹介しました
この場合は例えば nRF51 DK ボード上で動かしていたり、USB ドングルを使って開発している場合にはいいのですが、BL600 等のサードパーティ製の製品上で動かす場合に有効になりませんでした
今回は BL600 上で動作する nRF51 系のアプリで RSSI を強くする方法を紹介します

環境

  • Windows7 64bit
  • nRF51822
  • nRF51 DK
  • nRF51 SDK 9.0.0
  • SoftDevice S130

設定方法

ずばり以下を設定する
自分は advertising_init メソッド内でコールしました

nrf_gpio_cfg_output(20);
nrf_gpio_pin_clear(20);

初めこれでできたときは「魔法とはこれか」と思ったくらいビックリしました
詳しいことは良くわからないのですが、どうやら nRF51 DK の P0.20 ピンが VDD 周りの制御をしているらしく、そこに信号を送らないようにすればいいとか、詳しい方ヘルプ、、、

参考サイト

2015年11月27日金曜日

nrf51822 で RSSI の強度を上げる方法

概要

アドバタイジング時に RSSI の強度を強くしたり弱くしたりすることで検知させたいデバイスの距離を操作することができます
nrf51822 で RSSI の強度を設定する方法を紹介します

環境

  • Windows7 64bit
  • nRF51822
  • nRF51 DK
  • nRF51 SDK 9.0.0

設定方法

適当な場所で以下をコールすれば OK です
自分は advertising_init 内でコールして問題ありませんでした

err_code = sd_ble_gap_tx_power_set(4);
APP_ERROR_CHECK(err_code);

sd_ble_gap_tx_power_set メソッドは ble_gap.h のヘッダファイルに含まれているのでない場合は include してください

設定できるパラメータは -40, -30, -20, -16, -12, -8, -4, 0, 4 だけです
これ以外を指定すると APP_ERROR_CHECK でエラーとなりアプリが停止します
試した感じだと -40 が弱く 4 が強い設定になります
-40 とかは本当に弱く 20 cm くらい離れると検知できません
4 は正確には計測していませんが、5m くらいは余裕でした

一度設定してからアプリ内で動的に変更することもできるようです

最後に

RSSI の強さが動的に変更できると具体的に何ができるか思いつきませんが、何かおもしろいことができるような気がします

参考サイト

2015年11月26日木曜日

RaspberryPi で無線 LAN のアクセスポイントを追加する方法

概要

過去に WiMax2 に接続する方法を紹介しました
WiMax2 が使えない状況が発生し iPhone のテザリングしかネットワークがなく、デザリングを新しい無線 LAN のアクセスポイントとして追加してみました

環境

  • Raspberry Pi Type B Single Board Computer 512MB
  • Raspbian 8.0 (Jessie)
  • Kernel Version 4.1.7+

手順

新規に network の定義を追加する

  • sudo cp /etc/wpa_supplicant/wpa_supplicant.conf{,.back}
  • sudo chmod 666 /etc/wpa_supplicant/wpa_supplicant.conf
  • sudo wpa_passphrase ssid ssid-password >> /etc/wpa_supplicant/wpa_supplicant.conf

ssid と ssid-password は今回は iPhone のテザリング情報を入力しました

追加した network 定義を編集する

  • sudo vim /etc/wpa_supplicant/wpa_supplicant.conf

追加した ssid の network の定義に以下を追加する

  • proto=WPA2
  • key_mgmt=WPA-PSK
  • pairwise=CCMP

記載したら保存して終了する

  • sudo chmod 600 /etc/wpa_supplicant/wpa_supplicant.conf

権限を戻しておく

ネットワークを再起動する

  • sudo systemctl restart networking

でしばらくするとテザリング用の NAT IP が iPhone からもらえると思います

最後に

既存の無線 LAN 設定が記載されている wpa_supplicant.conf に設定を追記するだけなので簡単でした

両方のネットワークにアクセスできる状況で、この設定ファイルを使うとどっちのネットワークを使うのか気になりました
優先度とかを定義することができるのか、単純にファイルの上位に記載されているネットワーク定義から評価していくのか、、、どうなんだろうか

試せる機会があったらやってみよう

2015年11月25日水曜日

nrf51822 でタイマーのクロック間隔を短くすることで起動時間を長く管理する方法

概要

前回 タイマーを使って起動時間を取得する方法を紹介しました
前回の問題点として管理できる時間が短いという点をあげました
今回はそれが解決でき、長い時間管理できるようになったので紹介します

環境

  • Windows7 64bit
  • nRF51822
  • nRF51 DK
  • nRF51 SDK 9.0.0
  • SoftDevice S130

実装方法

タイマーを使う方法は前回の記事を参照してください

まず前提として前回から判明したことが

  • 保存できるカウントの最大値は 24bit = 16, 777, 216 まで
  • 1 秒間のカウントで増加する値は 32, 768

であることがわかりました ( 参考 )

保存できるカウントを増やす方式は難しいため増加するカウントを減らすことで管理できる時間を増やせないか検討してみました

ずばり回答としては

#define APP_TIMER_PRESCALER 0

の値を増やすことです
この値を増やすことで影響するのが

APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false);

の部分です
この初期化をしている第一引数で増加するカウントの 32, 768 を割り算しているようです
例えば APP_TIMER_PRESCALER を 16 とすると 1 秒間でカウントされる値は

32, 768 / 16 = 2, 048

になります
なので最大保存時間は

16, 777, 216 / 2, 048 = 8, 192 (sec) = 136 (min) = 2.27 (hour)

になります
一応この値が 32 でも正常に動作することは確認しています

カウントから時間 (秒) を取得する方法は

uint32_t time = p_ticks / (APP_TIMER_CLOCK_FREQ / APP_TIMER_PRESCALER);

で OK です

気になる点

では一体 APP_TIMER_PRESCALER の値はいくつまで設定できるのかと言うとおそらく 4,095 までいけるっぽいです ( かなり不確定、カウントの最大が 24 bit であることから逆算しているみたいです )
確かに 4,095 を設定しても問題なく動くことは確認しました

ただ、今度はタイマーを使っているバッテリーレベルの Characteristics が更新されなくなってしまいました
32 や 16 のときはほぼリアルタイムで read してもバッテリーレベルが更新されていたのですが 4, 095 を設定すると更新されなくなりました

詳しく調査していないので、予想ですがこの後タイマーを作成 (app_timer_create) してスタート (app_timer_start) すると思うのですが、スタートする際にタイマーのインターバルを決定する引数 ( BATTERY_LEVEL_MEAS_INTERVAL) がありこれが APP_TIMER_PRESCALER を使っているため、更新するインターバルの時間が伸びたんだと思います

なので、ちゃんとやるとしたら時間を取得するためだけのタイマーを作成、スタートして、そのポインタから時間を参照するようにしたほういいと思います
チュートリアル を見てもアプリごとに 10 個タイマーを持てるとあるので、そうするのがベターなんだと思います

Tips

わからないことは Nordic Developer Zone で質問してみましょう
基本英語です
もちろん過去ログは検索してから質問したほうがいいです
結構適当な英語でも頑張って解釈してくれるので、ちゃんした返事が返ってきます