2015/10/29

[hw]ESP8266にnew.6を焼いた

えーい、迷っていても仕方ない。
new.5がいいのか、new.6がいいのかわからんので、焼いてから考えよう。

メモリマップを見ると、user1.binは領域が同じだから、それだけ焼いてしまえばいいだろう。
DOWNLOAD TOOLのテキストボックスが狭いので、横に広げて・・・。

image

広げるとこんなのが隠れてた。
でも、どうもせんけどね。

 

ready
AT+GMR
AT version:0.50.0.0(Oct 22 2015 11:56:11)
SDK version:1.4.1(pre2)
compile time:Oct 29 2015 18:10:20
OK

さっきコンパイルしたばかりだから、その時間になってるな。
フォルダ名はpre5だったのだが、ここではpre2になっている。
どこから文字列を引っ張っているかわからんかったが、まあよかろう。

アクセスポイントにつなぐこともできたから、とりあえずはこれでやってみよう。
次はHTTPアクセスしてみたいところだが、まだまだ知識が足らんねぇ。

[hw]ESP8266のコンパイル環境

ESP8266でATコマンド以外のことをやろうとしたら、ファームを作って焼くことになる。
まずはコンパイル環境を準備しよう。
もうハードウェアのことじゃないけど、いいや。


Step 1. Setup Linux Compile Environment 搭建ESP8266编译环境 - ESP8266 Developer Zone
コンパイル環境はここからダウンロード、とあるが、404 Not Found ...
More detailsのリンク先にあるGoogle Driveは生きていた。
https://drive.google.com/folderview?id=0B5bwBE9A5dBXaExvdDExVFNrUXM&usp=sharing
ダウンロードに時間がかかるので、ここで昼ご飯にしよう。

VirtualBoxに入れて、Guest AdditionsやOSの更新をする。
先にOSの更新をした方がいいのかな?
パスワードはespressifだ(PDF参照)。
これはこれで、かなり時間がかかる。
終わったら、Time and DateとかKeyboard Input Methodsとか、とにかく自分に合うようにしておく。

esp8266_lubuntuを起動しているVirtualBoxの「デバイス>共有フォルダー設定」を開いて、共有フォルダが設定されているか確認しよう。
PDFの手順通りにやるなら、共有名は「share」にしておく。
私はこの確認を、VirtualBox本体の設定画面でやっていたのだが、なぜかマウントがうまくできない。
「デバイス>共有フォルダー設定」の方を開くと、「Guest Additionsがインストールされていない」と警告が出てきた。
たぶん、Guest Additionsのインストール後にOSの更新をしたから、再インストールが必要になってしまったのだな。
やると、mount.shの実行でマウントできた。

そして、iot_sdkのappフォルダに移動して、make・・・と書いてあるけど、Makefileがないので動かない。
PDFと違うじゃないかぁぁぁぁぁぁ。
DSAS開発者の部屋:ESP8266 モジュールの AT コマンドに SSL クライアント機能を追加する
こちらを読むと、ビルドしたいものをappの中に置くらしい。
そして、gen_misc.shのあとにmakeしている。

esp8266@esp8266-VirtualBox:~/Share/esp_iot_sdk_v1.4.1_pre5/app$ ./gen_misc.sh 
gen_misc.sh version 20150511
Please follow below steps(1-5) to generate specific bin(s):
STEP 1: choose boot version(0=boot_v1.1, 1=boot_v1.2+, 2=none)
enter(0/1/2, default 2):
1
boot mode: new
STEP 2: choose bin generate(0=eagle.flash.bin+eagle.irom0text.bin, 1=user1.bin, 2=user2.bin)
enter (0/1/2, default 0):
1
generate bin: user1.bin
STEP 3: choose spi speed(0=20MHz, 1=26.7MHz, 2=40MHz, 3=80MHz)
enter (0/1/2/3, default 2):
2
spi speed: 40 MHz
STEP 4: choose spi mode(0=QIO, 1=QOUT, 2=DIO, 3=DOUT)
enter (0/1/2/3, default 0):
0
spi mode: QIO
STEP 5: choose spi size and map
    0= 512KB( 256KB+ 256KB)
    2=1024KB( 512KB+ 512KB)
    3=2048KB( 512KB+ 512KB)
    4=4096KB( 512KB+ 512KB)
    5=2048KB(1024KB+1024KB)
    6=4096KB(1024KB+1024KB)
enter (0/2/3/4/5/6, default 0):
6
spi size: 4096KB
spi ota map:  1024KB + 1024KB
start...
make[1]: Entering directory `/mnt/Share/esp_iot_sdk_v1.4.1_pre5/app/user'
DEPEND: xtensa-lx106-elf-gcc -M -Os -g -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -ffunction-sections -fdata-sections -DICACHE_FLASH -DAT_UPGRADE_SUPPORT -I include -I ./ -I ../../include/ets -I ../include -I ../../include -I ../../include/eagle user_main.c
DEPEND: xtensa-lx106-elf-gcc -M -Os -g -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -ffunction-sections -fdata-sections -DICACHE_FLASH -DAT_UPGRADE_SUPPORT -I include -I ./ -I ../../include/ets -I ../include -I ../../include -I ../../include/eagle at_upgrade.c
make[1]: Leaving directory `/mnt/Share/esp_iot_sdk_v1.4.1_pre5/app/user'
make[1]: Entering directory `/mnt/Share/esp_iot_sdk_v1.4.1_pre5/app/user'
make[1]: Warning: File `.output/eagle/debug/obj/user_main.d' has modification time 3.6 s in the future
xtensa-lx106-elf-gcc -Os -g -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -ffunction-sections -fdata-sections  -DICACHE_FLASH -DAT_UPGRADE_SUPPORT   -I include -I ./ -I ../../include/ets -I ../include -I ../../include -I ../../include/eagle  -o .output/eagle/debug/obj/at_upgrade.o -c at_upgrade.c
xtensa-lx106-elf-gcc -Os -g -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -ffunction-sections -fdata-sections  -DICACHE_FLASH -DAT_UPGRADE_SUPPORT   -I include -I ./ -I ../../include/ets -I ../include -I ../../include -I ../../include/eagle  -o .output/eagle/debug/obj/user_main.o -c user_main.c
xtensa-lx106-elf-ar ru .output/eagle/debug/lib/libuser.a .output/eagle/debug/obj/at_upgrade.o .output/eagle/debug/obj/user_main.o 
xtensa-lx106-elf-ar: creating .output/eagle/debug/lib/libuser.a
make[1]: warning:  Clock skew detected.  Your build may be incomplete.
make[1]: Leaving directory `/mnt/Share/esp_iot_sdk_v1.4.1_pre5/app/user'
make: Warning: File `user/.output/eagle/debug/lib/libuser.a' has modification time 3.7 s in the future
xtensa-lx106-elf-gcc  -L../lib -nostdlib -T../ld/eagle.app.v6.new.2048.ld -Wl,--no-check-sections -u call_user_start -Wl,-static -Wl,--start-group -lc -lgcc -lhal -lphy -lpp -lnet80211 -llwip -lwpa -lmain -ljson -lupgrade -lsmartconfig user/.output/eagle/debug/lib/libuser.a                     -lat -Wl,--end-group -o .output/eagle/debug/image/eagle.app.v6.out 
!!!
!!!user bin  1  !!!
-2067508167
2067508166
Support boot_v1.4 and +
Generate user1.4096.new.6.bin successully in folder bin/upgrade.
boot.bin------------>0x00000
user1.4096.new.6.bin--->0x01000
!!!
make: warning:  Clock skew detected.  Your build may be incomplete.
esp8266@esp8266-VirtualBox:~/Share/esp_iot_sdk_v1.4.1_pre5/app$ 

タイムスタンプがずれているのは気にしないでおくれ。

$ ls -l ../bin/upgrade/
total 7742
-rwxrwxrwx 1 root root  284596 Oct 29 14:29 user1.4096.new.6.bin
-rwxrwxrwx 1 root root 2881418 Oct 29 14:29 user1.4096.new.6.dump
-rwxrwxrwx 1 root root 4761082 Oct 29 14:29 user1.4096.new.6.S

なんかはできたようだ。
が、これをいきなり焼く前に、みんなのまねをしてビルド済みのものを焼いてみよう。
幸い、アップデートされるから焼かれたことも確認できる。

image

ESP_DOWNLOAD_TOOLのタイトルはV2.3になってるけど、ファイル名はV2.4だ。
あとね、このツールは日本語のパスとかに置かないようにしよう。STARTするとエラーになったよ。

ready
AT+GMR
AT version:0.50.0.0(Sep 18 2015 20:55:38)
SDK version:1.4.0
compile time:Sep 18 2015 21:30:56
OK

うん、ATは0.25.0.0→0.50.0.0になったし、SDKは1.1.2→1.4.0になった。

気になったのは、焼いたファイルが「user1.2048.new.5.bin」ということ。
さっきビルドしたらuser1.4096.new.6.binができたのだが、それはgen_misc.shのSTEP5で「6」を選んだからじゃないだろうか。
・・・うん、「5」でビルドしたらuser1.2048.new.5.binができた。

readme.txtを見ると、「user1.2048.new.5.bin」を使っているのは16Mbit-C1と32Mbit-C1だけだ。
そしてそもそも「6」のファイルはAT_v0.50の中に入っていない。
うーん、どう考えるとよいのだろうか・・・。

なお、ビルドしたbinの「5」と「6」の違いはこんな程度。
2番目はタイムスタンプっぽいし、3番目はチェックサムだろうか。

image

image

image

STEP 5: choose spi size and map
    0= 512KB( 256KB+ 256KB)
    2=1024KB( 512KB+ 512KB)
    3=2048KB( 512KB+ 512KB)
    4=4096KB( 512KB+ 512KB)
    5=2048KB(1024KB+1024KB)
    6=4096KB(1024KB+1024KB)

IOT_SDK_User_Manual v1.4に「6」を選んだときのメモリマップが載っていた。

image

  • sdk_v1.1.0以降
  • boot v1.4以降
  • flash download tool v1.2以降

