2016年4月24日日曜日

WiFiワイヤレスオーディオ(失敗)

送信側

受信側。手前の補聴器1個15万円ナリ

■やりたいこと■

赤外線ヘッドフォンアダプタが壊れました。私は耳が悪いので、これがないとテレビが見られません。アニメ見られないのは死活問題ですw ただ、最近市販されているワイヤレスヘッドフォンは音量が低すぎてほぼ聞こえません。特にBluetoothものは出力が小さくて先日ヨドバシで試聴してみたのですが、全滅でした。なんせ私はiPhone+標準添付のイヤホンだと最大音量にしても音楽ほぼ聞こえないんです。やぁねぇ、難聴orz

ということで、ESP-WROOM-02を使ってライン入力した音声信号をWiFiで飛ばし、受信側もESP-WROOM-02を使って受けたデータをDACで出力しそれなりに増幅してヘッドフォンへ…ということを試してみました。ラズパイなら簡単なんですが首からラズパイぶら下げるわけにもいきませんしw

ESP内蔵のADCはあまりにも貧弱なのでMCP3204、DACはMCP4922を使いました。どっちも秋月で入手できます。アンプとしてはポタアン用オペアンプを試してみて、音量が出ないようなら適当なパワーアンプを使ってみようと思ってます。

…とスタートしたのですが。

■先に結論■

今のところ、意図したようには動いていません。ADC/DACからのやり取りとESP-NOWまたはUDPでの通信はそれぞれはちゃんと動いているのですが、一緒にするとデータが欠落してしまいます。

サインカーブを送信して受信側の信号をイヤホンで聞いていると、基本的には連続音がずーっと聞こえていて、数秒ごとにバタバタとノイズが入り、ときたまプチっと100mSecぐらい空白ができる…という感じです。HiFiはまったく期待していなかったのですが、ノイズはいかんです。

ADC/DACを扱うためのインターバルがESP-NOW/UDPの送受信処理によってブロックされているようです。FIFOバッファを持ったADC/DACでないと無理かなぁ。

当初の目標に関しては失敗なのですが、とりあえずADC/DACの接続、ESP-NOW/UDPでの伝送などの参考にしていただければ幸いです。

関係ないですが、インターフェース誌のMATLAB特集を読んでフィルタなどを生成できることを知りまして、「あれ、もしかしてMATLABで補聴器作れるんじゃね?」と思ってググってみたら、すでにやってるヒトが。世界は広い。ただ、帯域ごとのコンプレッションは含まれていないので、そこは遊べる余地があるなぁ。

■高速DA変換テスト■

苦手なSPIなので、メモリ上に作ったサイン波形を連続出力してみました。イヤホンを直結すると「ぷー」という200hzの単音が聞こえます。

■高速AD変換テスト■

標準SPIライブラリで読み込み処理を書きました。

昭和臭ただよう可変抵抗器

その簡易的な動作テストとしてボリューム(可変抵抗)をつないですべてのビットが出てくるかを確認します。



これはそのための文字列表示処理
  int a = readADC(kRightCh);
  char buf[32], buf2[32];
  itoa(a, buf, 2);
  sprintf(buf2, "%16s %5d", buf, a);
  Serial.println(buf2);


読み込み処理はMCPのタイミングチャート(page 21)の通りに書けばこうなります。
  digitalWrite(SS, LOW);
  SPI.transfer(0b00000110);
  uint16_t result = word(0x0f & SPI.transfer(0x00), SPI.transfer(0x00));  
  digitalWrite(SS, HIGH);
でも、これだとch選択が分かれてしまって、今ひとつ面倒くさいです。その前のページを見るとスタートビットさえあれば動くっぽいので
  digitalWrite(SS, LOW);
  SPI.transfer(0b00011000 | ch);
  uint16_t result = word(0x3f & SPI.transfer(0x00), SPI.transfer(0x00)) >> 2;  
  digitalWrite(SS, HIGH);
と書きました。ちなみに連続した24bitのパターンが崩れなければいいので、
  digitalWrite(SS, LOW);
  SPI.transfer(0b01100000 | ch << 2);
  uint16_t result = word(SPI.transfer(0x00), SPI.transfer(0x00)) >> 4;  
  digitalWrite(SS, HIGH);
と書いても動きます。計算量は同じなので、どちらでも。

■ESP-NOWについて■

