2016年1月11日月曜日

ESP-WROOM-02でSPI接続のADCから取得したデータをUDPで送出


緑のマイク基板と赤いESP基板の間にあるのがMCP3002。赤い基板上で右側のLEDがうすぼんやりと点灯しているのは、SPIのDIN信号。

50kspsでサンプリングしたデータをUDPに激しく送信中。

■SPI接続のADC■

ADCもいろいろありますが、数十Ksps以上のシリアルはSPI接続のものが多いです。

今回、MCP3002という精度10bit、入力2chのADCを使います。これは5v電源なら200kspsまで動き(2.7vだと75ksps)、そのわりに秋月で180円という大変おトクなチップです。マイクをつなげばお手頃な音声入力などが可能です。

SPIはあまり使ったことがないので、こちらの記事(ESP8266 (ESP-WROOM-02) でセンサーを扱う)を参考にさせていただきました。ありがとうございます。

SPIドライバはこちらからダウンロードします(MetalPhreak/ESP8266_SPI_Driver)。通常のArduinoライブラリとは形式が異なるので、以下の作業でArduino IDEが認識できるようにします(もっといい方法をご存知の方、ご教示いただければ幸いです)。

  • ダウンロードしたらzipを解凍する
  • フォルダの名前をESP8266_SPI_Driverに変更する
  • フォルダの中のspi_register.h, spi.h, spi.cをESP_SPI_Driver直下に移動
  • Arduinoのlibrariesフォルダ直下へ移動
  • Arduino IDEを再起動

動作させてみたところ、1回のデータ取得に要する時間は11-12μ秒程度でした(関数を100回呼び出して計測)。

■ESP-WROOM-02からUDP■

1回のデータ送信に要する時間は60-70m秒程度でした(関数呼び出し)。

■ESP用のソース■

なるべく一定の速度でサンプリングしつつ、UDPで送信しなければならないのですが、両者のスピードが違いすぎるので何らかのマルチタスクっぽい仕組みが必要です。Arduinoではこういう場合Tickerを使うのですが、Tickerは最小単位がミリ秒なので、1秒間に1000データしか取れません。それではせっかく高速のSPIを使う意味がありません。

幸いなことにESPにはos_timer_arm_usというμ秒単位のインターバルが用意されていますので、これを使います。なお、これを使う場合には、setupの始めの方でsystem_timer_reinit()を使って初期化し直す必要がありますので、ご注意を。これを使わないとミリ秒でしか動いてくれません。

ということで、おおまかな構成としては

  • 初期化ルーチンでWifi接続してから、20μ秒ごとのインターバルを開始
  • インターバルで呼ばれたらSPIからADCのデータを取り込みバッファにしまう
  • バッファが一杯になったらフラグを立てて別のバッファに切り替える
  • loop()ではバッファ一杯になったかどうかのフラグをチェックし、いっぱいになっていたらUDPでデータを送信します。



■検証用のJavaコード■

UDPでちゃんとデータを送り出せているのかを検証するために受信側のコードをJavaで作りました。UDPを受信して、連番と最小値/最大値などを表示するだけです。グラフ化したり音声を出力する根性がなかったので値だけです。

こちらの記事を参考にさせていただきました。ありがとうございます。
http://k-hiura.cocolog-nifty.com/blog/2011/07/java-6e01.html


■ハマりどころ■

  • 自家製ESPモジュールからIO15が出てない。IO15のプルダウン抵抗近くのviaホールにハンダ付けして引っ張り出す。
  • SPIが動かない。これは当初参考にしていた記事の配線図が間違っていたため。私の2時間を返せ。ということで著者さんには間違ってますよ、とメールしておいた。まだ直ってないなぁ。
  • 接続直後にESPが暴走する。あれさっきまで動いてたのに…?? と思ったら、初歩的なC言語的間違い。30年ぶりぐらいにやらかした。
      char **buf; buf[0] = ptr1; buf[1] = ptr2; 
  • ESPはos_timer_arm_usってAPIでマイクロ秒単位のTickerを使えるはずなのに、ミリ秒単位でしか動いてくれない。改めてSDKマニュアルを読んだら、system_timer_reinit()で初期化しないとダメよと書いてあった。
  • Javaの符号なし整数にまたハマってしまった。いい加減覚えろよ>俺

2016年1月10日日曜日

Energiaでお風呂時計(第二回)


■追記(2016/01/27)■

ついに電池切れました。前回充電したのは12/22だったので、35日ほど動いたことになります。プログラムを改善したのはこの1/10のことだったので、かなり改造が効いている様子です。ついでに、明暗の制御を少し改良しました。

■続き■

前回の「Energiaでお風呂時計」、動くことは動くんですが・・・「無印の化粧品ボックス+ジップロック+ブレッドボード」という見た目があまりにも悲惨なので「100均の瓶+ユニバーサルボード」ですっきり仕上げてみました。

最初、透明な蓋の弁当箱を探したんですが、吉祥寺の100均では見つからず。とりあえず「防水」「透明」「適当なサイズ」というところで食品保存用と思われるプラスチック+金属蓋の容器にしました。

蓋が金属だと影が出来てしまって動作が安定しないのではないか?という懸念はありましたが、いまいち透明度の低いジップロックのロスが想像以上に大きかったようで、「明暗判別」の値を2倍近くにしないと消灯してくれない状態でした。

ユニバーサル基板は、部品沼から出てきた20年物のSUNHAYATO製、150円の値札が貼ってありました。さすがにフラックスが劣化しているのか、ハンダの乗りが悪い悪い。

ボードのレイアウトは下からLED、センサー、CPUです。LEDが割と重いので、安定させるために&蓋の影にならず見やすい位置、センサーは蓋の影にならない場所に上下逆さまに、残ったところがCPU。