「5」は、こう。

image

  • sdk v1.1.0以降
  • boot v1.4以降
  • flash download tool v1.2以降

条件は同じなのだが、右側のFLASHのUser Data領域が「6」の方が広いのだな。
それくらいみたいだから「6」でもいいのかな。

[勉]Bluetooth SIG

知らん単語を調べるシリーズ。
今回は「Bluetooth SIG」。

技術用語というわけでもないが、まあいいや。


Home | Bluetooth Technology Special Interest Group

SIGは「Special Interest Group」の略。
単なる略語なので、そんなに警戒(?)するものではない。

JPEGのGもそうだが(Joint Photographic Experts Group)、PNGのGは違う(Portable Network Graphics)。
WGはWorking Groupの略でしばしば使われるな。


Bluetooth SIG について | Bluetooth Technology Special Interest Group

英語のページばかりかと思いきや、日本語のページもあるのだ。
任務は、こう。

  • Bluetooth仕様の公開
  • 認証プログラムの管理運営
  • Bluetooth商標の保護
  • Bluetooth無線技術の普及促進

なんとなく、NFC Forumも同じような印象がある。
非営利団体だけど、仕様決めをするから、大きい会社なんかは会員になっているようだ。


メンバーシップ入門 | Bluetooth Technology Special Interest Group

どうやって会員になるかが、ここら辺に書いてある。
私は個人事業主なので「企業向け」だから関係が無いから、さらっと流そう。

 

メンバー名鑑 | Bluetooth Technology Special Interest Group

メンバーにも種類があるのだが、現時点では24288社がメンバーになっているようだ。
ただ、「ibm」で検索すると2つ出てきたりするように、場所やビジネスタイプかはわからないが、全社で1つというわけではなさそうだ。


さて、開発だけする人が関係するとしたら、仕様関係の情報だ。

採択済み仕様は、主に「コア仕様」と「コア仕様補完」を見るだろう。
現在(2015/10/29)のところ、コア仕様はv4.2、コア仕様補完はv5だ。

Assigned Numbersも見るが、私がよく見るのはGAPのところ。
なぜかというと、これは仕様書にも数値が書いてないのだ。
BLEのパケット解析をして数値が出てきて、それをGAPサイトで調べ、ヒットした名前をコア仕様補完から探す、という流れだ。

もう少し具体的に話そう。
例えば、スニファで以下のようなデータが取得できたとする。

image

まず、Adv PDU Typeが「ADV_IND」なので、コア仕様書をADV_INDで検索する。
そうすると、「Vol 6: Core System Package [Low Energy Controller volume] - Part B: Link Layer Specification - 2.3.1.1 ADV_IND」が見つかる。
ペイロードの説明で、AdvAが6oct、AdvDataが0~31octとなっていて、パケットもそうなってる。
AdvAはAdvertisingしている人のアドレスで、それがpublicなのかrandomなのかはTxAddでわかる。
AdvDataはAdvertising Data、とのこと。

じゃあAdvertising Dataはどうやって見ればいいのか、とPart Bを検索すると、「2.3 Advertising Channel PDU」に「フォーマットは [Vol.3] Part C, Section Appendix Aにある」と書かれている。
見に行くと・・・ないやん! 時間のことだけだ・・・。

仕方ないので Vol.3 Part Cを見ると「11 Advertising and Scan Response Data Format」があった。
ここの図にデータの構造が出ている。
1つ分の構造は、こうだ。

image

先頭がデータ長、あとはAD TypeとAD Data。
これが複数入っていて、全体で31octまで使えるようになっている。
このAD Typeが、上記リンクのGAPに書いてあるのだ。

先ほどの図にあるパケットは、AD Typeが0x01。
データタイプ名は「Flags」だ。

image

コア仕様補完のPart A - 1.3章を見よと書いてある。

image

そうしてようやく、AD Dataが1octで、ビットごとに意味を持っているということがわかる。
0x05なので、

  • LE Limited Discoverable Mode
  • BR/EDR Not Supported

ということだ。


Bluetooth Development Portal

Developer Potalというサイトもある。
こちらは、個人でもアカウントを作ることができる(作る利点はわかっていないが・・・)。

Bluetooth Developer Studioなどもこちらからダウンロードできる。
ダウンロードは直接できず、フォームにメールアドレスなどを書くと、そこにダウンロード先が送られてくるという形だ。

2015/10/28

[hw]ESP8266でATコマンドを使いたいならNon-OS版

そうそう、UART Downloadモードで何を焼くかだが、これはSDKがあり、それでビルドしたものを焼けるらしい。
今(2015/10/28)までの最新版は、

  • Non-OS:1.4.0
  • RTOS : 1.1.0(githubに行ったら、1.2.0があった)

とのこと。

こちらが、Espressif Systemsのリポジトリ一覧
それを読むと、RTOSはFreeRTOSをベースにしたものらしい。
もう1つ、IoT Platformのリポジトリがあり、こちらもRTOS版のSDKがベースらしい。

 

Q: What is the difference between RTOS and the non-OS SDK? - ESP8266 Developer Zone
こちらによると、non-OS版はATコマンドに対応するけど、RTOS版は対応してない、というように読めた。
なんとなく、OSのタスクとしてUART処理タスクがいて、それがさばいているという予想だったのだが。。

DSAS開発者の部屋:ESP8266 モジュールの AT コマンドに SSL クライアント機能を追加する
こちらは、ATコマンドを追加された方。
うーん、iot_sdkを使っているようだ。
Non-OSの最新版は1.4.0だが、これは「esp_iot_sdk_v1.4.0_15_09_18」となっていた。
つまり、iot_sdk=Non-OS版、ということだ。
よく見れば、Latest Releaseの下に書かれているTipsに「PWMやATが使いたいならNon-OSを使え」とあった。

 

Non-OS版はgithubには上がっていないようだ。


では、うちにあるWROOM-02にはどれが焼いてあるのか確認しよう。

AT+GMR
AT version:0.25.0.0(Jun 24 2015 18:02:27)
SDK version:1.1.2
compile time:Jun 24 2015 18:15:29
OK

コンパイル日時が2015年6月24日。
この「SDK v1.1.2 Patch for AT firmware」かなぁ。
http://bbs.espressif.com/viewtopic.php?f=46&t=648
AT_bin_v0.25とあるから、これかな。

これを最新にしようとしたら、こうなるのか。

  • ベース:Non-OS版1.4.0 or Patch 1.4.1_pre5
  • ATコマンド:AT v0.50

Patchと書いてあったが、展開するとまるまる入っていた。
差分はこう(左側はv1.4.0)。

image

v1.4.0のbin/atと、AT_v0.50に入っているファイルの違いは、AT_v0.50にはblank.bin、boot_v1.4(b1).bin、esp_init_data_default.binの3ファイルがあるだけだ。
それ以外にも、512+512だの、1024+1024だのフォルダがあるのだが、どれを焼くのだろう?

ねむいさんのぶろぐ | ESP-WROOM-02を使ってみる2 -外付けSPIフラッシュの書き換え-
こちらでは、1024+1024とのこと。
readme.txtにFlashサイズが書いてあるので、そこから選べばよいのだろう。
あら、WROOM-02は32MbitのFLASHが載っているのだが、「32Mbit」と「32Mbit-C1」がある。
ブログでは、32Mbit-C1を選ばれているのだが、はて、なんでだろうか?

-C1 designation from readme.txt in SDKv1.4\bin\at - ESP8266 Developer Zone
こちらによると、-C1がつく方は公式ダウンロードツール用みたいだ。
でも、それなら公式ダウンロードツールは-C1がついたサイズだけ表示してればいいんじゃないのか?

image

ツールのホバーを見ると、コンパイル時の設定でキャッシュがどうのこうのと書いてある。
もうわからなくなってきたので、キャッシュのCとでも思うことにしよう(違うと思うが)。

[hw]ESP8266とWROOM-02

ESP8266はこちら。
http://espressif.com/en/products/esp8266/

そしてESP-WROOM-02はこちら。
http://espressif.com/en/products/wroom/

今回買ったのは、WROOM-02という、ESP8266EXが載ったボード。
WiFiができてホストとATコマンドでやりとりするボード、くらいに思っていたのだが、もっとパワフルだ。
どちらかというと単体でも動けるし、ATコマンドでやりとりもできるし、というところか。

ESP8266EXは、Transilca社のLX106というものをコアプロセッサにしているとのこと。
WROOM-02はそれに加え、プログラム用にSPIのFLASHメモリが32Mbits、つまり4MByte分載っているようだ。
WROOM-02のピンとしてはSPIも出てるけど、FLASHメモリともつながっているから、使いたいときはChip Selectを制御しながらやりなさい、ということなのだろう。
購入したピッチ変換基板にはSPIなどが出されていないのは、あまりそういう使い方はしないから減らしておこう、ということなのかな。

そして、そのSPI FLASHをUART経由で書き換えることができて、それがESP8266を「UART Download Mode」で起動した場合なのだろう。
ESP8266のHardware User Guide v1.1によると、2つのモードがあるとのこと。

  • UART Download mode
  • Flash Boot mode

UART Downloadモードは、ダウンロードツールを使ってFLASHかメモリにプログラムをダウンロードできる。メモリに焼いた時は再起動したら消えますよ、と書いてある。まあそうだろう。

焼き方は、こちらが詳しそうだ(私はまだやってない)。
ねむいさんのぶろぐ | ESP-WROOM-02を使ってみる2 -外付けSPIフラッシュの書き換え-

 

そういうのを、あちこち読みながらようやく理解した。
いやあ、奥が深いというか、ちゃんと調べないといかんですなぁ。

[android]BLE許可と位置情報許可の両方を考慮

Android6.0というかAPI23というか、そこからアプリごとに位置情報の権限を許可するかどうか設定できるようになった。
しかし、それとは別に端末自体のBluetooth有効設定というものがある。
この2つは、それぞれ別に設定できるのだけど、その許可を得る場合にはどう組み合わせるとよいのだろうか?