一度に送れるパケット長は最大200バイトです。また、CRCをつけて調べてみたのですが、パケット単位の誤り検出が行われているようで、化けたデータは届きません。

別のESPから送信しっぱなしにしておいてデータを受信したらLEDが点灯する状態で走らせれば、本来なら常時点灯したままになるはずです。しかし、時々0.5-1Hzぐらいの周期でLEDが消えます。これはたぶん他のWiFiからの干渉なのだと思います。本来、WiFiはチャンネルを自動選択しますが、ESP-NOWは固定したままなので、これはどうしようもないですね。

UDPではその現象は起こりません。が、正弦波を流してイヤホンで聞いていると、前記の通り数秒ごとにバタバタとノイズが入ります。ノイズの入り方はESP-NOWでのLEDの点滅と同じような感じなので、共通した原因なのだろうと思います。

■動作テストと考察■

オーバーランやアンダーランの処理を真面目に書いてないですが、テストとして送信側では計算で作ったサインカーブをバッファにセットし、ADC読み込みをスキップした状態でパケットを送ります。受信側は受信したパケットを順次DACに送出して、オシロで波形を見ます。

きれいな正弦波が見えるのですが、ときどき直流になりますw 受信データが化けていないのはCRCで確認済(このソースには含まれていません)なので、WiFiの受信処理によってDACへ出力するためのインターバルが止まっているのが原因と思われます。ただ、送った波形が少なくとも数パケット分なんの障害もなく受信されていることの方が多いので、定常的な受信処理そのものでインターバルがブロックされるわけではなく、それ以外のオーバーヘッドによって止まっているのではないかと推測しています。

一般的に音声信号は微小時間単位で見ると同じパターンの繰り返しなので、パケットの受信にときどき失敗することがあってもDACへの出力が止まらなければ聴覚上それほど酷い状態にはならないのですが、ときどき止まるってのは冒頭に書いたようにわりと耳障りな状態になります。

■ソース■

githubに置いておきます。


■今後■

ESPでI2Sで動作させた事例を見つけたので、DACチップを入手できたら試してみます。