明暗センサーはブレイクアウトボードにヘッダピンをがっつりとハンダ付けしてしまったのでIC用の背の低いソケットには使えず、かといってヘッダソケットを使うとLEDよりも出っ張ってしまうのでアウト。ということでユニバーサルボードに直接ハンダ付けしました。100円を越える部品を直接ハンダ付けするのは心臓がドキドキしますw

セグメントの配線には電流制限用の抵抗100Ω☓7個入れました。1kΩでも1.5mAぐらい流れるのでスタティックなら十分明るいのですが、ダイナミック点灯だとさすがに暗くてダメ。試行錯誤の結果と手持ち抵抗により100Ωになりました。

■で、起動しない■

で、組み上がったところでGND/VCCがショートしていないか確認してから電池つないでも起動してくれません。

電源電圧もI2Cのプルアップも正常。何せI2C以外はみんなDigital Outputという単純な回路なので、疑うところは「CPUがちゃんと動いていない」ということぐらい。ごく簡単なLチカプログラムを動かしてみても信号が出てきません。

となるとリセットが原因です。

ブレッドボード上では何も配線しなくても動いていたのですが・・・2553で前にもあったなー。というわけで、47kΩでプルアップしたところ、動作するようになりました。推奨回路ではコンデンサでGNDとつなぐようにも書いてあるのですが(電源を入れた時にしばらくGND近くを保って、リセットさせるため)、まぁ動いているから省略w

■起動したけど■



…なんだこの表示はorz

よくみると、

  • 中央が点灯すべきところで下が点灯している
  • 下が点灯すべきところでドット点灯している

ということで、3本の配線が間違ってました。せっかくワイヤの長さを揃えてきれいに配線したのに台無しですorz


なお、ユニバーサル基板と電池ボックス(単4☓3本)の固定には輪ゴムを利用しました。

■プログラム■

前のバージョンとほとんど変わっていません。変えたのは、前記の通り明暗を判定する値を大きくしたことと、明暗によってLEDの明るさを決める関数の演算式、それに秒表示の時のゼロサプラスをやめたこと、の3点です。

■ユニバーサル基板■

昔はブレッドボードがなかったので、抵抗の値を試行錯誤で決めるのも面倒でした。

今回、アホな配線ミスはありましたが、ブレッドボードで決まった通りに配線するだけなので、昔と比べれば大分ラクになりました。

でも、私は基本的にソフト屋なので、何の痛みも伴わないundoに慣れきっています。ユニバーサル基板で配線しながら考えていたのは「基板設計する方がラクだな」ということでした。配線ミスの修正を含めて、ユニバーサル基板の作成にかかったのは3時間ほどでした。このぐらいの基板設計なら2時間ぐらいで終わりますし、届いた基板へのハンダ付けも1時間かかりません。

昔は自分で1日かけてエッチングするか、数万円だして業者に頼むしかなかったんですが、今はカード決済で送料込み2400円ですからねぇ・・・。

基板を起こせば2枚目以降はあっという間に作れますし。まぁ、大抵の場合は需要ないのでそのまま未使用基板が増えていくだけなんですけどもw

2016年1月8日金曜日

赤外線リモコンとLチカがあれば聴覚障害でもOK

私みたいに耳が悪いと何が不便って後ろで何が起こっているかわからないんですよね。「声をかける」というのが他人の注意を喚起する上で如何に有効なものであることか(詠嘆)。10mぐらい離れた人同士が会話しているのって、ほんと魔法みたいに見えます。

で、以前、赤外線リモコンのボタンを押すとLEDが点滅して誰かが呼んでいることを知らせてくれるデバイスを作りました。結構便利でした。

でもね、所詮はLED、仕事に夢中になっていると気づかないことも。

ということで、作りました。少し大きなリモコン付きのLチカを。


ビデオでは最大1wぐらいにおさえていますが、フル点灯30wの状態を直接見ると目が痛いです。

■材料■

プラットフォームはmbed、LPC1114FN28とLEDドライバと電源、それに赤外線受光器です。

以前、「普通の基板に表面実装パワーLEDを並べて何ワットぐらい点灯できるか?」を調べようとElecrowで起こした基板を引っ張りだしてきました。うーん、まだホームリフロー試行錯誤中だったので表面実装のハンダが汚いorz せっかく基板を作るのだからとファン駆動回路やPIR接続ピンなどインタフェースがてんこ盛りになっており、その1つとして「赤外線受光器インタフェース」も付いてます(実は基板見るまですっかり忘れてた)。よくある5v電源3ピンの赤外線受光器を挿すだけで使えます。なお、私が買ったものは5v電源を与えてもVoutが3vまでしか上がらないものだったので直結していますが製品や電源電圧によって異なります。買ってきたら出力電圧を確かめてもし3.3vを越えるようならば電源を3.3vにするか出力を抵抗で分圧してください。



手前の黒い直方体はDC/DCです。24vから3.3vまで落とすとさすがに通常の三端子レギュレータはかなり熱くなります。

LEDドライバはCL6807を3セット、電流検出用のシャント抵抗は0.1ΩなのでLED 7個ずつの各ストリングには1Aまで流せます。電源24vではVfの7倍にはちょっと足りないのですが、そこはマージン見越して動かしてます。なお、CL6807は秋月の「1000mA 可変定電流パワーLEDドライバーキット」にも使われています。このキット、我が家の洗面台の自動点灯LEDにも使っていますが、安定していて使いやすいです。ただし、マイコンから制御するためには多少の改造が必要です。CL6807はバラでも売ってますし、プリント基板を起こさなくてもSOT89-5用基板とSBD、シャント抵抗(0.1 - 1.0Ω)、4.7μFの積層セラミックコンデンサ、ユニバーサル基板があれば自作も可能です。なおメーカーの応用回路例には書いてないのですが、LEDへの出力の両端にパスコン(1μF)をつけると点灯が安定します。