パターンは、こうなる。

  1. Bluetoothも有効だし、アプリの位置情報も許可あり
  2. Bluetoothは有効だが、アプリの位置情報は許可無し
  3. Bluetoothは無効だが、アプリの位置情報は許可あり
  4. Bluetoothも無効だし、アプリの位置情報も許可無し

1~3は、あまり問題が無い。
両方有効であればそのまま動けばよいし、片方だけであれば今まで通り確認すればよい。
問題は4番。
両方とも許していない場合は、どのようにあしらうとよいのだろうか?

ちなみに、いまgithubにアップしているソースでは3番もだめだ。
まだ調べきれていないが、getBluetoothLeScanner()でnullが返るため、onResume()時に強制終了してしまっている。


まず、onResume()。
ここでは、BluetoothAdapter#isEnabled()がfalseだった場合、startActivityForResult()してBluetooth使用の許可を得ようとしている。
で、勘違いしていたのだが、これは非同期処理なので、そっちはそっちで動くけれど、今のコンテキストもそれはそれで流されるようだ。
投げたインテントから結果が返ってくると、onActivityResult()が呼ばれるようだ。
サンプルでは、Bluetoothが許可されなかったらアプリ終了のfinish()を呼んでいる。

いま強制終了しているのは、Bluetoothの使用許可を得る前にBLEのスキャンを開始しようとしているためだろう。

対応を追加した。
許可が無いときの対応追加 · hirokuma/android-BluetoothLeGatt@70d24eb
ついでに、アプリ権限の確認をonResume()に移したり、権限の許可を求めるときはスキャンを開始しないようにしたりしている。
なんか、しくみがわかっていないものを変更している感じがして、怖いですな。
でも、いまや一人で全部作ったとしてもできることなどたかが知れているので、楽できるんだ、と考えることにしよう。

[hw]WROOM-02をつないだ図

自分用に、WROOM-02をつないだときの回路図を載せておく。
回路図は、いつもの水魚堂の回路図エディタです。

image

WROOM-02と書いたが、ネットで見ているといろいろなところで販売されていて、ピッチを変換するボードもいろいろあるようだ。

私は、スイッチサイエンスさんから、WROOM-02と変換基板をそれぞれ購入した。
WROOM-02だけ購入して、ピッチ変換の基板がないと面倒なのに気付いた、というパターンだ。
ESP-WROOM-02ピッチ変換済みモジュール《シンプル版》 - スイッチサイエンス
こちらと同じように見えるが、基板別売りの方はIO02が3V3とショートしているが、セットになっている方はカットされているそうだ。
データシートではこのようになっている。

image

image

GPIO2はどちらもHighだから、別にカットしなくてもよいように思うのだが・・・。
それと、IO2が3V3とショートしているなら、IO0もプルアップ抵抗とか使わずにショートさせてもいいんじゃないの?

そういう、ハードに詳しくない人の疑問はあるのだが、壊すもの嫌なので従うことにした。
ここでチップ抵抗とか持っているとかっこよくできるんだろうけど、大きい抵抗器しか持たないので空中配線だ。
配線は、前回購入したTTW-200が役立っている。

image

 

さて、せっかくなのでアクセスポイントと接続したい。
うちのは、NECのWARPSTAR WR4100Nなのだ。
WPA/WPA2-PSK(AES)なのだけど、つながってくれるのだろうか?

よくわからんので、こちらを見ながら設定。
ESP8266 - ESP-WROOM-02を動かしてみた - Qiita

AT+GMR
AT version:0.25.0.0(Jun 24 2015 18:02:27)
SDK version:1.1.2
compile time:Jun 24 2015 18:15:29
OK
AT+CIPSTAMAC

ERROR
AT+CIPSTAMAC?
+CIPSTAMAC:"WROOM02のMACアドレスがコロン区切りで表示"

OK
AT+CWMODE=1

OK
AT+CWJAP="SSIDの名前","パスキー"
WIFI CONNECTED
WIFI GOT IP

OK

おー、できたできた!
赤文字がターミナルから入力した文字列だ。
「?」を入力し忘れてエラーになるのも確認した(打ち間違えただけだが)。

knaka IT-blog: esp8266(esp-wroom-02) WIFIの接続テスト (PCから)
こちらによると、初回はアクセスポイントへの接続リトライを繰り返すらしい。
自分のところに接続する前に「AT+CIFSR」コマンドで見ていたのだが、うちのじゃないIPアドレスになっていた。
出荷時の動作確認で残ったままなのかもしれないが、だから最初から電流が多く必要なのだな。

 

PC経由で接続しても面白くないので、次は小さい基板で動かしたい。
いきなりUART操作しようとして足が吊ったらいかんので、準備運動としてmbedを使おう。
うちには、STM32のNUCLEO-F411REと、nRF52832のPreview-DKがあるのだが(BLE Nanoはセンサーを付けたので除外)、Preview-DKってmbedのサイトに出てこないのよねぇ。
こういう、表に出てこないmbedのPlatformってどういう風に扱うものなのだろう?

ともかく、情報が集まりやすそうなNUCLEOを使うことにしよう。
今日と明日くらいしかまとまった時間で遊ぶことができないから、何か動かせるようになっておきたいものだ。

[勉]BtoB, B2B

知らん言葉を調べるシリーズ。
今回は、BtoBとかB2Bとか。

ITProのメールマガジンで、「【最終回】BtoBマーケティングの理想形」というのを見かけたからキーワードにしたのだが、リンク先につながらなかった。。。


B2B(ビー ツー ビー)とは - コトバンク
企業間取引 - Wikipedia

企業間での電子商取引とのこと。
Bは、BusinessのB、だ。

内容はともかく、「to」を「2」で置き換えるのは、しばしば略語として見かける。
そして、B以外にも見かけるので、いくつか並べておこう。

  • B2B : Business to Business(企業間)
  • B2G : Business to Government(企業と政府)
  • B2E : Business to Employee(企業と従業員)
  • B2C : Business to Consumer(企業と消費者)
  • C2C : Consumer to Consumer(消費者間)

うーん、なんでもあり、という感じがしてきた。
こういう略語って、なんとなく胡散臭く感じてしまう・・・。

まず気になるのが、和製英語じゃなかろうか?だ。
ほら、「ナイター」とかは子供の頃から聞く言葉だったけど、教えてもらうまでは和製英語だって知らなかったし。
Business-to-business
英語のWikipediaに出てくるから、大丈夫だろう。

コトバンクや日本のWikipediaと英語のWikipediaを見て思ったのだが、日本の方は「電子商取引」が前面に出ているけど、英語版はそんなに出てないところだ。
写真の説明にelectronicと出てくるが、これは電子部品を売ってる店というだけのようだ。秋葉原のラジオ何とかみたいに店が並んでいるのかな?

Business-to-business – Wikipedia
こちらはドイツ語版。
「electronische」が電気っぽいのでGoogle翻訳すると、電子通信とかeビジネスとか出てくるので、英語圏以外の人が「B2B」みたいに使うと、電子商取引の意味合いを含むということかもしれんな。

[hw]ESP8266がfatal exceptionする (2)

私は解決するまでしつこいぞ。
というわけで、studyシリーズをかなぐり捨てて調査に入った。

うちのESP8266というか、WROOM-02がfatal exceptionする件についてだ。


ESP8266のことを調べると、最初に出てくるのが「電流がいるよ!」だ。
うちは、これを使っている。
ブレッドボード用電源ボード3.3V - スイッチサイエンス
最大200mAということで、そんんだけあれば十分だろうと思っていた。

が、うちで起きている「fatal exception (0)」で検索すると、こういうのが出てきた。
Everything ESP8266 - Fatal Exception (0)
「least 200mA」って、そんなにいるのかい??
通信中ならまだしも、起動のところはそんなに使わないように思うのだが・・・。

PDFを読むと、最初の方にあるスペックとしては「平均80mA」だったが、人々の記事を見ていると、レギュレータで安定した電源を供給できない場合は、コンデンサを入れて対応しているようだった。

 

まずは、0.1uFのコンデンサを+3.3VとGNDの間に入れてみた。
極性がない、肌色のエイみたいなコンデンサね。
・・・変わらず。

では、470uFの電解コンデンサを入れてみた。
極性がある、ロボットみたいなコンデンサね。
おお! リセットしなくなった!!

普通に動いた場合は、115200bpsのコンソールを開いているとゴミっぽいものが出た後「ready」が出て止まる。
「AT+GMR (CR/LF)」とすると、バージョン情報が出てきた。

AT+GMR
AT version:0.25.0.0(Jun 24 2015 18:02:27)
SDK version:1.1.2
compile time:Jun 24 2015 18:15:29
OK

壊してなくてよかった~

2015/10/27

[hw]ESP8266がfatal exceptionする

WiFiモジュールのESP-WROOM-02 Wi-Fiモジュールを購入した。
いきおいでハンダ付けしたものの、fatal exception (0)が出て、何もできない。。。
眠たいので、後日調べるためのログだけ残しておく。
このログは、繰り返しずっと出続けるのだ。

 ets Jan  8 2013,rst cause:1, boot mode:(3,7)
load 0x40100000, len 1396, room 16
tail 4
chksum 0x89
load 0x3ffe8000, len 776, room 4
tail 4
chksum 0xe8
load 0x3ffe8308, len 540, room 4
tail 8
chksum 0xc0
csum 0xc0
2nd boot version : 1.4(b1)
  SPI Speed      : 40MHz
  SPI Mode       : QIO
  SPI Flash Size & Map: 8Mbit(512KB+512KB)
jump to run user1 @ 1000
Fatal exception (0):
epc1=0x40202280, epc2=0x00000000, epc3=0x00000000, excvaddr=0x0000003c, depc=0x00000000

 

ハンダ付けを自分でやったので、どこか甘くなってるのかも、と弱気になってきた。
でも、RSTをプルダウンしてもプルアップしても動作が変わらん気がする。
GPIOの0をGNDに引っ付けるとログがすぐに止まるので、ファーム更新モードなどは生きているのだろう。

うーん、後日後日。