■メモ■

  • ADC/DACともに、CSはずっとLOWにしててもダメです。特にDACはラッチがついているから問題ないんじゃないかと思ったんですが、1データごとにCSを上げ下げしないと動いてくれません。
  • 前にも書いたかもしれませんが、Serialは結構CPUパワーを食いますしTimerの動きも邪魔します。動作の様子を見るためのSerialですが、高速処理にハサむとシュレディンガーの猫的な状態になるので気をつけましょう(経験者・談

2016年4月23日土曜日

ヒートガンリフロー、失敗

見事失敗しました。5秒もかかりませんでした。

理由:部品がすべて吹き飛んだから

割と大きめな表面実装三端子はともかく、0603抵抗は大丈夫だろうと思っていたのですが、いやー、きれいサッパリ吹き飛びましたw 温度をあげるためのノズル(白光(HAKKO) ハッコーヒーティングガン オプションノズル A1111 )を取り寄せたのですが、ノズル細くなる→勢い良くなる→飛ぶ…は当然っすね。

と思ってノズル外してみてもやっぱり飛びました。やっぱ一番安いヒートガン(白光 ハッコーヒーティングガン 883B 100V-1KW平型プラグ 883-13 )じゃダメか…。リフローするには、専用の温度調節機能付きヒートガン(高い)じゃないとダメですね。

まぁ…失敗しても笑って済ませられるところが表面実装部品のいいところ。実験単価は基板と三端子あわせても100円以下でした。  

2016年4月20日水曜日

出勤前電子工作(未完成)



今日はこのぐらいにしといたるわー。ずっとやろうやろうと思っていたけど、かなり面倒な作業になる予感があったので手を付けなかったプロジェクト、ようやく始めました。

しかし、何も出勤前にやるこたないよねw


これは昨日の朝ですが。 あと、友達から「写真がピンぼけだ」というご意見をいただいたのですが、それはブログの縮小機能がダメなせいです。クリックして拡大すると鮮明になります。わりと(割とかよ

2016年4月8日金曜日

みんな、はんだペーストは冷蔵庫から出したかな?

 


明日何か作る、という予定はないんだけど…とりあえず冷えていると作業性が悪いので、今のうちに出しておく。

みなさん、いい週末を。

p.s.
予定してた基板が届かなかったので、結局何もしないでしまいました(ありがち

2016年4月7日木曜日

回路は仕様通りに動く

AdafruitとSparkfunとSwitchScienceへの報恩

夜中に目が覚めて眠れなくなってしまったので、ESP-WROOM-02で昨日届いた部品のテストをしました。

が、どうもうまく動いてくれません。現象切り分けのために、基本のLチカを走らせてみると…走りません。使ったのは私のESPボードの動作確認用につかっているやつで、IO12 - IO16を同時にLOW/HIGH切り替えるだけのもの。間違えようがありません。

さらに切り分けのために
  • 手持ちの複数のESPボード
  • ブレッドボード
  • ジャンパワイヤ
  • USBシリアル
  • ESP SDK

を取り替えて試しましたがダメです。しかし、Lチカ以外のプログラムは動きます。

…気付きました。手元にあるボードは、先日の「道路工事的点滅デモプログラム」のためにRESET-IO16を接続してあることに。

Lチカプログラムでは起動直後にIO16をLOWにしてます。つまり、起動直後に強制的にリセットかけていたわけです。

…そりゃー動かないよorz

ちなみにテストしたのは、1v -> 3.3vへの昇圧DC/DCコンバータです。200mAの出力容量とのことですが、1000μFの電解コンデンサを付けてもESPは起動できませんでした。1Fのスーパーキャパシタにチャージしてから試してみても一瞬IO13のLEDが光っておしまいでした。手元には5Fのキャパシタもありますが、やめておきます。DC/DCは他のマイコンに使いますわ。

窓の外がそろそろ白んできました。

今日はオフィスで眠いだろなー。サラリーマンは辛いw

2016年4月1日金曜日

降雨検出器「盛り塩1号」

いうまでもないけどエイプリルフールだからな。
派手に滑ったけど。

電子工作の歴史は降雨検出の歴史でもあります。

歴史上様々なセンサーが登場し、消えていきました。しかし、弊社(倉橋屋・東京/日本)はこの度、画期的センサーの開発に成功いたしました。

デモを御覧ください。点滅時は降雨待ちの状態です。「盛り塩1号」はわずか250mgの水滴により、センサーが死滅し、点滅を止めたことがおわかりいただけるかと存じます。



■構造■

ESP-WROOM-02モジュールに、パル生協の「海はいのち」(粗塩)を盛りました。湿度の高い季節には精製度の高い塩、乾燥した時期には粗塩を用いると潮解によるアシスト感度を調整することが可能になります。

■原理■

雨の大部分が水(化学式:H2O)から構成されていることをご存じの方も多いかと存じます。弊社では「しおがみずにとけるとでんきがながれる」ことに注目し、開発に着手しました。

大きな問題は、塩が溶けたことをどうやって検出し、遠隔地に伝えるか、でした。遠隔地への伝達はWiFi内蔵マイコンESP-WROOM-02(総務省による技術基準適合証明取得済)を使用することで解決しました。残る問題はソフトウェアの開発です。しかし、ソフトウェアの開発には莫大な費用がかかり、セキュリティなどのリスクも懸念されます。その為、ごく単純なソフトウェアで確実に動作することが求められます。

このあまりに困難な問題へのブレークスルーは、多くの画期的発明がそうであるように実験中の事故によってもたらされました。

その朝、私こと倉橋浩一は開発のバグ除けのためいつものように玄関先に盛り塩を置こうとして、ついうっかり動作中の開発機の上に塩を盛ってしまったのです。

あまりの事態にショックを受けました。

いつの間にか、頬を涙が濡らしていました。

次の瞬間、涙が回路の上に落ち、回路をショートさせてESP-WOOM-02は電波の発信を止めていました。センサーが確実に雨に反応した瞬間です。

これだ! 壊せば確実だ!!

問題は解決しました。これならソフトウェアは単に電波出してればいいので、単純化された信頼性の高くセキュアなソフトウェアを書くことができます。

そこからの開発はあっという間でした。電流(弊社では「塩漏れ電流」と呼称しています)が確実にチップの息の根を止めるよう新日本無線製高性能レギュレータを採用し、広いインピーダンス特性で奥深くまでチップが破壊されるようOS-CONを装着しました。テストに消費したESP-WROOM-02モジュールは少なくとも20台以上になりました。


犠牲になったESP-WROOM-02は、日本の伝統「針供養」に則り、豆腐に挿して弔いました。科学の犠牲になった彼らの安らかなdeep sleepに合掌。

なおRESET-IO16間はジャンパ結線済です

本日、2016年3月32日、発売します。税込1680円です(送料込み、塩は附属しておりません)。

以下に制御ソフトウェアを公開致します。(ライセンスはApache)。他の機種でも動作すると思います。また、同じ原理を用いる場合、nRF51などGPIOの余力の小さいものの方が感度が高く、MSP430Fのように割りとタフなのに消費電力の小さいものは大電流に耐えてしまい向いていないかもしれません。




■今後の課題■

同センサーはESP-WROOM-02モジュールの破損によって降雨を通知します。そのため、一雨ごとに約1680円のモジュールが尊い犠牲となります。雨に気づかず外出した場合と比較すれば微々たる金額とはいえ、今後、破損する部品がなるべく安くなるように開発を続けていきたいと考えております。

■今後の目標■

塩(エン)が熱により溶融すると電流が流れる化学現象を活かした火災報知機「焼き塩2号」の開発を進めております。現在、塩が溶けても溶けないハンダの開発者を募集しております。

■4月2日の追記■

ここで用いたESP-WROOM-02は、ホットプレートリフロー時の失敗作です。最近は滅多に失敗しないのですが、ホットプレートでハンダが溶けているタイミングで衝撃を加えてしまい、見事にズレました。ダメ元でピンセットで戻してみたけど、やっぱりダメで起動しません。

ので、こういう形で供養しました。電子部品、特にCPUをダメにしてしまったときのこの罪悪感は何なのでしょう。単なる「もったいない」以上のものがあるように思います。

■4月11日の追記■

当初この記事には「新製品発売します!」というタイトルを付けていたのですが、本日、スイッチサイエンスさんから新製品が発売となりまして(いやマジで)。紛らわしいのでこっちの記事のタイトルを変更致しました。

今後は後先考えて生きるようにしたいと思います(54歳・会社員男性)。

2016年3月30日水曜日

ESP-NOW 1:N通信




■ESP-NOWの実験■

手前左がスレーブ(受信)、奥の4つがサーバ(送信)です。スレーブには4台分のMACアドレスを登録し、サーバには受信側のMACアドレスを登録してあります。

送信側:
起動してからsetup()でdigitalWrite(13,LOW)が実行されるまでの間は左側LEDがぼんやり点灯しています(deep sleep中はoff)。右側のシリアルTx LEDの2回目の点灯が送信です(deep sleepからの解除時のシステムメッセージで1回光り、送信時にもう一回光ります)。

受信側:
受信時に光ります。ご覧のとおり、送信側の2回目の点灯と受信側のシリアルの点灯が同期しています。よかったよかった。と思ったら1回明らかに抜けているところがあるなぁ。

フレームのレイヤで誤り検出をしているので、よその電波とぶつかって信号が乱れたらいさぎよく破棄されるのが電波通信の習わしです。きっと他のWiFiなどとの輻輳でデータが壊れたのでパケットが破棄されたのでしょう。

以下ソースは受信側(スレーブ)です。複数のサーバを相手にするために「氾濫原」さんのものに少し変更しました。ありがとうございます。


■怪現象■

なお、最初は4枚をミニブレッドボードに乗せたのですが、その時に奇妙な現象が起こりました。ごく接近した2枚が勝手に同期してしまうのです。最初電源の問題かと思ったのですが、ミニブレッドボードの端と端において離せば再現しません。別電源でも1cm程度に近づけると同期します。何が原因でしょうね。

Eagle自動配線の小ネタ

最初に書いておきますが、アマチュアの戯れ言です。

中学生の頃にも方眼紙とレタリングテープと塩化第二鉄でプリント基板を作っていました。その後長いブランクを経て、Eagleで設計+Elecrowに発注というタッグで再度基板を作るようになってからのお話。

2014年10月、最初の基板

初めての基板はスッカスカでした。それから約1年半が経過して、密度は大分向上しました。そうするとEagle自動配線一発では100%にはならず、混雑しているところをひっくり返したり優先したい配線を先に通したりして、何とかします。

で、以前はベタアースも全部設定してから自動配線していたんですが、ベタアースと同時に配線すると自動配線失敗する確率が高くなります。

なので、私は:

  1. 優先して扱うべき信号ラインがあれば再優先で最短距離を引く
  2. ここで一度gitに保存
  3. 電力系、スイッチング系があるときには1点に電源/アースを集中して手配線
  4. ここでまたgitに保存
  5. その他の配線が地下鉄大江戸線状態にならないようにレイアウトなどいじりながら様子を見る。どうにもならないときには2や1やその前に戻る
  6. いい感じになってからベタアースを施す

って感じで作業しています。gitにはsource treeというアプリを使ってます。Eagleはgitなど外部からのファイル操作に対応しているわけではないので、
  • 一度Eagleのwindowを閉じる
  • commitして保存するか、revertで過去に戻る。source treeだとどっちも直感的に操作できるので良です。
  • 再度Eagleで開く

という操作を入れてます。まぁコーヒーブレイクに丁度良いですね。

今は両面びっしり。吸着ピンセット欲しい

…冷静に考えてみると、基板設計技術が向上したわけではなくて、自動設計依存の設計フローが改善しただけですね…orz

プロの方は、どの程度自動設計を使っているんでしょう?

2016年3月28日月曜日

ESP-WROOM-02の直接通信モードESPNOWを試す


ESP NOWは生パケットをやりとりするモード。DHCPどころかチャンネル自動選択もないので基本的にはチャンネル指定して送りっぱなし。つまり、余計な処理がない分オーバーヘッドも消費電力が少ないということです。

いやー、知りませんでした。何か別のことを調べていたらこの記事がヒットして、そんなことがあったのかー、となった次第。ちゃんとリリースノートを読まないといかんですね。


■ビルドする■

ただし、esp-nowは普通のarduino sdkには含まれていないので、ビルド通りません。設定を変える必要があります。

Arduino IDE : 1.6.5
Board Manager : esp8266 2.1.0

一度Arduino IDEを終了し、
~/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/platform.txt
のcompiler.c.elf.libs=-lm -lgcc -lhal -lphy -lpp -lnet80211 -llwip -lwpa -lcrypto -lmain -lwps -laxtls -lsmartconfig -lmesh -lwpa2という行に -lespnowを追加します。

…って書くと一瞬なんですけどね、ここまでたどり着くのに2日かかりました。makeEspArduinoを試したり、PlatformIOをインストールしたり。まぁその過程でSublime TextからESPをビルドする方法が見つかったりしたので、まったくムダになったというわけではありませんが(空元気

■試す■

まず上記ページに掲載されているソースを試してみます。いやー、シンプルで美しい。なお蛇足ですがESP-WROOM-02が2枚必要です。

スレーブは受信側、常時電源入れっぱなしにしておいてデータが届くのを待つイメージ。コントローラは送信側です。このサンプルでは2.5秒ごとにdeep sleepから復帰して適当な文字データを送っています。Deep Sleepを使うので、RESETとIO16を接続する必要があります

なお、実際に送受信する前に、2枚のESPそれぞれのMACアドレスが必要です。今回のアプリを起動すると自分のStation interfaceとSoft AP interfaceのMACアドレスがシリアルに出力されますので、

Slave : 相手側(Controller)STATION_IFのMACアドレス
Controller:相手側(Slave)SOFTAP_IFのMACアドレス

これをそれぞれのソースの最初の方にあるuint8_t macにセットします。相手側のアドレスを設定して登録するというのがミソ、まぁMACアドレスなんて変更できちゃうんですが、一応世界の一つだけのアドレスということになっているので、これで相手をフィルタリングするわけです。そうでないとご近所のWiFiがたまたま同じチャンネルに送信している時のデータをすべて受けてしまうので使いにくくて死にます。

実行結果はこんな感じ。画面下がController、2.5秒ごとにdeep sleepから復帰してデータを送信してます。画面上はSlaveでIO13のLEDは1秒ごとにLチカ、Controllerからデータが送られるたびにシリアルのLEDが点滅しているのがご覧いただけるかと思います。

データを送信する側は起きてすぐ寝るという感じで、通常TCP/IPなどで送信する場合に接続するだけで2-5秒かかってしまうのと比べるとかなりの消費電力削減が期待できます。




今回はこれで力尽きました(結果としてはよそのWebに紹介されてたプログラムを走らせて終わりなんだけどさ、ビルド通すまでが大変でした)。次回はこれでちゃんとセンサーのデータを送ってみます。

■追記■

1度に送れるデータは200バイトまでです。

…センサーからのデータをまとめて送ろうとしてハマりました。送っても送っても届かなくて、散々調べたらこれが原因でした。ちゃんとエラーステータスを見ましょうね、というお話ですね。とほほ。