なお基板の裏には放熱器を高品質グリースで貼り付けてありますが、これぞ焼け石に水。フルパワーにすると室温20度でも基板温度は50度を越えていきます。我ながら何をしたかったのかわからない基板です(笑)。

■ソフト■

AQ0802、IR Receiverなどのライブラリを使って、組み立てました。ループは1秒間に10回まわっていて、Lチカの基本周期となっています。リモコンの信号を受けると、「あと何回点滅させるか」という変数に値を代入します。その変数が偶数なら点灯、奇数なら消灯、という決まりにすることで、0.1秒ごとにペカペカ点滅します。これだと複数のLEDを逆相や追いかけるように点滅させるのがラクです。

2016年1月1日金曜日

Energiaでお風呂時計(第一回)

完成後、CPUもブレッドボード上へ移動

まぁ、またデジタル時計なんですけど。

使ったCPUはMSP430G2553ですが、開発環境はArduino互換なので、RTCを用意すれば簡単に移植することができます。ただ、nanoを使ったとしても消費電流を押さえるのはシンドいと思います。

■仕様■

  • 表示は4桁7セグメント赤色LED
  • お風呂なので電源は電池
  • 電池は1ヶ月ぐらいもたせたい
  • 時刻と入浴時間を交互に表示

■実装■

省電力で4桁の7セグを動かせる・・・ということで、CPUにはMSP430G2553を選びます。RTCは使わず、G2553に32768hzのXtalを追加して1秒ごとに割り込みを発生させて時計代わりにします。