2015/10/26

[android]@NonNull?

GitHubにあったAndroidサンプルを開くと、Android Studioエディタのスクロールバーにマークがいくつも出てきた。

image

付近をクリックすると、ソースに薄黄色のマークがついていた。
カーソルを当てると、ホバーに「Not annotated parameter overrides @NonNull parameter」とか出てきた。
はて、エラーではないようだが、何を言っているのだろうか・・・。

検索すると、こちらが出てきた。
脱ビギナー!Androidのnullな話 - クックパッド開発者ブログ
Annotationはなんとなく調べたことがあったけど、Androidが標準で用意したAnnotationということか。
@Nullableが「nullもありですよ」で、@NonNullが「nullはなしですよ」。
もし@NonNullしててnullが来たら、例外を発行してくれるらしい。

なるほどねぇ。
私は、nullって出てきたからNULLチェックでもすればいいんだろう、と入れたけど変わらなかったので、不思議に思ったのだ。
Cとかだと静的解析ツールやコーディング規約がうるさいので機械的に入れたりするけど、どうせNULLになる時点でだめやん、と思うのですよねぇ。
役に立たないわけじゃないけど、どっちかというと開発中はassert()で落とす方が好きなのだ。

[android]startLeScan()は時代遅れ?

Androidを調べてはブログに書き、調べてはブログに書き、と、ぜんぜん進みません。
今回は、Peripheralのスキャンについて。

サンプルを見ると、startLeScan()というAPIでスキャンしていそうだったので、検索した。
そうすると、こんなのが出てきた。
android - startLeScan replacement to current api - Stack Overflow
stopLeScan()はdeprecatedらしいので、新しいのはどのクラスにあるの?という質問だ。
えー、Androidについているサンプルって、そのときの最新になってるもんじゃないの??
ないんだろうね。

API21からは、こちららしい。
BluetoothLeScanner
Lollipopということで、Android5なのかな。

 

こちらがわかりやすそうだ。
Android5.0〜でBLEを使う(Central編) - vaguely
ふだんPeripheralだけしか見てないので、Centralと出てくるとびくっとするな。

さて、AndroidサンプルをGitHubからForkすることができたので、ここまでの変更を置いた。
https://github.com/hirokuma/android-BluetoothLeGatt

まだスキャンするところを差し替えただけで、内容はまったく把握してないです。ははは。

[android]位置情報許可が無いときに許可を求める

遊んでいられる時間も少なくなってきたので、せめて今週中にはAndroidでNotifyを受けとって時間と値を表示するようなアプリを作りたい。
手っ取り早く、Androidについているサンプルを改造して仕立てよう。

でも、あれだけはやりたい。
アプリが位置取得を許可していないから動作しない、というやつへの警告だ。
BLEのアプリは、こういうのをやることになると思っている。

  1. [実装]uses-permissionの設定
    • android.permission.BLUETOOTH
    • android.permission.BLUETOOTH_ADMIN
    • android.permission.ACCESS_COARSE_LOCATIONかFINE_LOCATION
  2. [設定]アプリの許可
    • 「位置情報」を許可する
    • API23以降だけ?

1番目はアプリを作るときにやればいいけど、2番目は実行時の話だ。
気付かないままになりそうで、怖い。

スキャンしたときに例外が発生するとかだろうと思ったが、

W/Binder: Caught a RuntimeException from the binder stub implementation.
          java.lang.SecurityException: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results
              at android.os.Parcel.readException(Parcel.java:1599)
              at android.os.Parcel.readException(Parcel.java:1552)
              at android.bluetooth.IBluetoothGatt$Stub$Proxy.startScan(IBluetoothGatt.java:772)
              at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper.onClientRegistered(BluetoothLeScanner.java:324)
              at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:56)
              at android.os.Binder.execTransact(Binder.java:453)

と、アプリ名が出てこないので、catchはできなさそうな気がする。
できたとしても、それよりはアプリが表に出てきたときに警告する方が親切だと思う。

なのでやりたいことは、こう。

  • 自分のアプリで「位置情報」が許可になっているか調べる
  • 許可されていない場合は、アプリ情報の画面に飛ばせるようにする

こういう説明がGoogle Playにあるので、普通にインストールするときは聞いてきてくれるのかも。
Android 6.0 以降のアプリの権限の管理


この辺を参考にした。

onCreate()の最初の方に、こんなのを追加。

        if (checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // 権限がない場合はリクエスト
            requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
        }

起動すると、こういうのが出てきた。
「許可」にすると、アプリの権限にも「位置情報」が許可されていた。

image

まあ、onCreate()だけじゃなくて、onResume()にも入れた方がいいんだろうな。
とは思うのだけど、位置情報を許したくない人にとってはうっとうしいだろう。
でも、BLEでスキャンしないということはあまりないと思うので、許可が無いままだったらアプリ終了、でもよいかもしれない。

2015/10/25

[nrf51]PairingとBonding

nRF51822とAndroidアプリだが、なんか気持ちが停滞してしまって進んでいない。
目が乾燥している気がするのよねぇ。

せっかく作るから、今みたいに誰でも接続できるんじゃなくて、ペアリングとかしてみたい。
ペア・リング(Pair Ring)を装着してみたい、じゃないよ。
ペアリング(Pairing)をしてみたいのだ。

そういえば、ボンディングという言葉もよく聞く。
検索すると、どっちも引っかかったりして訳がわからなくなってきた。
どこがどう違うのだろうか?
あるいは、「一般人はペアリングって呼ぶけど、開発者はボンディングって呼ぶよね」みたいなことなんだろうか?


こういうときは、NordicのInfocenterだ。

Paringのシーケンスは、SMP Pairing Phase 2のあと、アプリにBLE_GAP_EVT_CONN_SEC_UPDATEを返し、最後にBLE_GAP_EVT_AUTH_STATUSがSUCCESSで返っている。

Bondingもほぼ同じなのだけど、BLE_GAP_EVT_CONN_SEC_UPDATEのあと、SMP Pairing Phase 3があってからBLE_GAP_EVT_AUTH_STATUSがSUCCESSで返り、アプリは鍵を保存している。

シーケンスはほとんど一緒なのだが、どこで動きが変わっているかというと、最初にCentralからSMP Pairing Requestが来て、SoftDeviceがアプリにBLE_GAP_EVT_SEC_PARAMS_REQUESTが通知されたときと、その返し方が違っていた。

  • Paringのとき
    • BLE_GAP_EVT_SEC_PARAMS_REQUESTが「no_bond」で来ている
    • sd_ble_gap_sec_params_reply()の最後の引数が「NULL」になっている
  • Bondingのとき
    • BLE_GAP_EVT_SEC_PARAMS_REQUESTが「bond」で来ている
    • sd_ble_gap_sec_params_reply()の最後の引数が「p_keyset」になっている

ということは、PairingかBondingかの違いはCentral側が主導権を持っているということか。
AndroidとかiOSとかでペアリング操作はOSの役目だと思うけど、そのときに「ペアリング or ボンディング」みたいな選択はないと思う。

ボンディングのbondって、木工ボンドとかのあれと同じ意味なのだろうか。
だったら、のり付けというか、通信するペアになりはするけれども、ペアを覚えておくほどでもない場合がペアリングで、覚えておくときがボンディングなのだろうか?
シーケンスの一覧を見ても、PairingとBondingがあるのはJust Worksだけで、Passkey EntryやOOBのときはBondingしかないのよね。
Interface誌の特集では、暗号鍵の交換手順がボンディングとあるのだが、とりあえずNordicではそういう使い方をしているようだ、というところにとどめておこう。


sd_ble_gap_sec_params_reply()の最後の引数はin/outなんだけど、examplesを検索しても使っているのはmultiprotocol/ble_app_gzllのサンプルで、まねしていいのかどうかわからん。
試してみればいいんだろうけど、nRF52でNFCペアリングしようとして訳がわからなくなってしまったので、やる気が起きないのよねぇ。

2015/10/24

噂のTTW-200

噂のあいつが届いた。
そう、TTW-200だ。

image

かちっ、とはまる。
実に快適だ!

ソフトも焼き直して、ちゃんとAD値が取得できるようになった。
よかったよかった。

[ble]Advertisingのアクセスアドレスは同じ

私はBLEのパケットスニファとして、TIのドングルを使っている。
だいたい、こんな感じのパケットが取れる。

image

PDU以降しか見ていなかったが、急にAccess Addressが気になった。
これを載せると、ハードウェアがわかってしまって、もしうちの近所でBLE開発している人がいたら私のことがバレてしまうかも・・・。

そう思って、BLE Nanoを買ったことだし試しに見てみると、同じ値。
iPad miniのアプリからPeripheralになって送信してみたが、同じ値。
あれ、みんな同じ値なの??

こういうときは、Bluetoothのコア仕様書だ。
Core_v4.2の、「Vol 6, Part B 2.1.2 Access Address」にはこうある。

image

同じなんだ!
0x8E89BED6で固定なんだ。

念のため、shallがどのくらいの位置づけかも確認。
これは「Vol 1, Part E 1.1 SHALL」に「mandatory requirements」とある。
RFC-2119と同じで、必須、かなり強い必須ととらえてよいだろう。

なので、改造したBLE端末とかじゃない限りは、このアクセスアドレスなんだろう。
特定されなさそうでよかった~と思ったけど、この記事を書くときにAdvertisingしてるから、時間帯でバレてしまう可能性もあるな(上の画像でペイロードをはずしたのも、バレるのを防ぐためだ)。
電波暗室とか作れるといいんだろうけど、個人じゃ無理だし、この周波数帯だといろいろ困りそうだ。

[nrf51]意外ッ! それはAdLint対応

来月から、家でお仕事になる。
すごく怯えている・・・。
仕事内容はともかく、どうやって品質を保てばよいか、というところなのだ。

[c]静的解析ツールAdLintを試す
以前、といっても今月なのだが、AdLintを試そうとしていた。
そしてそのまま忘れていたのだが、そろそろちゃんとせんといかんということで、仕事とは全然関係の無いnRF51822で遊んでいるソースで試した。

前回はWindows環境でやったけれども、nRF51はどっちかというとgcc系で使っている(Keilはバイナリ制限があるので)。
なので、やはりcygwinくらいでやろうとしたが、当時と同じくうまく動かず。
あれこれ考えたが、純粋に「adlint」コマンドの実行パスがWindows側にインストールしたadlintを読んでいることがわかった。
パスの問題であれば、.bashrcにcygwin側のrubyでインストールしたadlintのパスを先に追加した。
パスは、「gem which adlint」で確認し、ここではlib/adlint.rbが出てきたので、bin/adlintをPATHに追加だ。
それで、cygwinでも動かすことができた。
(あっさり書いているが、すごく時間がかかってしまった・・・)

通った後は、AdLintに対応していくだけなのだが、これはこれで時間がかかった。
やはり静的解析なので、ヘッダファイルはすべて読み込めるようにしておかないといけない。
やり方は書いてあったのだが、こちらの「ユーザ独自の環境設定をする場合はどうすればいいの?」が役立った。
まあ、こういうのはツールを購入しても発生するから、慣れておくしかないだろう。
どうしようもないところは、YAMLのファイルを編集して逃げるみたいだ。

https://github.com/hirokuma/nrf51822_adctest
ここの、nrf51822/s110/armgcc/adlintに、AdLintの設定ファイルを置いている。
adlint_traits.ymlファイルは、gccへの絶対パスをL.145辺りに書いているので、修正が必要だ。

 

と、書いてはいるが、単にこれはAdLintに対応しただけで、AdLintの指摘に対応したわけではない。
実際にAdLintを通すとわかるが、たくさーん出てくる。
main.cだけd、600行以上も指摘があるのだ。
どういう指摘かは、ふふ、実際にやってみた人だけのお楽しみだ。


いちおう言っておくと、もったいぶってるわけでもなんでも無く、この辺りを気にする人は私が書かなくても気にするだろうし、気にしない人は私が書いても気にしないだろうから、わざわざ載せないだけだ。
これを気にし出すと、プロジェクトの人間関係が悪くなりやすいから、プロジェクト管理の人が「ごめん、やって!」とお願いするようなやり方がいいんじゃないかと思っている。
品質には問題が無いのに、ツールの指摘を消すだけのために変更してもらわんといかんからだ。

static関数のNULLチェックなんか、私はassert()で止めてしまいたいタイプなんだけど(どうせNULLだったとしてもバグ以外ないし)、再起動させればひとまず対応できるというのも間違った考え方ではない。
では、それを誰が決めるかというと、プロジェクトリーダー(PL)になるだろう。
PLは会社の方針とかで決めるかもしれないが、プロジェクトのことはプロジェクトで決めるのが筋だと思う。
曖昧な指示に対しては、曖昧な結果しか返ってこない。

 

などと、ごにょごにょ考えてしまうが、今回はこのくらいにしておこう。

2015/10/23

[nrf51]一発勝負して、敗れる…

BLE Nanoは小さいので、電池ホルダーに直接取り付けることにした。
取り付けると、もう前回みたいな焼き方はできなくなる。
そういう勝負をかけてよいのか・・・。

えいっ

image

 

えーっと、Analog Inのピンをアプリで1つ間違えていましたね。。。
P04とP05がAINになることができて、P04がAIN5、P05がAIN6。
P04を使ったのでAIN5とするべきだったのだが、4に目が行ってしまってAIN4にしてしまったのだね。
hirokuma、敗れたり。。。

 

AIN4はP03なので、S2とS7を変更すればいいんだけど、あしたTTW-200が届くから、もうこのままにしておこう。

[nrf51][bds]サービス構造体がservice_if.cに移った

Bluetooth Developer Studioが正式リリースされたのに伴ってか、Nordicプラグインも1.1.7になった。
その際、自動生成するサービス構造体のインスタンスが、service_if.cに移動した。

そうなってしまうと、直接サービスが持っているAPIをアプリからたたけない。
いま困っているのが、Notifyの送信方法についてだ。
AD変換が終わったら値をNotifyしたいのだけど、あらどうしましょう。

どっちかしかない。

  1. service_ifにNotify用のAPIを追加する
  2. service_ifにサービス構造体のインスタンスを返すAPIを追加する

1がまっとうな気はするのだが、たったインスタンス1つだけのためにAPIをserviceの数だけ追加せんといかんの?という思いが出てしまう。
最適化してインラインになってくれそうな気もするが、呼び出すだけなのに・・・。

それに、今までのNordicサンプルは、直接ServiceのAPIをたたく形だったので、また元に戻るんじゃないのか、という気もする。
だったらインスタンスのポインタをもらうようにすると済むのだけど、内臓をさらけ出すようでそれはそれで気持ちが悪い。
まあ、イメージとしてはC++のthisみたいなもんなので、そう割り切ればよいのだろうが。

うーーーーん・・・・・
答が出せない・・・。

[勉]LTE

知らん言葉を勉強しようシリーズ。
今回は、LTE。

既に、ネタをどこから仕入れていいかわからなくなりつつある・・・。


LTEネットワーク、実は盗聴が容易 - 5G - 日経テクノロジーオンライン

今回はここを見て思いついた。
見ただけで、内容は読んでいない。

3G、3.5Gとかまではなんとなく覚えているが、そこから4Gだの、その一歩手前だの、いろいろ規格があったように思う。
HSDPAってなんだっけ?と思ったら、これは3.5Gに相当するみたいだ。
Wikipediaによると、LTEは3.9Gとのこと。さっきでいう「一歩手前」のやつだ。


LTE

Long Term Evolutionってことはわかるが、いったい何が長いんだ?と思うではないか。
これは通信規格とかパケットとかそういうのではなく、3Gを長期的に発展させるとかそんな意味らしい。
読もうとしたけど、専門的すぎてわからん・・・。

 

NTT東日本 | 3G・4G・LTEが分からない!:スマホ時代は「LTE」「4G」が主役に | フレッツ光

3.9Gってさっき書いたけど、4Gとしてとらえるのが一般的になってきているらしい。
なんということだ・・・。

 

多少眺めた感想としては、

  • みんな、速度と使えるエリアくらいしか興味を持ってないみたい

ということか。


うん、今回はこのくらいで満足だ。

[nrf51]Bluetooth Developer Studio 1.0

朝方、Bluetooth Developerからメールが来ていた。
Bluetooth Developer Studioの1.0がリリースされたというメールだった。

ダウンロードには、フォームへの入力が必要だ。
入力すると、メールが送られてきて、ダウンロードできるようになる。
きっと一度ダウンロードした人は同じURLからダウンロードできるんだろう、と前のメールを残しておいたのだが、捨ててよいようだ。

なお、以前試したときの記事はこちら。


nRF51用のプラグインも更新されていたので、差分を見ておこう。

 

image

componentsの変更ファイルは、ble_srv_common.cとhくらい。
BDS版には、SoftDeviceのバイナリは入っていない。
app_util_bds.hは・・・空行だけの違い。
なんでそういう変な差分を残すのかねぇ。nRF SDKは変更が多くてただでさえ困ってるんだから、こういう局所的な変更のときくらいは最小限に済ませればよいのに。

 

image

こちらはexamples。
グレーになっているのは、BDS版にだけ存在するファイルだ。
main.cが変更になっているので見てみたが、serviceの初期化がbluetooth_init()というのを呼ぶだけで済むようになっている。
それに伴い、サービスへのハンドラがbluetooth_on_ble_evt()に移動し、サービス構造体も消えた。

と、service_if.cのbluetooth_init()を見てみたが、空実装だった。。。
い、いや、これはきっとpluginが自動生成するところだからに決まっている。

では、新しいBluetooth Developer Studioで試してみよう。


使い方は、以前とそれほど変わらないようだ。
気付いた点をいくつか。

  • アプリを起動したときに、UACが働いていたのが普通になった
  • PREFERENCESがついた。
    Check for Updateがあるから、これからは自動更新できるのかな?
  • Generate Codeに、レポートの出力機能が追加された。
    Level1~3で、以下のようなものが出力できた。
    1. Proflieの内容と、ServiceおよびCharacteristicのUUID
    2. Proflieの内容と、ServiceおよびCharacteristicの詳細
    3. Proflieの内容と、ServiceおよびCharacteristicとそのフィールドの詳細
  • GAPボタンが付いた(前からあったっけ?)。
    Advertisingするデータの編集ができそう。

image

GAPは、まだNordicのプラグインでは出力してくれないようだ。
今のところ、プラグインではServiceの出力だけになっている。
これだけやってくれるだけでも非常に助かるのだが。

気にしていたbluetooth_init()は、ちゃんと生成してくれていた。
よかったよかった。
ただ、イベントハンドラも生成しているので、「触らないでね」というタイプの自動生成ではなく、「作ったからあとはよろしく」というタイプのようだ。
間違って上書きしてしまうのさえ避ければ、よいだろう。

 

以前issueにあげた不具合は直っているようだった。
クローズしようとしたが、特にそういう欄はないようだったので、放置しておこう。


プラグインで生成したServiceを見たところ、UUIDの設定方法が変更になっていた。

以前

    ble_uuid128_t bds_base_uuid = {{0xEF, 0xE8, 0xC7, 0x87, 0xF7, 0x70, 0x43, 0x92, 0x1E, 0x47, 0xD1, 0x7C, 0x00, 0x00, 0x40, 0x40}};
    uint8_t       uuid_type;
    err_code = sd_ble_uuid_vs_add(&bds_base_uuid, &uuid_type);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    ble_uuid.type = uuid_type;
    ble_uuid.uuid = 0xE9EB;

今回

    BLE_UUID_BLE_ASSIGN(ble_uuid, 0x4040E9EB7CD1471E924370F787C7E8EF);

こんなに大きい数字を直接扱えるの?

#define BLE_UUID_BLE_ASSIGN(instance, value) do {\
            instance.type = BLE_UUID_TYPE_BLE; \
            instance.uuid = value;} while(0)