さすがにLEDを常時点灯していては電池がもたないので、入浴時のみ表示するようにします。入浴中であることを検出するには、
  • 倒立スイッチ、風呂に入ったら時計を立てると点灯→一番簡単
  • PIRセンサーで人の動きを検出→簡単だけどお風呂のお湯で誤動作するかも?
  • 照度センサで明かりを付けたら動作開始
  • ドップラーレーダーで(ry
などいろいろ考えたのですが、ここはAPDS9930という照度・近接センサーを使います。ebayで「gesture sensor」って書いてあったのでAPDS9960みたいなことができるのかと思って買ったら単なる照度・近接センサーだった、というオチ。9960より劇的に安かったんですが、典型的な安物買いの銭失いでした。でも、寝かせて置くのももったいないので、使います。それに携帯電話用のデバイスなので、CDSなどで明るさを検知するよりも電力を消費しません(アナログの達人ならできるのかもしれないけど、動作時の消費電流250μA/待機時90μA,Sleep時2.2μAなんて回路を作るのは私にゃ無理)。

配線にはブレッドボードを使い、7セグLEDと電池ボックスは秋月です。

大きな声ではいえませんが、電流制限抵抗などは一切入れてません。Vf=1.8vの赤色LEDを使う場合には3.3v - 1.8v = 1.5v、5mAも流せば十分なので1.5 / 0.005 = 300Ωぐらいの抵抗をG2553とLEDのセグメント側の間に入れておくのが正しい使い方です。正しくない使い方をしているので「1」を表示している時と「8」を表示している時で明るさが異なってしまう(各桁を接続している端子に7セグメント分の電流が集中するので「8」のときは容量が足りなくなってしまう)のですが、まぁ自分用なので壊れなければOK。そのうちボード起こしたら抵抗入れるから、それまでがんばれG2553。

G2553への書き込みにはTIのLauchPadを使います。

ソフトはArduino互換のEnergia IDEを使って書きます。くれぐれもバージョン0101E0017と0101E0016は使わないようにお気をつけてください。

以下配線表。各セグメント7本と桁4本、電源、I2Cだけです。時計合わせはそのうち考えます。hourとminuteの間にコロンが点灯する表示器が欲しい(こないだaitendoで買ったら全品不良で点灯しなかった)。


MSP430G2553相手ピン備考
P1_47セグLED 11Seg A
P1_57Seg B
P2_04Seg C
P2_52Seg D
P2_21Seg E
P2_310Seg F
P2_45Seg G
P0_012Dig 1
P0_19Dig 2
P1_28Dig 3
P1_36Dig 4
P1_7APDS9930SDA
P1_6SCL
P2_6XTAL
P2_7XTAL


この他、電池の赤をブレッドボードの赤、黒をブレッドボードの青、G2553のVccとAPDS9930のVCCをブレッドボードの赤、G2553のGndとAPDS9930のGNDをブレッドボードの青、にそれぞれ接続します。


最初のバージョンは19日間動作しました(浴室使用時間は1日平均30分ぐらい)。LED駆動のデューティー比をかなり絞り込んだ現行バージョンは現在12日目ですが、さて。


■ハマり■

他のところに書いたネタもありますが:
  • 別のところ(Energia最新版でI2Cが動かない)に書いたけど最新のEnergiaを使ったらI2Cが動かなくなってしまった。2つ前のビルドをダウンロードしたら何事もなかったかのように動いた。うがあ。
  • 作業中にミスで電源逆接とG2553逆差しで2個トバしてしまった。
  • シリアルポートをGPIOでも使うとSerial.printなどを使った瞬間にリセットがかかる。まぁ当たり前なんですが……ライブラリの中のSerial.printで発症したために「ライブラリを呼ぶとフリーズする」という症状になり、ライブラリの問題か?と誤認してしまったために発見が遅れました。いやはや。
  • 明暗のスレッショルド設定にちょっと苦労しました。最終的にはセンサーからの値をLEDに表示させるプログラムを書いていろんんな向きで値を測定して閾値を決めました。やっぱ現場に行かんとダメやで。
  • 風呂場の明かりをつけているのに時計が消灯してしまうことがあって当初は上記閾値の問題かと思ったのですが、どうやらセンサーがLED電球の高速点滅の「滅」を拾ってしまうようで照明の明るさ/閾値設定とは関係なく発生します。なので、平均値を取るようにしました。ただ、センサーの値は1秒に1回サンプリングしており点灯時の明るさで500-700、消灯時の閾値が60という設定なので、LED電球を消灯してもすぐには時計が消えません。
  • ダイナミック点灯の合間にI2Cでセンサーを取りに行くと一瞬時計表示がチラついてしまいます。なので、時刻と入力時間を切り替えるときに読みに行くように変更しました。RTOS欲しい。
  • 照度に合わせてLEDの明るさを変えていますが、違いがわかりません。手で影を作ると少し暗くなるのでソレと判断できるのですが、あまり暗くすると消灯モードになっちゃいますし。

■ソース■

基本的には以前書いたデジタル時計の使い回しです。ArduinoでLEDのダイナミック点灯させるとだいたいこんな処理になっちゃいます。あと、APDS9930のライブラリはArduino用を使いました(APDS9930 Ambient Light and Proximity sensor)。

なんということもないダイナミック点灯プログラムなのですが、CPUのクロックを点灯中には8Mhz、消灯時には1Mhzに切り替えています。切り替えることでI2Cなどに影響がでないか心配だったのですが、問題ありません。1MhzだとG2553の消費電流は230μAで9930は220μA(スリープはさせていないが通信はごく低頻度なので消費電流はもっと低いはず)なので、まったくLEDを点灯させなければ2000時間程度は動くはずですが、点灯しない時計は意味がないので困ったものです。


2015年12月31日木曜日

ESP-WROOM-02のRTOSをMacOS X El Capitaionで動かす


■大まかな手順■


  • esp-open-sdkをビルド
  • esp-open-rtosをダウンロード

…これだけのことなんですが、MacOS X El Capitain固有の問題やら私の環境固有の問題で大ハマリしました。また、最初ESP8266-RTOS-SDKを試してみたのですが、サンプルのビルドすら通らずに挫折してesp-open-rtosに逃げたら、あっという間にマルチスレッドなLチカまで通って拍子抜け、という経緯がありました。

ということで、ハマりどころも含めてご紹介します。

なお、esp-open-sdkは、大文字小文字を区別するファイル・システムでないと動作しません。なので、Volumeを作ってその中で作業をします。そしてesp-open-rtosはesp-open-sdkがないとダメです。なので、再起動などでunmoutされた後に再度esp-open-rtosを使う場合には以下の手順で再度esp-open-rtosの入っているdmgファイルをマウントしなおす必要があります。

$ sudo hdiutil mount ~/Documents/case-sensitive.dmg
…「見つからない」というエラーが出ればすぐ気づくのですが、ビルドで別のエラーがでる、esptool.pyで書き込みしようとした時にうまくいかない…という直接関連なさそうなエラーが出るので、ちょっとハマりました。

あと、Homebrewが必要です。

■まずesp-open-sdkをビルド■


https://github.com/pfalcon/esp-open-sdk
このページの「Requirements and Dependencies / MacOS」を参考にesp-open-sdkが動く様にします。
$ brew tap homebrew/dupes
$ brew install binutils coreutils automake wget gawk libtool gperf gnu-sed --with-default-names grep
$ export PATH="/usr/local/opt/gnu-sed/libexec/gnubin:$PATH"
$ sudo hdiutil create ~/Documents/case-sensitive.dmg -volname "case-sensitive" -size 10g -fs "Case-sensitive HFS+"
$ sudo hdiutil mount ~/Documents/case-sensitive.dmg
$ cd /Volumes/case-sensitive
$ git clone --recursive https://github.com/pfalcon/esp-open-sdk.git$ make STANDALONE=y

Buildingでのgit cloneは当然問題ないのですが、その次のmakeでビルドが通りませんでした。なお、私はmake STANDALONE=yを選択しました。esp-open-rtosにはSTANDALONE=nを選べと書いてあるのですが(後で気付いた)、とりあえず問題なく使うことができました。

□ハマり1:じゃまな古いsed□

ビルド途中でエラーが出ました。sed -rオプションが使えない云々。調べるとmac標準のsedではなくgnu-sedを使えば解消できるとあるのですが、「Requirements and Dependencies / MacOS」でbrewと使って導入済み。かなり右往左往しましたが、結果として消し忘れていたMacPortsのsedが悪さをしていました。以下の手順に従ってMacPortsをアンインストールして、sed -rオプション云々のエラーは消えました。


□ハマり2:Xcode command line tools□

makeしているとこんなエラーがズラーっと出てとまります。
[INFO ]  Installing pass-2 core C compiler[ERROR]    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cstddef:46:9: error: no member named 'ptrdiff_t' in the global namespace
...
エラーメッセージの内容からXcodeのcommand line toolsが悪さをしているっぽい。対応策はここで見つけました。

私のところはXcode 6.3ではないですが、結果的には以下のスクリプトを実行することで解消できました。
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-blocking.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-clast-to-gimple.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-dependences.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-interchange.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-optimize-isl.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-poly.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-scop-detection.c
sed -i '1s/^/#include <stddef.h>\n/' crosstool-NG/.build/src/gcc-4.8.2/gcc/graphite-sese-to-poly.c
すぐに終わりますので、再度 make STANDALONE=y を実行します。私のところはこれで通りました。
Espressif ESP8266 SDK is installed, its libraries and headers are merged with the toolchain
このメッセージが出たら完了です。

なお、そのすぐ上にも書いてあるように、ツールを実行するためにパスを設定する必要があります。.bash_profileに追加しておきましょう。
export PATH=/Volumes/case-sensitive/esp-open-sdk/xtensa-lx106-elf/bin:$PATH



■esp-open-rtosの設定とサンプルの実行■

https://github.com/SuperHouse/esp-open-rtos

RTOS-SDKの大騒ぎと比べるとあっけないほど簡単です。まず、適当な作業用ディレクトリを作り、そこにesp-open-rtosをダウンロードします。
cd
mkdir esp
cd esp
git clone --recursive https://github.com/Superhouse/esp-open-rtos.git
cd esp-open-rtos

…はい、これだけです。

次に、自分のアプリをビルドする際のssidとpasswordを設定しておきます。1つのESP8266/ESP-WROOM-02だけで遊ぶには良いんですが、複数あるときはちょっと面倒ですが・・・include/ssid_config.hを開き、
#define WIFI_SSID "mywifissid"
#define WIFI_PASS "my secret password"
を自分のSSID/passwordに変更し、すぐ上にある#warningも消します。やらないとは思いますが、ここでcloneしたsdkに変更をしてpushする際に、自分のSSID/passwordを一緒にプッシュしないように気をつけなさいよ、というwarningです。

続いて、サンプルのビルドと実行ですが、そのまえにESP-WROOM-02をシリアルポートにつなぎ、PROGを押したままRESETを押し離し、PROGを離します。さらに2組のLEDと220-1kΩの抵抗を直列にして、GPIO 12とGPIO 13に接続します。次に、examples/blink_times/blink_timers.cを開き、
const int gpio_frc2 = 14;
を
const int gpio_frc2 = 13;
に変更します(他のGPIOを使う場合にはそれに合わせて変更してください)。

あとは、

make flash -j4 -C examples/blink_timers ESPPORT=/dev/<usbシリアルのポート>
を実行すれば、ビルドの後、自動的にESPに書き込まれ、二個のLEDが1/5秒周期と2秒周期で点滅します。ソースを見ればわかりますが、2個のLEDはそれぞれ別々のスレッドとして動作しています。

お疲れ様でした。ソースをXcodeなどのエディタで開いてしまえば、ビルド&ダウンロードはコマンド一発(ターミナルでは上向き↓を押してENTERを押すだけ)なので、Arduino IDEで使う場合とそう変わりはありません。これで本格的なマルチスレッドが手に入るのだから、苦労も報われるというものです。



■余談:ESP8266-RTOS-SDKをビルドする際のハマり■

ビルドはできたものの、サンプル中の「GPIO_OUTPUTが見つからない」というエラーを解消できずに挫折というか諦めました。ただ、そこまで行くのにかなり苦労したので、一応記録を残しておきます。

ESP8266_RTOS_SDK

まず、esp-open-sdkをセットアップするのはesp-open-rtosと同じです。

次に適当なディレクトリを作ってそのなかに移動してから
$git clone https://github.com/espressif/ESP8266_RTOS_SDK.git
でSDKをダウンロードします。つぎに、gen_misc.shを開き、SDK_PATHは書いてあるとおりRTOSの場所、BIN_PATHはビルドしたバイナリを置く場所を指定します。

BIN_PATHに指定したディレクトリはビルド前に作っておかないとエラーになります。指定したディレクトリにバイナリが入るので、そこからesptool.pyなどを起動すると何かとラクですね。

さて、ビルドを始めると、
.out section `.irom0.text' will not fit in region `irom0_0_seg'
で止まってしまいます。

回避策はRTOS_SDK V1.3 do not fit my code any moreで見つけました。ESP8266_RTOS_SDK/ld/eagle.app.v6.ldってファイルを開き、MEMORYってブロックを記事の末尾にある
MEMORY
{
  dport0_0_seg :                        org = 0x3FF00000, len = 0x10
  dram0_0_seg :                         org = 0x3FFE8000, len = 0x14000
  iram1_0_seg :                         org = 0x40100000, len = 0x8000
  irom0_0_seg :                         org = 0x40210000, len = 0x7C000
}
で置き換えるとビルド通ります。お疲れ様でした。

2015年12月30日水曜日

ホームリフロー入門はサンハヤトのハンダクリームに限るっ


■追記2018-03-22■

これはあまり初期費用をかけないで表面実装部品をきれいに実装しよう!という方向けの記事です。その後、0.5mmピッチのICやコネクタを扱うようになり作る枚数も多くなったので、ステンシルプリンターとリフロー炉を導入しました。

ただ、「1mm以上の部品をさくっと実装して試してみたい」というような状況では、今でもサンハヤトのシリンジ入りハンダクリームを愛用しています。50gぐらい入ったボトル欲しいです>サンハヤトさん

■ホームリフロー■

いきなりアフィリでも狙ってんの?ってタイトルで恐縮ですが、ホームリフローを始めて18ヶ月にして初めて購入したサンハヤト「表面実装部品取付キット SMX-21」を使ってみました。

最短時間で不良ゼロ

でした。マチ針を使って「うまく塗れない」と言っていたあの日。マンガ「ハルロック」から得た知識でマイナスドライバーを使ってうまく塗れるようになって歩留まり向上したあの時。そして購入後18ヶ月を経過してさすがに品質低下してはんだボールだらけになり「ダメだこりゃ」と気付いた朝。ついにさようならです。

白い箱の中身


■注意事項■

箱を開けると「表面実装部品取り付けキット 特殊クリームハンダをお使いになるまえに」という注意書きが入ってます(フラック成分が固まってピストンが動きにくくなっていることがある云々)。私のはそれほどではないものの少し固くなっていたので、記載通りの処置をして問題なく使えました。とはいえ、最初使う時にはどのぐらいの力で押したら出てくるのかわからないので、ティッシュなどを用意するか比較的面積の広いパッドを標的にするのが良いかと思います。

クリームハンダは冷蔵庫で保存する必要があります。作業の1-2時間前に冷蔵庫から出しておきましょう。ただ、室温に戻ったとはいえ手の温度よりは冷えてます。冷えたものを暖めると当然熱膨張します。そのため、ふと気が付くと5mmぐらいハンダが出ていることがあるので、作業は手早く行い中断する場合にはティッシュなどの上に置きましょう。ただ瓶に入っているものと違い、瓶からスプーンですくい取るという作業がないので、中断せずにずっと拡大鏡の視野の中で作業し続けることができると思います。

あと念のためですが、キットには接着剤が付属しています。これでチップを固定するとハンダ付け作業が楽になるのですが・・・この接着剤はリフローには対応していません。あくまで手ハンダ用の接着剤なのでお間違えなく。

■塗布■

もう簡単です。拡大鏡をみながら注射器でプチプチと粘り気のある灰色のクリームを置いていくだけです。クリームはかなり粘り気が強くパッドに触れるだけで付着してくれるのでサクサク進みます。ESP-WROOM-02は底面に接点があるのでブリッジしないか心配になったのですが、パッドを無視して一列にブチューっと流し込んだだけです。ただ、チップを押し付けると表面張力が悪い方に作用してしまうと思い、そっと乗せるだけにしました。溶けた時にレジストがハンダをはじいてくれるはず。いずれにせよブリッジのリスクは高くなるので、積極的にはオススメはしません。「一列なおもて動作す。いわんや1パッドごとに置いておや」って感じ(違

チップ部品に関しては、2012なら楽勝でハンダを置きにいけます。

というわけで塗り終わったのがこちらです。


率直に言って汚い。慣れてないからしょうがないねっ

ご覧のように、ちょっと多すぎですね・・・チップ抵抗などはたぶんこの半分ぐらいでいいかと思います。拡大鏡で見ながら作業していると立体感がなくてどのぐらい盛っているのかわからないのと、ハンダのノリがいいのでついつい多めに出してしまいました・・・。なお、写真のタイムスタンプによれば、開封写真の最後〜塗布完了写真の最初まで約15分でした。前回マイナスドライバーで同じ基板に塗った時には30分程度かかっていたと思うので、大幅な時間短縮です。

さて、部品を置いていきます。アル中気味の私ですが、チップ部品を置くときでも手が震えないのでまだ大丈夫かなと安心する一時です。


もうはみ出しまくりだし、ESPの下など本当に不安になってしまう状態ですが、ともかくやってみます。

リフロー工程は

  1. ホットプレートにフタをして150度ぐらいに温めておく
  2. 基板をそっと乗せて、1-2分ほど余熱する。この時、温度を確認するために蓋を開けなければいけないですが、温度はそれほどシビアに考えなくても良いと思います。1-2分と幅がありますが、余熱することが目的なので基板表面が140-150度ぐらいになったらOKではないかと。
  3. 加熱開始、ホットプレートの表面が250度を越えないように注意しつつ、じっと見ていると基板表面が180度を超えたぐらいのところでハンダがキラッと溶けます。そのままホットプレートの温度を保ち、基板表面が210-220度ぐらいになったところで加熱をやめます。
  4. あとは全力でうちわ等で扇いで冷まします。基板表面が150度ぐらいまで冷えればもう触れたり落としても部品が動いたりすることはないので、ピンセットでステンレス流し台などに置いて冷まします。


…あ、リフロー完了直後の写真がない。



というわけで、スイッチやピンソケットなどてハンダ部品取り付け後の写真しかありませんが、こんな感じに仕上がりました。R10のあたりはクリームハンダが盛大にはみ出していたのですが、大きなはんだボールが2個あっただけで、フラックスクリーナーで簡単に除去できました。抵抗などかなりの大盛りですね。ESPについては「ここは少し多いな」というところ(下の写真左下端)は大盛りになっていますが、それ以外のところはきれいに溶け込んでいます。

さて、あとはチップの下でショートしていないかを通電前にテスターで確認をします。
  • VinとGnd、3v3とGnd、Vinと3v3間がショートしていないか
  • ESPの全ピンの接続とブリッジ確認
    • テスターでパッドとその端子が導通しているかを確認
    • 隣のピンとショートしていないかを確認
  • 抵抗、コンデンサ、LEDなどが正しい値を示しているか確認
    • 回路によっては必ずしも表示値と同じにならないので、他の部品との並直列などに考慮する必要はあります。

なお、電源の入力側と出力側の抵抗値を測って記録しておくと、次に同じものを作るときの参考になります。

冒頭書いた通り、ハンダ不良ゼロで一発で動きました。いえー。

■ハンダをしまうときのtips■

シリンジを少し引いてからジップ袋にしまいましょう。発生するガスや熱膨張に起因するキャップの内側にハンダクリームが漏れて固まる現象を軽減できます(と経験者は語るorz)。でもシリンジ引くと空気を吸って酸化が早まるような気もしますし…どっちが優先するかは今後の課題とさせていただきます。

追記(2016-01-31):注射針(ニードル)は、使った後1-2週間で詰まりますね。試しに交換しないで置いたら、2週間後は固いけど少し水っぽい、4週間たつと渾身の力を込めるとごく少量出てくるレベルで、まったく使えません。2週間後に水っぽくなったのは、固まりかけたものがフィルタみたいな状態になり、フラックスだけがにじみ出てきてしまったせいだと思います。

注射針はキットには5本しか入っていないし少し太いかなと思うので、ebay.comなどで安い工作用の注射針をまとめて買っておくと便利です(送料無料で500円ぐらい)。
SMT SMD PCB Solder Paste Adhesive Glue Liquid Dispenser+Dispensing Needle(50pcs)

5本ずつ10種類も入っているので、細すぎるのと太すぎるのが余ってしまうのが悩みです。国内だとインクジェットプリンタのインク入れ替え用に売られているものが入手しやすいようです。

いずれにしても、使い終わったら注射針をつけたままにしておいて、その次に使用するときにはまず針を変えてから作業するのが良いです。ご参考まで。

2015年12月29日火曜日

ESPにつないだRGB LEDをブラウザから制御する


■WiFi制御Lチカ■

ESPからサーバへデータを送信するのは何度かやったのですが、そういえばブラウザなどからESPを制御する、というのはやっていなかったので試してみました。

上の動画では、

  1. http://server/?w=4
  2. http://server/?r=1023&g=1023&b=1023
  3. http://server/?r=1023&g=0&b=0
  4. http://server/?r=0&g=1023
  5. http://server/?w
  6. http://server/?r=0&g=0&b=1023

の順番で操作しています。1.明滅指定、2.全色全点灯、3.青のみ明滅、4.緑のみ明滅、5. 明滅をストップ、6.青のみ点灯、という制御です。

こういうのをゼロから作るのはシンドいので、まず土台になりそうなプログラムをESP8266サンプルの中から探すと「HelloServer」というのが見つかりました。

これは、ブラウザから「/」または「/inline」でアクセスするとそれぞれ異なるメッセージが返ってきて、それ以外だとnot foundとともにargが表示される、というものです。必要なのはパスとargなので、これを使います。

■仕様と解説■

単にLEDを点滅させるだけじゃつまらないので、

  • RGB LEDを接続する
  • 各色ごとに明るさを変える r=100&g=200&b=300 って感じで
  • w=<n>と指定するとn mSec×256周期で滑らかに明滅する。ただしその時に設定されている各色の値がピークの明るさになる。

って仕様にしてみました。明るさを調節するにはanalogWriteでPWMを使い、それを滑らかに変化させるためにTickerを使います。

analogWriteは指定したGPIOに対して約500hzのPWM出力をします。値として0-1023を指定することができますが、値/1023の比率でonになっている時間が長くなります。0を指定すればずっとoff、512なら約50%、1023ならonのまま、ってことです。

Tickerは指定した秒数ごとに指定した関数を呼び出してくれます。attachで有効になり、detachで無効になります。今回のプログラムではsetupであらかじめサインカーブを描くテーブルisinを作っておき、設定したミリ秒数毎にテーブルの値を出力することで滑らかに明るさを変化しています。実際にその処理をおこなっているのはwaveHandlerです。waveHandlerではwaveCountで示されるisinの値を各色ごとの直近の明るさ比率(gRGB)に補正して、RGBごとに位相を120度ずつずらして(i*MaxSinTable/3)出力しています。一個出力したらwaveCountに1を足して次の値を準備します。

ブラウザからのコマンドを受け付けるのはhandleRootです。最初の例で示したように引数は同時に複数指定することができます。何個引数があるかはserver.args()で知ることができるので、これでforループを回します。そして、「引数名=値」の形式の引数名に相当するargName(i)の最初の1文字だけを取り出し、値をarg(i)から取り出します。そして引数名として指定されたのがr, g, bならばそれぞれの明るさをセットし、wならば値をミリ秒単位の割り込み周期としてattachかdetachを実行します。wはトグル動作つまり呼ばれるごとにon/offを切り替えるので、tickerAttachedというフラグを用意して切り替えます。

サーバのルートが呼ばれたらhandleRootを呼び出すということは、setup()の中で
server.on("/", handleRoot);
と指定しています。

…楽だわー。Play! Framework並にラクだわー(すいません、仕事でstruts2などという化石の干物を腐らせたようなライブラリを相手にしているので、つい愚痴が)。

なお、handleNotFoundはサンプルのままです。ブラウザから例えば
http:<server>/foo?tare=panda
と呼び出すと、画面上には
File Not Found

URI: /foo
Method: GET
Arguments: 1
 tare: panda

という表示が返ってきてソースと見比べながら引数などをどういう具合いに扱われるかがよくわかります。

また、setup()では
  server.on("/inline", [](){
    server.send(200, "text/plain", "this works as well");
  });
という記述もあります。この [ ]( ) { } は無名の関数で、別のところにhandler関数を書くかわりにここで簡単な処理をチャッチャと記述してしまうことができます。サンプルのように単純なテキストメッセージを返すならこれで十分ですね。

■ハードウェア■

素のESP-WROOM-02は配線が面倒くさいので、今回は自家製のESP基板を使いました。FTDIとRGB LEDを接続するだけなので素晴らしく簡単です。電源にも良い部品を使っているので動作も安定しています(だれも褒めてくれないので自分だけは自分に優しくしよう)。



ESPでのお約束なプルダウン / プルアップ抵抗などの他には、RGB LEDを接続するだけです。

RGB LEDは秋月の「RGBフルカラーLED 5mm4本足 OSTA5131」です。BlueとGreenのLEDは3.6v以上の電圧かけないと光らないのが建前なんですが、実際には3.3vでも結構明るく点灯しちゃうんですよね。なお、GPIOと直結するのはまずいので、220オームの抵抗を直列に入れてます。また、このRGB LEDはカソードコモンといってマイナスにつなぐ側が共通になっています。GNDと接続してください。その辺、ブレッドボードでつくると妙にでかくなってしまうので、aitendoのユニバーサル基板で作りました。
ああハンダ付けは楽しいw


■はまりどころ■

今回はなかった、と言いたかったんですが、実は解決できていない問題が1つ。このプログラムを起動して r=200&g=200&b=200&w=8 と暗め and ゆっくり目で動かしていると時々「パッ」と明るくなります。WiFiに関する機能を取り除いても起こりますが、明滅させないでいると起こりません。

明滅時にはanalogWrite命令で頻繁にPWMの出力幅を変えているのですが、実行のタイミングが悪いとHIGHがしばらく続いてしまうのではないかと思います。同じような現象はmbed / LPC1114FN28でも経験していて、この時はPWMの周波数を高くすることで回避できたのですが、Arduino IDE環境ではPWMの周波数を簡単には変更できないのでさてどーしたもんかしら。

■ソース■

というわけで、ソースです。

2015年12月27日日曜日

クリームハンダの寿命

リフロー用のハンダ、クリームハンダには寿命があります。微細なハンダ粒とフラックスからできているので、フラックスの影響でハンダが酸化したりフラックス自体の活性が低下するのが原因だそうで、物によりますが大体数ヶ月の消費期限が設定されています。

さて、我が家のクリームハンダ、買ってから18か月が経過しました。

さすがにダメな仕上がりです。



何かよくない微生物でも増殖しちゃったんじゃないか?というレベルでタチの悪そうなハンダボールが多発していて、買ってきた頃と比較すると明らかに状態が悪化しています。何より、今回の基板はリフローしただけでは動かず、溶剤で基板を洗ってハンダボールを除去した後ハンダゴテで補修してようやく動きました。リフローした意味がないw

徐々に悪化したのであまり気にしていなかったのですが、振り返ってみると健全に使えたのは購入後半年ぐらいだったかなと思います。

安いものならebayで送料無料の数百円(ビンに入ったペースト)から、高品質だけど高いサンハヤト製品でも1300円(注射針なしのシリンジ入りハンダのみ)〜3000円(ハンダ入りシリンジ、注射針、吸取り網、固定用接着剤などのセット)で買えるものなので、今後は3-6か月ぐらいで新しいのに交換していこうと思います。

なお、サンハヤトの「表面実装部品取り付けキット SMX-21(共晶ハンダ) / SMX-51(鉛フリー)」「特殊クリームハンダ SMX-H05(共晶ハンダ) / SMX-B05(鉛フリー)」は、門田無線さんで買うと便利です。通販ならクール宅急便で届きますし、あらかじめ連絡して代金を振り込めば取り寄せして店頭で入手することもできます(消費期限のある商品なので、お店にご迷惑をおかけしないようにしましょう)。

廃棄方法はお住いの自治体の指定に従ってください。

2015年12月26日土曜日

ElecrowにPCB Assemblyを頼んでみた


基板だけなら今までにも何度かElecrowに発注したことあるのですが、今度は部品実装まで頼んでみました。

大まかな手順は以下の通り。
  1. 何はともあれ回路・基板を設計する
  2. PCB Assembly注文ページのリンクから、まず先方に連絡を入れる。
  3. 担当者がアサインされてメールが届くので、その指示に従い、ガーバー、部品リストなどを送って見積もりを出してもらう。部品リスト(BOM)は、以下のように分けて記載します。記入例はElecrowパーツリストライブラリのExcelファイルに同梱(別シート)されています。
    • Elecrowの部品リストに掲載されているもの
    • Digi-key / Mouserなどから入手可能なもの
    • 日本から送るもの
  4. 先方から見積もりが届く。今回、10個,50個,100個で見積もってもらいました。
  5. OKなら、PCB Assemblyのページから支払いをする。PCB Assemblyは単価$1なので、金額分の数量($100なら100個、分かりやすい)を注文する。
  6. 日本から送る部品があるならば、とっとと送る。
  7. 到着を待つ
こんな感じです。最初に連絡を入れてから1日かかりませんでした。注文には最低数量の制限はありません。また、パーツを基板の上に乗せるためのparts mappingを用意する方法がわからなかったので質問してみたのですが、特に何も言われませんでした。

今回お願いしたのは5x5cmほどの両面基板10枚、主要なパーツは日本から送り、RCとLEDを先方のパーツリストから選んで全部ひっくるめて$80でした。とても安いです。

さて、秋月で部品を買ってこなくちゃ。届いたら、また報告します。

■追記(12/30)■

中国への部品発送にはEMSを使いました。通常の発送伝票の他にInvoiceの記入が必要です。なおシンセンへの送料は秋月箱300g以下で900円でした。ご参考まで。

■追記(2016年)■

10日ほどで届きました! 仕上がりは大変キレイです。プリントの掠れもズレもなく、ハンダは輝き1つずつ静電気防止袋に収まって届きました。

で、その後何回か注文しましたが、シルク印刷については当たり外れがあるようです。

グリーンのレジスト+1.6mm厚については、今まで外れたことがありません。しかし、それ以外の色については、ズレたり掠れたりすることがあります。Elecrowは緑以外を指定しても追加料金を取られないのですが、やはり緑1.6mmが一番安定しているかもしれません。

赤や1.6mm以外の基板を指定する場合には、少し割高になりますがpremier PCBを指定することができます。割高といっても100枚作って20% upって感じです。premierだと24milの文字でも潰れずにプリントされます。

あと、ガーバーとBOM(パーツリスト)はくれぐれも正確に。間違えていた場合でも先方から「これはどうなってんの?」と問い合わせが来ることはなく、そのまま生産されてしまいます。

なので、初めての場合はまず最初に少量生産してもらって様子を見る方が安全です。例えば基板を100枚注文して部品を100個発送しておき、「最初に10個だけ作って日本に送ってくれ。よければ残りの90個も生産」というオーダーも可能です(最初に基板100枚分と製造費10セット分を支払う。OKなら90セット分の製造費を支払う)。もちろん、その場合の製造手数料($10)と送料($15〜)は2回分になりますが、そこは部品をパーにするリスクと天秤にかけてご検討ください。

そんなこんなで、premier PCB + PCB Assemblyで注文したモジュール、スイッチサイエンス様から絶賛発売中です :-)


2015年12月23日水曜日

Energia最新版でI2Cが動かない



Energiaの最新版Energia 0101E0017(と一つ前のEnergia 0101E0016)では、MSP430G2553にてI2Cがうまく動いてくれません。

厳密に信号レベルで見たわけではないのですが、他のデバイスあるいはEnergia 0101E0015で動いていたライブラリ等が動作しません。

回避方法は、とりあえずEnergia 0101E0015に戻せば動きます。はい。

・・・これで休日の貴重な2時間を潰してしまったじゃないかorz

I2C of MSP430G2553 is not working on Energia 0101E0016 and 0101E0017. if you got same problem, please install Energia 0101E0015.