nRF51 SDKのドキュメントを見ると、BLE_UUID_TYPE_BLEは16bitを意味しているらしい。
念のためInfocenterも見てみたが、同じだ。

../../../services/ble_adconvert_service.c:135:69: error: integer constant is too large for its type [-Werror]
     BLE_UUID_BLE_ASSIGN(ble_uuid, 0x4040E9EB7CD1471E924370F787C7E8EF);

だよねぇ・・・。
UUIDをshortの状態でプロジェクトを保存せんといかんのか?

うん、そうみたいだ。
前のプロジェクトそのままだったせいかもしれないが、一度128bitにして、また16bitにしてやるとうまくいった。
あせったわぁ。

2015/10/21

[rpi]Raspberry Pi2もやってきた

image

最初に写真を置くと、それっぽいページに見えそうな気がするのでやってみた。

きょうはBLE Nanoも届いたのだが、一緒に頼んでいたRaspberry Pi2も来た。
なんか、勢いで買ってしまった気はする。

初代は初代でよかったのだけど、何かの記事を読んでPi2でしかできないものを見つけたんだろう。
私はそういう人だ。

来月から自宅勤務になるので、慣れればそういうのをやる時間も以前より作りやすくなるだろう。
なんでもかんでもはできないけど、少しずつですな。

[nrf51]BLE Nanoがやってきた

うちに、BLE Nanoがやってきた。
いつものように、スイッチサイエンスさんから購入。
RedBearLab BLE Nanoキット--在庫限り

image

小さい!
下にあるCR2032の電池ホルダーに載っかる小ささ。
でも、2.54mmのピンがつくので、私でも扱えそうだ。

下にあるUSBのついたやつは、MK20というもので、これを使って焼くこともできるらしい。
mbedにもなるようなので、たぶんPCに挿すとFAT12か何かで見えるのだろう。
MK20側のDCLKとDIOが、Nano側のSWCLKとSWDIOにつながっているから、ここで焼くのだろう。
MK20DチップのSPIOピンとつながっているようだから、SPIでやっているのかな?

 

BLE Nanoへの電源供給は、VINとVDDがある。
VDDはそのままnRF51822というかMDBT40に入っていくが、VINは一度レギュレータ(という呼び名でいいのかな?)を通して3.3VになってからMDBT40に入っていく。
このレギュレータは3.3V~13Vまで許容しているので、USBからの電圧をそのまま入れることができる。
ということを、さっきブレッドボード用電源ボード3.3Vのハンダ付けが終わってから知りました。
VDDとレギュレータの方がVINよりも近いので念のためにテスタで導通を見たが、あってる。


実物を見て気付いたが、ピンをハンダ付けするのがもったいない。
せっかく小さいのだから、小さいまま使いたくなる。

image

無理やり、J-Linkとつなげた。
しかし、BLE Nanoとブレッドボードは力で穴とピンが接しているだけなので、不安定。
スルーホール用テストワイヤ TTW-200が便利、という意味がよくわかります。
写真に収まらなかったけど、J-LinkのSWD9ピンもけっこう無理している。CLKとIOが隣接していなければ。。

 

とりあえずつながったので、nRFgo Studioで見てみた。

image

QFAAなのはわかったが、最後の0x0057はHWID?
でも、Compatibility Matrix v2.1には0x0057というHWIDがないのだがなぁ。
nrfjprogで見てみたが、やはり0x0057だった。

A question about OpenOCD+nrf51822 [closed] - Nordic Developer Zone
この人も0x0057ってなに?という質問をしている。
回答は、HWIDはいろいろな要因で変わるから、ICリビジョンはNRF_FICRを見て、ということみたい。
components\libraries\ic_infoでうんぬん、といっているので、そこのソースを見ながらやってみよう。

>nrfjprog --memrd 0xf0000fe8 --n 4
0xF0000FE8: 0000004C

0x4C000000だけど、そもそも0xE010_0000以降はメモリマップではreservedなんだよなぁ。
Compatibility Matrixでは、QFAAの0x0072がRev.3らしいから、それより前ということでRev.2なのだろう。Build codeもGx0だしね。

[android]BLEのscanをしたらSecurityExceptionが起きた

前回の続き。
ようやくADTのプロジェクトをインポートできたので、実際に動かしてみる。
プロジェクトは、こちらで登録してダウンロードしたもの。
Bluetooth Smart Developers | Bluetooth Development Portal

立ち上げると、よくBLEであるようにSCANボタンがあるので、Advertisingさせた状態で押してみたが・・・何も出ない。
スニファではAdvertisingしているし、Androidの設定画面でも出てくる。
アプリに出てこないだけ。

やはりインポートしたやり方がよくなかったのかとadbログを見ると、なんかSecurityExceptionが起きている。

java.lang.SecurityException: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results

インポートしたら、そういうパーミッションも欠けてしまうものなのか。。
と思って検索すると、そう言うわけではなかった。
bluetooth - Android6.0(marshmallow)にOSをUpdateしたらアプリのBLE機能が動かなくなった時の対処方法 - Qiita
Android6.0になってかららしい。

BluetoothLeScanner
Android DeveloperのstartScan()を見ると、APIは21から追加されたらしい。
API21はAndroid5.0なので、当時からそうなっていそうな気がするのだが・・・。
Android 6.0 Changes | Android Developers
データ保護のために変更したらしい。

こういうのって、コンパイルエラーなりワーニングなり出てくれないと、気付かないよなぁ。
みんなどうやって気付いているんだろう?

 

ACCESS_FINE_LOCATION
すばらしいロケーション、ではなく、正確な位置情報、かな。
プロテクションレベルは「dangerous」。危険だ!

ACCESS_COARSE_LOCATION
おおよその位置情報、でよいのかな。
これも「dangerous」だ!

BLEのビーコンは、どっちになるんだろう?
位置といっても、ビーコンの付近ということしかわからないが、届く範囲は数メートルから数十メートルだから、その範囲にいることはわかってしまう。
近距離としてはおおよそなんだけど、遠距離としては正確な感じがする。
そういうわけで、COARSEの方をuses-permissionに追加。

そして焼き直してSCAN!
・・・あれ、同じExceptionが出る。
リビルドし直したが、変わらん。
わからん、わからんのだ・・・。

Androidの方でアプリ情報を見てみた。
ちゃんとビルドできているなら、位置情報うんぬんと書いてあるはずだ。
が、アプリ情報に「許可」という欄があり、そこには「権限が付与されていません」と出ている。
タップすると「位置情報」とあり、スイッチできるようになっていた。
今の状態は、オフ。
これをオンにしてSCANすると・・・出てきた。
ちゃんとAdvertisingしていた端末が出てきたのだ。
もちろん、Exceptionも発生していない。
2段構えだったのか・・・。

じゃあ、Android6.0にする前からインストールしているNordicのnRF Master Control Panelアプリなんかもスキャンできないのかと思ったら、これはできる。
アプリ情報を見ても、許可はしていないし、許可内容に「位置情報」がない。

つまり、API23でビルドしているから出てきた、ということなのかな。
まあ、許可内容をスイッチできるのはありがたいですな。

[android]Android Studio1.5βでADTをインポートして疲れた

あきらめて、AndroidでBLEアプリを作り始めよう。

ネットで検索したが、さすがスマホとあって、nRF51822とは比にならないくらいたくさん出てきた。
ここまで出てくると、一から作ろうという気がなくなってきますな。。
あと、iOSに比べると今ひとつらしいことがどの記事からもうかがえる。
みんなそう言っているので、そうなんだろうね。
iOSはやるつもりがないので、使うときになって考えよう。

 

Android5.0〜でBLEを使う(Central編) - vaguely

こちらの下の方に、Bluetooth Developerにもサンプルコードがあるとのこと。
せっかくなので、そちらを試してみよう。

Bluetooth Smart Developers | Bluetooth Development Portal

フォームに入力すると、ダウンロード先のメールが送られてきた。
今日(2015年10月)ではApplication_Accelerator_v1.0.1.zipだった。

image

今回はPDFを読まず、Androidを見る。
中はADTでできているので、Android Studioにインポートした。
android-18がないと怒られた。
いまさらインストールしたくないので、変更。
タイピングなどのメモ:Android StudioでAPIレベルを変更する - livedoor Blog(ブログ)
何も考えずに、API23にしておく。Nexus7で使いたくなったら、下げよう。

今度は「Gradle DSL method not found: 'android()'」と出てきた。
Solving the “gradle DSL method not found: android()” issue in Android Studio — Medium
なんかわからんけどbuild.gradleにandroidという関数ができるから、消せばよいよ、と。
確かに、あった。
消すと・・・またandroid-18がないと怒られた。
え-、これがだめなのー。

ではどうしたらよいのか・・・。
さっきはFlavorsタブで設定したので、違うところで試す。
PropertiesのCompile Sdk VersionをAPI23にする・・・またbuild.gradleにandroidができた。

image

Errorの括弧に書いてある数字は、build.gradleの行数なのだね。
それはともかく、設定を書くと、build.gradleファイルが更新されるようだ。
そして、Androidに関するものはandroidの中に書かれるのだろう。

めんどうなのでAPI18をインストールしたくなるが、時間があるので我慢だ。
もう一度エラーを見ると、リンクしてそうなのがあるではないか。
Open Gradle wrapper fileをクリックすると、ファイルが開かれた。

#Wed Apr 10 15:27:10 PDT 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip

こんなの見せられてもねぇ。
AndroidStudioでプロジェクトインポートしたときのsyncエラー - Qiita
こちらは、gradle-wrapper.propertiesが変だったというお話だ。
む、では前回ウィザード経由で作ったときのファイルを見てみよう。

#Mon Oct 19 10:07:13 JST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip

むむ、これか?ということで置き換えた。
が、まだエラーが出る。
出ているメッセージは同じなのだが、さっきはwrapperファイルへのリンクだったが、今度はGradle settingsへのリンクになった。

image

そのパスにファイルはあるんだけど・・・。
OKすると、Project JDKのnot specifiedだとか。
クリックすると、Project Structureのダイアログが出てきて、Project Settings>Projectが表示された。
たしかに、Project SDKが<No SDK>になってる。
これをAPI23にして、Try Againすると・・・またDSL android()が見つからないになった。
きー!

Import an Android project to Android Studio
build.gradleに、プラグインの設定を追加したらよかった、とのこと。
あ、確かにない。
ウィザードで作ったものは、ファイルの先頭に「apply plugin: 'com.android.application'」だったので、コピー。
おお、エラーが変わった。

今度は、buildToolsVersionが指定されていない、と。
リンクは出ていないが、慣れてきたので、File>Project Structureを選択。
やはり、あった。Propertiesタブだ。一番新しそうな22.0.1を選択。
OKすると・・・また「android-18」・・・。

 

腹が立ってきたので、プロジェクトのトップとsrcにあるbuild.gradleを、それぞれウィザードで作成したときのbuild.gradleとファイルごと置き換えた。
あれ・・・build.gradleって2つあるの??

 

もう一度、インポートからやり直そう。
まず、gradle/wrapper/gradle-wrapper.propertiesを編集。

次に、app/build.gradleを編集。
build.gradleはプロジェクトのトップとappの中にあり、android-18うんぬんは appにあるbuild.gradleなのだ。

image

ウィザードで作ったものとの差分はこんな感じ。

image

「android-18が無いからSDKをインストールせよ」じゃなくて、こっちのbuild.gradleへのリンクも示してほしかったな・・・。

これだけで、syncが成功した。
やれやれ・・・。


今回得たAndroid Studio対策は、

ウィザードで新規アプリを作り、その設定をまねせよ

でした。

[勉]OpenStack (2)

知らないことを調べるシリーズ。
昨日に引き続き、OpenStackだ。

前回調べて、あまり私には縁のなさそうな分野であることはわかったのだが、話しについて行くくらいの知識は持っておきたいものだ。


ゼロから始めるOpenStack (1) OpenStackの各コンポーネント | マイナビニュース

IaaSと呼ばれるようなサービスを自分で提供したいと思ったときに、どうやってそれを実現するかを考えないといけないが、その選択肢の1つとしてOpenStackがある。
オープンソースなので、提供元からの有償でのサポートはないけれども(サポートを有償で行う会社はあるのかもしれないが)、オープンソースならではのコミュニティなどで解決していくスタイルだろう。
「OpenStackディストリビューション」という言葉も出てきていたので、Linuxみたいにいろいろ特色を出しているのだろう。

「そこまでしなくても、AWSとか利用したらいいやん」と思ってしまうが、開かれていないシステムとして作りたい場合もあるのだろう。
「オンプレミス」というやつですか(いつも、オンプロミス、と間違ってしまうが)。
私のやってきた仕事では、そういうのが必要なことがなかったけれども、そういう環境もあるのかもしれない。


だめだ、自分でやることがないと思ってしまうと、ぜんぜん頭に入ってこない。
せっかく2日に分けたのだが、このくらいで終わらせてもらおう。

2015/10/20

[勉]OpenStack (1)

知らない言葉を勉強するシリーズ。
今回はOpenStack。


インタビュー&トーク - OpenStack Summit Tokyo、最新SDN技術に要注目:ITpro

このページの半分くらいまで読んだが、何の話かさっぱりわからない。。
SDN? IaaS?
言葉というか世界がわからなくて、読むことができん。


SDNとは|Software-Defined Networking - 意味/解説/説明/定義 : IT用語辞典
2013年に更新した記事。
いかん、用語説明すらさっぱりわからない。
ネットワーク機器の設定を集中管理するらしいが、なにがなんやら。
Windows Insider用語解説:Software-Defined Network(SDN)とは何か? - @IT
こちらも2013年。
図があったので、少しわかった。
まず、家でパソコンを使うようなレベルのネットワークじゃなくて、かなり大規模なネットワークの話だ。

会社ではネットワーク管理者がいて、パソコンを作業場に追加すると設定をお願いしないとネットにつながらなかった。
そういえば拠点の立ち上げ時は、わざわざ本社のネットワーク管理者が出張してやってきて、あれこれ設定をしていったなぁ。
そして、本社から拠点のネットワークを設定してくれていたけど、ああいう感じの話だろうか。


IaaSとは|HaaS|Infrastructure as a Service - 意味/解説/説明/定義 : IT用語辞典
2009年。こちらが、さっき書いた、遠隔のネットワーク管理者が設定をしてくれる話なのかな。
第1回 クラウドを再入門,クラウドとは何か?:雲を駆け抜けろ|gihyo.jp … 技術評論社
2011年。
「専用のサーバを仮想的に提供する」ということで、これが流行りの「AWSで必要なときだけサーバを追加して~」という話なのか。

私が自分でサーバを立ち上げるとなると、パソコン用意して、サーバ用OS入れて、ネットワークの設定して、セキュリティの設定して、あとはサーバとして必要なアプリをインストールするだろう。
でも「ネットワークの設定して」はかなり大変な感じがする。うちでやるときは接続する機器は数台しかないけど、インターネット上に置いて「みんなアクセスしてね」ってやると、人は来るわ、検索エンジンがクロール(でいいのかな?)しに来るわ、あやしい攻撃者が来るわで、負荷にも対応せんといかんし、安全にも対応せんといかん。
正直なところ、どうやってよいのかわからない。。。

そういうのを、サーバを立ち上げたい人から見ると、「SDN+Iaasでうまいことやってくれる」、ということなのかな。
AWSをよく聞くけど、読んだ感じではIaaSが表に見えていて、SDNは当然のもの、ということか。


この世界の巨人は、やはりAWSなのか。
どこもかしこも、比較対象としてAWSだし。
昨日、AndroidStudioを試したときにつながったGoogle Cloud Platformというやつも、実はIaaSのようだ。
第1回 Google Cloud Platformの概要:ソロソロ来るゾ! Google Cloud Platform!|gihyo.jp … 技術評論社

Google Cloud Platform を無料で試す
60日間で300ドル分を無料で試せるらしい。

IoT (モノのインターネット) | アマゾン ウェブ サービス(AWS 日本語)
こっちは1年間と長く、IoTの場合は毎月25万件のメッセージまで無料らしい。
「使ってもらわないとわからない」ということなのだろうが、いやあ、どこもすごいですな。

 

はっ!
肝心のOpenStackについて何も調べてなかった。
でも今日は週に2回の出勤日なので、ここまで。

2015/10/19

Visual Studio Codeは、今のところifdefがそのまま出る

タイトル通りだ。

うちのテキストエディタはEmEditorがメインなのだが、#ifなどに色つけできない。
秀丸エディタのように自分で有効なマクロ名を指定するのもよいが、#ifのところだけアウトライン化されるというのもありだと思う。
ともかく、何かしら見分けが付くのがありがたいのだが。

そういう思いで、Visual Studio Codeを試してみた。
このバージョンは、0.9.1だ。

image

残念。
将来はわからないけど、現状では特に何もなさそうだ。

まあ、C/C++の使用者も減ってきただろうし、#ifが入れ子になったらどうしようとか考え出すと、いっそのこと何もしない方が潔いのかもしれない。


ぱっと見て、こういうフォントもいいな、と思った。
私は普段、MSゴシック 9ptで使っているのだが、いいのがないかと探すこともある。
このフォントは、たぶんConsolasか。ちょっと太い気がするが、太字なのかフォントが大きいだけかわからん。

私の好みとしては、こんなのだ。

  • 等幅
  • 9ptくらいで使う
  • 半角と全角の比率が1:2
  • あまりぼやっとしていない

最後ので、だいたいビットマップフォントが選ばれ、だいたいMSゴシックに戻っていくのだった。
まあ、好みの問題だからね。

[android]久々にAndroid Studioを使う

最後にAndroidアプリをビルドしたのがいつだったのかすら思い出せない。
BLEのデータを貯めるアプリを作るため、久々に起動したら、新しいバージョンがあるとのこと。
前回が1.2くらいだったが、設定をβ版ありにしていたためか、バージョンアップするとこうなった。

image

Windowsで使っているのだが、ホームディレクトリに「.AndroidStudio」「..AndroidStudio1.2」「.AndroidStudioPreview1.5」となっている。
消してもよいのだろうが、今後もこういう感じで増えていくのだろうか・・・。


以前からそうだったのか忘れたが、右上にGoogleアカウントにログインする枠があった。

image

最初にログインしたときは、Google Cloud Platformのサイトに飛んだが、特にそういうのを使うつもりは無いのでスルー。


もともとAndroid Studioに慣れているわけではないので、あっさりと終わります。
あ、ウィザードで「スクロールなんとか」をActivityに選んだのですが、自動でこういうかっこよいアプリができていました。

image

BLEから送ってきたAD値をだらだらとログに出したいので選んだのだけど、よく考えると無限に追加できるわけでもないから、コンソールみたいに表示行数の上限を決めたようなViewがよいな。
そういう、自分に都合のよい出来合のViewを探したいのだけど、どう探したらよいかわからんというのが目下の悩みですな。

[勉]UWB

知らん言葉を調べるシリーズ。
そもそも「私が知らない言葉」なので、どこからそれを仕入れるかで煮詰まりつつある・・・。

今回は、UWB。


古川電工,26GHz帯を利用した障害物検出用UWB車載レーダーを開発 - クルマ - 日経テクノロジーオンライン

Wikipediaによると、Ultra Wide Band、の略らしい。
日本語だと「超広帯域無線」。
有線だと「ブロードバンド」という言葉があったが、あれの無線版だろうか。
WCDMAとかの速い通信は、Widebandだから、広帯域無線なのだろう。

基本的に、無線は1つの周波数で1つの通信しかできない。
だいたい、その通信で使える周波数の幅があり、その幅をチャネル単位で区切り、チャネル同士がぶつからないように気をつけるとか、同じチャネルだったら通信するタイミングがぶつからないように気をつけるとか、そういう配慮がいる。
だから、電波は共有財産だし、違法電波に厳しいのだ。

幅が広い=チャネルがたくさんある=チャネルを複数使って通信速度を上げる!、という構図かと思っていたのだが、下の記事を読むとそう簡単なことではないようだ。

あと、周波数が高いと距離が短くなるというか、エネルギーがたくさんいるから減衰が激しい、というのは世の常だ。
だから26GHzなんてどのくらい届くんだ?と心配になるが、30m以内とある。

 

UWB とは何だったのか(1)|Wireless・のおと|サイレックス・テクノロジー株式会社
UWB とは何だったのか(2)|Wireless・のおと|サイレックス・テクノロジー株式会社
UWB とは何だったのか(3)|Wireless・のおと|サイレックス・テクノロジー株式会社
UWB とは何だったのか(4)|Wireless・のおと|サイレックス・テクノロジー株式会社

過去形なのですが・・・。
記事は2013年と2年前なのだけど、なかなか面白い。
「そういえばWireless USBなんて話もあったなあ」と思い出してしまった。

これを読み終えてから気付いたのだが、最初のリンクは「レーダー」だ。
無線通信ではない!
ニュースの下にある関連リンクも、レーダーばかりだ。
やはり、UWBでの無線通信というのは過去形なのかもしれない。
「送信して反射波を受信する」だから、通信といえば通信なのかな。

 

エコー画像をやっていた経験からすると、周波数が高い方が分解能が高い。つまり、細かい。
超音波の場合には周波数と画像の深さ方向の正確さが直結する。
障害物の検知だったら、距離がはっきりわかりさえすればよいのかな?
準ミリ波帯パルスレーダ 「周辺監視レーダ」
同じ古河電工なのだが(あれ、日経テクノロジーの記事タイトルは「古川」になってる)、これはパルスドップラーで距離を測っているとのこと。
エコーも、血流の速度を調べるため赤血球にパルス波や連続波をあてて、それで速度を見るのだが、原理は同じ。
パルスを出し、そのパルスが戻ってくるまでの時間で距離を測る。
でも、電波って光速だから、そんなに時間の計測ができるほどの時間がかかるのだろうか・・・。
まあ、できるんだろうね。
だからこそ、これが成り立ってるのだろうし。

[android6]USB電源の使い道が選択できる

うちのNexus5が、Android6.0になった。
あんまり違いがわかってないが、デバッグ状態になったときに表示されるステータスバーのアイコンが鬼っぽくなった。

そのステータスバーを引きずり下ろすと、こういう通知が出ていた。

image

タップすると、選択できた。

image

デバイスとして認識しないと電源はやらん!みたいなOSのときに助かるのかな?
でも、デフォルト設定は前のままにしておいた方がよかったと思う。

そういえば、前の設定画面は残っているのかと見に行ったが、残っていなかった(「ストレージとUSB」のメニューで選択できていたような気がする)。

2015/10/18

[ai]『深層学習』を読む (7)

さて、caffeもちょっと動かしたので、深層学習を読み進めよう。
今回は6章の「畳み込みニューラルネット」だ。

ここは、他に比べると頭に入りやすかった。
学生の時にやっていた画像処理の内容に近かったためだ。
よく聞く「畳み込み」というのも、画像フィルタを適用するだけのことだった(計算的には「相関」と呼ぶようだ)。
こんなの。
http://ipr20.cs.ehime-u.ac.jp/column/gazo_syori/chapter5.html

「畳み込み層」では、フィルタした結果が元と同じサイズで、「プーリング層」は小さくなるのが主みたいだ。
どうやってプーリング層が小さくなるかというと、数画素ごとに読み飛ばすからで、これはアフィン変換で小さくするような感覚だ。

そういうのを何回か行い、学習パラメータが挟まることで画像のクラスタリングができるというのは、非常に不思議だ。
いや、実際にできているからそこを疑うわけではないのだが、勝手にそうなっていくのが面白い。
さすが機械学習だ。

 

さて、今のところまで読んだところでは、最後の出力はソフトマックス関数なので、入力をクラスタリングする装置として眺めていることになる。
いままで「どうやって分類させようか」と悩んでいたところが、ある程度まで切り離された感がある。
そこを1つの装置として眺めると、あとは「入力を何にするか」と「出力をどう使うか」になってくるか。

ネットで、研究段階でもいいので実用している例があるか探してみた。

まあ、クラスタリングするんだから、そういうものよねぇ。
内容としても「精度が上がった」みたいなのが多かった。

ディープラーニングはビジネスにどう使えるか? - WirelessWire News(ワイヤレスワイヤーニュース)
この辺を読むと、日本での情報が少ないだけかもなあ、とも思う。
では海外からの情報を読むか、となると、日本語で書かれた本ですら読んでわからないところがあるのに、英語となると・・・と尻込みしてしまう。

かといって、すでにできたものを使うとなるとアイデア勝負になって、あんまり私には向いていない。
なかなか新しい分野というのは難しいもんだ。

2015/10/17

[caffe?]lmdbでデータを見てみる

CaffeでDeep Learning つまずきやすいところを中心に
こちらを見ると、build/tools/convert_imageset.binを使うと学習画像やテスト画像をDBに取り込んでくれるらしい。
デフォルトのDBは、lmdbというもののようだ。
あれ、私は画像じゃなくて、他のをやりたいのだが・・・

というわけで、どういうデータを入れたらいいのか、mnistで取り込んだデータを見てみることにした。


$ sudo apt-get install lmdb-utils
$
mdb_stat examples/mnist/mnist_test_lmdb
Status of Main DB
  Tree depth: 3
  Branch pages: 13
  Leaf pages: 2500
  Overflow pages: 0
  Entries: 10000

ほう。

$ mdb-dump

ない、と怒られた。。。
こちらを見ると、「ppa:cz.nic-labs/knot-dnsがあるよ」ということだった。

PPAってなんだっけねぇ、と調べると、allaboutのページがあった。
私はxubuntuなので、メニューの「Settings > Software & Updates」で、"Other Software"タブを選び、Addした。
こういうのって、apt-get upgradeで何とかなるものだろうか?

$ sudo apt-get update
$ sudo apt-get upgrade
$ mdb_dump

おー、出てきた!

$ mdb_dump examples/mnist/mnist_test_lmdb
VERSION=3
format=bytevalue
type=btree
mapsize=1099511627776
maxreaders=126
db_pagesize=4096
HEADER=END
3030303030303030
0801101c181c229006.....002807
3030303030303031
0801101c181c229006.....002802

(中略)
DATA=END

データの部分の、1行目は連番で、2行目がデータのようだ。
データは、1byte2桁なので、795byteある。
画像は28x28=784。
ということは、795 - 784 = 11byteが付加データ。
こちらによると、MNISTのヘッダは16byteらしいので、それがそのまま載っているわけではない。
MNIST 手書き数字データを画像ファイルに変換する - y_uti のブログ

最初に付いている

0801101c181c22900600...

と、最後に付いている

...000280n

が付加データだろうが、さて、どこからどこまでなのか。
0x1c=28なので、画像のサイズなのだろうが、それだとあまりに画像データに特化しすぎてるよな。。。


あきらめて、検索した。
Caffe: Understanding expected lmdb datastructure for blobs - Stack Overflow

頭の9byteと、お尻の2byteが付加データだった。
データの並びは、caffe.protoのDatumを見ればよいらしい。

message Datum {
  optional int32 channels = 1;
  optional int32 height = 2;
  optional int32 width = 3;
  // the actual image data, in bytes
  optional bytes data = 4;
  optional int32 label = 5;
  // Optionally, the datum could also hold float data.
  repeated float float_data = 6;
  // If true data contains an encoded image that need to be decoded
  optional bool encoded = 7 [default = false];
}

(?_?
protobufの方を見てみよう。
encodingの説明を見てみると・・・

message Test1 {
  required int32 a = 1;
}

こういう設定で、「a=150」とすると、データはこうなるらしい。

08 96 01

へー。0x96 = 150なので、そこはわかるが、前後がわからん。

まず、7bit表現かつリトルエンディアン表現とのこと。
そしてMessageはkey-valueのペアになっていて、最初はkey。
keyは、 (field_number << 3) | wire_type)、という構成。

08
→ 0000_1000 (2進数)
000_1000 (7bit化)
field_number : 0001wire_type : 000

wire_typeが0なのは、表を見ると意味が「Varint」。
field_numberが1なのは、message Test1の「a」という意味。

96 01
→ 1001_0110 0000_0001 (2進数)
→ 001_0110 000_0001 (7bit化)
→ 000_0001 001_0110 (リトルエンディアン)
→ 1001_0110 (つなげた)
→ 0x96 (16進数)
→ 150 (10進数)

他にもルールがあるけど、ごめん、きつい。
あとは、もう、ここのヘッダだけ見ていこう。

0801101c181c229006.....280n

08 : key - field_number=1="channels", wire_type=0=varint型
01 : channels = 0x01
10 : key - field_number=2="height", wire_type=0=varint型
1c : height=28
18 : key - field_number=3="width", wire_type=0=varint型
1c : width=28
22 : key - field_number=4="data", wire_type=2=Length-delimited型
90 06 : Length=0x310=784byte

28 : key - field_number=5="label", wire_type=0=varint型
0n : label=n

データを見ると、頭の方は固定で、labelだけが変わっている。
ここでは、labelが手書き文字が表す数字なのだろう。
最初のリンクで「データセット用意」のクラスに当たるところが、labelになるのかな。


これを、音声や文章のようなストリーミングというか1次元のデータで扱いたいなら、高さか幅を1にして並べればよいのだろう。

でも、lenet_train_test.prototxtを見ても、データが2次元とか、高さとか幅とか、そういうのが見えてこないのよねぇ。
畳み込みニューラルネットって、「深層学習」を読むと2次元のマップに見立て、入力層の広さよりも中間層の広さの方が狭い、みたいな図になっているのだ。
狭いので、中間層の1つのユニットに、入力層のMxNのユニットが結合される、みたいなことになっている。
そういうのが、prototxtになさそうなのだ。

まあ、まだ畳み込みニューラルネットを読んでないので、先走りすぎたかな。