ESP8266のSPI通信周りをオシロで確認した

ESP8266に手を出したワケ

今まで作ってきたボードはRaspberry Pi前提で、車両からCANデータを取得するものでした。ちょっと回路の間違いはあったけど一応動いている。でも、ボード単体でCANデータを送信できるようにしたり、ちょっとした解析ができれば、便利ではないかと思った。それには通信機能がついているマイコンが必要だ。

ESP WROOM-02開発ボード

ここ1年くらいで急速に盛り上がってきたESP8266というWiFiチップがある。WiFiチップと言っても、Arduino IDEで開発できる単体マイコンでもあるから、他にマイコンは要らないわけだ。チップ単体だと500円を切っており、ヘタにArduinoボードを買うより安いというのも痺れる。

前回まで作っていたCANボードの搭載チップMCP2515はSPI接続だから、ESP8266のSPI APIを使おうとしたのです。

動かない・・・

ところが動かないんだなこれが。Arduino用のMCP2515ライブラリをESP8266で動くように移植していたのだが、テコでも動かない。レジスタも読めない。

ESP8266にはSPIとHSPIという2種類があるようなのだが・・・世間様の情報を見ても、なぜ2つあるのか全くわからなかったのだ。また、SPIにはArduino SDKでサポートされているArduino互換のSPI APIと、MetalPhreak: ESP8266_SPI_Driverの2種類あるのもなぞだった。
たまらず先人に質問したりしたのだが、接続等も間違っていないようだし。これはソフト的な問題なのか、それともチップ内部で使っているSPI接続(フラッシュメモリ)との競合なのか、などとと謎は増すばかり。

しかし、基板まで作っておいて手元にはテスター以外の計測器がなく・・・「わからないときはモノに聞け!」とばかりに宮仕え先のオシロをひっぱりだしてしまった。

ESP8266のSPI通信周りをオシロで確認した

まず、疑ったのはSPIのモード。SPI通信には4種類のモードがある。mbedのSPIマスターのWikiがまとまっている。Arduino ESP8266 SDKの標準SPIだとMODE0しかサポートしていないそうなので、MetalPhreak: ESP8266_SPI_Driverを使ってテストした。

ヘッダファイルのコメントには、

///////////////////////////////////////////////////////////////////
//
// Function Name: spi_mode
// Description: Configures SPI mode parameters for clock edge and
 clock polarity.
// Parameters: spi_no - SPI (0) or HSPI (1)
// spi_cpha - (0) Data is valid on clock leading edge
// (1) Data is valid on clock trailing edge
// spi_cpol - (0) Clock is low when inactive
// (1) Clock is high when inactive
//
///////////////////////////////////////////////////////////////////
void spi_mode(uint8 spi_no, uint8 spi_cpha,uint8 spi_cpol)

こう書いてあるので自然と、

spi_mode(HSPI, 0, 0);

と書いてしまっていた。この状態でオシロでクロック出力を観察しようとすると・・・

hspi_0_0

信号!出てねえ!!

マジかよ。ちなみに緑がクロック、水色がスレーブ信号出力(MISO)です。SPI通信の場合、クロック供給はホスト側(マイコン)がやるのでクロックが出ていないのは明らかに異常・・・・だと思うのですがどうでしょう?

spi_mode(HSPI, 1, 0);

hspi_1_0

あ、これがArduino一般で言うところのMODE0じゃないのか?

spi_mode(HSPI, 0, 1);

hspi_0_1

んークロックが負論理になっててラッチ先行だからMODE2ですよね。

spi_mode(HSPI, 1, 1);

hspi_1_1

クロックが負論理で、シフト先行だから、MODE3ですよね。

おい!MODE1どこいった!!とにかくspi_mode(HSPI, 0, 0)だと動きそうにないことはわかった。ちなみにこの初期化をしない(デフォルト)で波形を観察すると、デフォルトはspi_mode(HSPI, 1, 0)のようです。なんかモヤモヤするけど、とりあえずの観察結果は以上です。MCP2515はMODE0とMODE3をサポートしているから、デフォルトでOKなのかしら(確認していない)

たぶん、何か勘違いしていると思いますが、現場からは以上です。

SPIとHSPIの違い

もうひとつの疑問。HSPIとSPIの違いは・・・実はよくわかりませんでした。速度差なのかな?と思って速度を調べてみました。

SPIのほうはArduino標準APIに沿っているので最大ホストクロックの2分周(DIV2)のようです。この場合の波形は以下のようになります。

SPI_MODE0_DIV2

1クロック(立ち上がり立下り)でだいたい150nsだから、周波数に直すと約6.6MHzですかね。まあ大半の用途では十分でしょう。

一方でMetalPhreak: ESP8266_SPI_Driverのspi_clock(HSPI, 1, 2);の場合は以下のような波形になりました。

HSPI_CLK_1_2

60nsに2クロック入っているように見えます。だから周波数に直すと33MHzも出ているということになります。この設定では信号がかなり鈍ってしまってますので、実際に基板パターンをひきまわしてペリフェラルと33Mbpsで通信ができるとは限りませんが・・・確かに速いですね。

MCP2515の場合10MbpsまでサポートしていますからHSPIの方がよさそうです。デバイスにもよりますが画像取り込みもできる速度だと思います。意外とポテンシャル高いねESP8266。

どうしてもCAN BUSが動かなかった

CAN BUSってなに?

CAN BUSとは…ボツシュが開発した車両用のネットワークであり、これにつなげられると車速や燃料噴射量などを取得できる。

車両にはOBD2端子というものがダッシュボード下に出ていて、自動車工場にある自動診断装置を接続すると、車両の情報を読んで、故障を診断する。厳密にはコマンドのハンドシェイクによってプロトコル名が違うのだが、基本はCAN BUSからデータを読んでいる。

我々素人がCANを読むにはOBD2アダプタというものを買えば、基本的にはOK。安いし、スマホのアプリにBluetoothで飛ばして電子メーターとか可能になる。

だから、わざわざハードウェアを作る理由は、実はあんまりない。でも、昔からスマホでドラレコとかやっていた身から言わせてもらえれば、スマホは「設置」するのも「接続」するのもけっこう大変だ。正直言ってだるい。

車両機器は、できればダッシュボードにがっちり固定しておきたい。Raspberry Piの場合はHDMI出力があるから、CANが読めれば電子メーターや累積燃費系みたいなものをリッチにつくることができるだろう。

どうしてもCAN BUSが動かなかった

これまで作ってきたボードは、大した周辺チップが載っておらず特に問題なかったのだ。でもCANは動かなかった。動かない原因がわからない。

机の上の惨状

机の上の惨状

リフローオーブンの温度ミスで部品が焼けたのか、CANコントローラMCP2515とトランシーバMCP2551の回路の結線ミスなのか、Raspberry PiのOS側の設定ミスなのか、ヤフオクで落としたプリウスのヨーレートセンサーの中古が壊れているのか、もう皆目見当がつかないわけである。

手元にある測定機器といえば、10年前に買ったフルークのテスター1個・・・・・ロジアナもオシロもなしに、表面実装部品のボードを開発すること自体が、あまりに無謀で常軌を逸していたのは否めない。しかしもはや測定機器を買うお金がない。これまで投入してきた金額は5万円以上。到底趣味の範囲で買えるものではなかった。

ふと・・・初心にかえって

実物を目の前にして、なお調べようもないので、ボード設計時のデータを見直すことにした。

図面上はつながっていると思われたが・・・

図面上はつながっていると思われたが・・・

電源にパスコンはいってない素人丸出しの回路図はおいておくとして、一応MCP2515の電源に3.3Vはつながっているように思えた・・・・

ああ、なんということでしょう

ああ、なんということでしょう

しかし・・・基板の方は未配線だったのだ!(図中の黄色い線)

どうしてこんなことがおきたかというと、せっかくEagle CADが出してくれていた警告を1度無視する操作をしてしまった。Eagleの仕様上、未配線を無視すると図面からも消滅するのであった。ワーニングには必ず意味がある。ブラインドでポチポチしてはいけなかった。

手配線で3.3Vを20番ピンに投入したら、めでたく動き出した・・・ここまで2週間。本当に疲れた。

 

初めてフル搭載した基板を焼いた

初めてフル搭載した基板を焼いた

おまえなんかレンジでチンだ!

できあがった基板はCARMOD1、と呼びます。

CARMOD1

CARMOD1

自動車のOBD2端子からCANデータをひっぱってきて、Raspberry Piに渡すだけです。バッテリー直結を見越して、電圧監視とRaspberry Pi本体への電源供給を管理します。ついでに、ソフトではいまいちうまく動いていないウォッチドックタイマーを外部に持ち、Raspberry Piがおかしくなったらリセットできます。

・・・・・できるはずでした!!次回以降に続きます。

リフロープログラム公開&リフローの勘所

スイッチサイエンスのリフローキットのプログラム

Papanda_SSR_Solder_Toaster_Controller_Platform (GitHub)

これ以上持っていても仕方がないのでとりあえず公開しておきます。実は純正プログラムも、最初はPID制御をしていたけど後に辞めた、ということを知ったのはPIDライブラリで書きなおしたあとでした(^^;

TSSOP-8パッケージのリフロー成功

まだ、1608パッドの周辺はダマになってるけど、狭ピッチのICもリフローできるようになってきたよ。

TSSOP-8リフローの様子

秘訣は….

クリームはんだを撹拌すること

でした….マジかよ。要するに上澄みの方は有機溶剤が飛んでいて、十分な濡れ性を確保できていなかったようだ。表面張力で引き寄せられない部分がダマになるってわけ。均一性が崩れるので撹拌しすぎるのも良くないらしいけど。

世間を見回せば、今回買ったような容器タイプじゃなくて、シリンジタイプのものがたくさんあるのね。これは有機溶剤が飛ばないようにするためのものだと思う。

正直、通販だと賞味期限とか保管時の温度とか信頼できないわけだけど、最低限撹拌はするというのが勘所かしら。

 

温度プロファイルの条件出し

最終的な温度プロファイルは以下に。

最終温度プロファイル

正直最初のころとあまり変わっていない。プリヒート工程を2段にしたことくらいかな。パラメータは以下に。

  • ヒーター: 下段のみ
  • TimeInterval: 2000 ms
  • Kp: 107
  • Ki: 0.65
  • Kd: 18.5
  • 工程: 80度/120度/230度

PID使っちゃったのが運のつきなんだけど、PID理論についてはモータのPID制御法 というページが一番わかりやすかったです。今回のヒーターの場合はKdがあまり小さいと追従性がいまいちということがわかりました。

あと色々苦労した経験上、やっぱりプログラムや熱電対だけでは実際の基板の温度がわからないので、下記のような放射温度計がどーしても必要です。参照基板に熱電対をカプトンテープで固定しているのですが、隣接する実際の基板と20度以上違うことも珍しくありませんでした。

熱せないとクリームはんだ溶けませんけど、熱し過ぎるとチップが壊れるので測定重要です。

Eagleの設定し忘れ

余談ですが。

どうも以前から気になっていたのだが、PCBステンシルを使ってパッドに盛ったクリームはんだの量が多い。写真でも確認できるけど1608のパッドはてんこ盛りである。デザインルールはElecrowからダウンロードしたものをそのまま使っていたので再確認してみると…Masksの設定が全くされていない(オール0)であることに気づいた。いつからだ….

Cream項目設定し忘れ

このうちのStopがストップマスクの設定で、Creamがクリームはんだを塗る領域を指定する指標らしいんだな。しかし、今これを気づいたところで、また基板とステンシルを再発注ということになってしまうのであった。

ほんと経験がないから金ばっかりかかってもう….ハード屋さんが身近にいれば色々助かるんだけどねえ。

いまさらSamba3で苦労している

いまさらSamba3で苦労している

ほんと「単一ドメインでディレクトリ/mnt/shareを誰でも共有できるようにする」目的だけ達成できればいいのに、すごーく苦労しているという話。SMB2を使って高速化したかっただけなんだけどねー

今更samba3もないものだけど余計に情報が錯綜して困ってる。

現状の設定ファイル

testparmを通したもの….

[global]
 server string = %h server
 map to guest = Bad User
 obey pam restrictions = Yes
 pam password change = Yes
 passwd program = /usr/bin/passwd %u
 passwd chat = *Enter\snew\s*\spassword:* %n\n *Retype\snew\s*\spassword:* %n\n *password\supdated\ssuccessfully* .
 unix password sync = Yes
 syslog = 0
 log level = 3
 log file = /var/log/samba/log.%m
 max log size = 100
 disable spoolss = Yes
 dns proxy = No
 panic action = /usr/share/samba/panic-action %d
 printing = bsd
 print command = lpr -r -P'%p' %s
 lpq command = lpq -P'%p'
 lprm command = lprm -P'%p' %j
 blocking locks = No
 oplocks = No
 wide links = Yes
[share]
 comment = Media Directories
 path = /mnt/share
 read only = No
 guest ok = Yes

設定ファイル解説

文字セットをWin/Linux/Macで「普通」に使えるようにする

display charset = UTF-8
 unix charset = UTF-8
 dos charset = CP932

security=shareを設定する愚策脱却

map to guest = Bad User
 (security = user)

SMB2を使って高速化

 max protocol = SMB2
 (security = user)

NetBIOS名の解決にDNSを使わない,タイムアウト抑止

dns proxy = No

アカウント管理を極力UNIX(PAM)に任せる

obey pam restrictions = Yes
 pam password change = Yes
 unix password sync = Yes

ログを最小にする

syslog = 0
 log file = /var/log/samba/log.%m
 max log size = 100

Sambaでプリンタ共有無効&ログ抑止

disable spoolss = Yes
 printing = bsd

複数Ver.Windows OSが共存している状態でファイルが壊れる問題の対処

blocking locks = No
 oplocks = No

Win含めたユーザにsymlinkを意識させず、かつ管理者はSambaの外で操作できる

unix extensions = No
 wide links = Yes

どうしてもMac OS Xからログインできない

ゲストでも登録ユーザでもダメで….多分上記の設定ファイルが間違っている
のだろうけど全くPAM <-> Sambaのアカウント管理が同期してくれないよのね。

/var/lib/samba/passdb.tdbがなぜか更新されない。smbpasswdも使えない。

腹が立ったので

# pdbedit -a -u papanda

として強制的にユーザ追加してguestログインは諦めた!敗北!

find,xargsコマンドの小ネタ

findコマンドの正規表現

仕事で。とある動画系商用システムで、定期的に動かしていたコンテンツを別サーバと同期するバッチが凍り付くようになったとヘルプ。バッチを覗いてみると…

find /var/cache -type f -name '*.jpg' -exec rm -f {} \;
find /var/cache -type f -name '*.JPG' -exec rm -f {} \;
find /var/cache -type f -name '*.png' -exec rm -f {} \;
find /var/cache -type f -name '*.PNG' -exec rm -f {} \;
find /var/cache -type f -name '*.bmp' -exec rm -f {} \;
(これが20行くらい続く)

ouch!

仮に/var/cacheに10万個ファイルがあれば、ディレクトリサーチは10万x20行。開発者に聞いたところ「拡張子を列挙しようと思ったが()が効かないのでそういうものだと諦めた」だそうで。

Linuxなどでよく使われているGNUfindコマンドの場合、regextypeで正規表現を切り替えることができる。大文字小文字を区別しない-iregexもある。以下のように書くだけでディレクトリサーチの回数は1/20になる。

find /var/cache -type f -regextype posix-exteneded -iregex
'.+\.(jpg|png|gif|bmp|mpg|mp4|3gpp|ts|mp4a|aac)$' ....

ファイル削除の高速化

さらにバッチが凍り付く原因を調べると、動画からサムネイルを生成する
プログラムが壊れたアップロードファイルを読み込んで暴走し、cacheディレクトリに800万個くらいのJPEGを生成したことがわかった。そりゃ凍り付くわな….

findのもうひとつの盲点は-execオプションの扱い。ちまたのLinux入門書を見ると半ば定型句のように-exec rm -f {} \;が書いてある(俺もな!)。
実はこの指定、1ファイルごとにrmコマンドをfork()してexec()するので
とても遅い。

本来、手動で複数ファイルを消すときも、

$ rm hoge.txt piyo.txt aho.jpg ...

というように複数ファイルを指定することが多いはず。これを模倣してくれるのがxargsコマンド。findから受け取ったファイルリストをコマンド引数ギリギリの長さまで羅列して、rmコマンドに渡してくれる。

20万個の空ファイルを生成してベンチマークしてみる。

$ time find cache -type f -exec rm -f {} \;
real 2m38.417s
user 0m1.356s
sys 0m35.328s

ファイル名に空白を含む場合を想定して、findには-print0オプションを、
xargsには-0オプションをつけることにしよう。

$ time find cache -type f -print0 | xargs -0 rm -f 
real 0m9.092s
user 0m0.276s
sys 0m2.812s

約18倍高速化

6時間かかる削除処理が20分で終わります…となると、実作業の効率はだいぶ異なってくる。顧客の心情も。

さて。これが最速か?実はわざわざxargsをパイプで結ばなくても、もともとfindコマンドには-deleteオプションがあり、一切外部コマンドを使わなくてもファイルを消すことだけはできる。ディレクトリサーチしているfindが直接unlink()システムコールを呼ぶから理論上は最速のはず….

$ time find cache -type f -delete
real 0m9.105s
user 0m0.144s
sys 0m2.692s

しかし(この環境では)あまり変わらなかったようだ。速度が全く同じであれば、rm -vfとして実際に消せたかログを残せるxargsコンビの方が多少有利か。

xargsコマンドの小技

ちなみに、xargsコマンドには-lオプションというのがあって何ファイルずつ引数に渡すかを指定できる。なお、-lのデフォルト行数は1なので以下の2行はほとんど等価である(等価に遅い)。

$ time find cache -type f -print0 | xargs -l -0 rm -f 
$ time find cache -type f -exec rm -f {} \;

xargsに-lオプションを付けたいとき、というのは擬似的には

$ mv hoge.txt /var/trash

のようなファイル削除以外のファイル操作コマンドの、第2引数にコピー先を与えたいときだろう。本当は以下のように書きたい用途において。

$ mv hoge.txt piyo.txt ... /var/trash

GNU fileutilsに属するコマンドはよく考えられており、cp,mv等には-tオプションが存在する。-tは宛先ディレクトリ指定。ゆえに以下の2行は等価である。

$ mv hoge.txt piyo.txt /var/trash
$ mv -t /var/trash hoge.txt piyo.txt

おっ、宛先ディレクトリが前出しできた。-t /var/trash以降にはコマンドライン引数限度めいっぱいまでファイル名が並べられるので、xargsとベストマッチする。

これまでの内容を組み合わせて、例えば特定のディレクトリの特定種のファイルのみを別ディレクトリに移動する、といった場面を考えたとき、以下のようなコマンドが最速となる、だろう。

$ find /var/cache -type f -regextype posix-exteneded ¥
-iregex '.+\.(jpg|png|gif|bmp|mpg|mp4|3gpp|ts|mp4a|aac)$' ¥
-print0 | xargs -0 mv -t /var/trash

ま、本当に緊急回避的に/var/cacheを掃除したいなら

$ mv cache cache_orig
$ mkdir -p cache

が最速である(^^; これがオチでいいのか….

クリームはんだ、ダマ地獄

まあ写真を見てくださいよ・・・・

ダマみえます?パッド周辺に細かいダマのようなものができてるでしょ。LPC1114周辺はさらに怪しくて短絡している始末。正直手はんだの方が高クォリティですよ。

せっかく炉まで作ったのに。温度プロファイルをアレコレ変えても今のところ打開策なし。ソーク工程を短くすると少しマシにはなりますが力尽きた。

クリームはんだそのものの問題?

温度のせいだけじゃないと思うんですよ。フラックスがヘタってるとしか思えないんだよね。なぜならPCBステンシル経由で塗付する時点ですでにダマっぽいので。クリームはんだの品質は、温度管理等様々な劣化要因があることは知ってて、もっとも安心そうな東京デバイセズから買って、それで駄目ならどうすりゃええんや・・・・

ほんと、ハードウェア趣味は金がかかるなあ。

てなわけで、しばらく日記をお休みしていたのは、こんな初歩的なところで躓いていたからなのでした。

自作基板の部品表を作ってみた

自作基板の部品表を作ってみた

今回は表面実装部品が多いので、秋月で都度買ってくるということもできなそうなので、ためしに部品表を作ってみました。部品はテープでくるので1個単位で買えないものも多いのでロット合計も出してみました。

bom1

最低金額3.5万円!

特に高いのがセンサー類。そして1個から買うのが難しいものが多いから、総額が高くなってしまうのです。600円のチップでも、10個が最小ロットなら6000円になってしまうから。センサー以外でも、小さいから良いと思っていたリアルタイムクロックのM41T62も533円とかなりお高い万円。ところが、ストロベリーリナックスでM41T62のブレイクアウトボードを買うと500円なのよね・・・あちらは基板に電池ホルダーまでついているというのに。量産効果なんだろうけど、少量生産が如何に割に合わないかを体感しています。

1枚当たり部品代をみても4300円は下回らない感じです。それでいてできることと言ったら、Raspberry Piを8V~30Vの間で安全に動かせて、リセットボタンとウォッチドックが追加されて、時計と加速度と気温大気圧計がついて、ファンコン用の12Vスイッチが1つ。これは需要ないですかね・・・商品企画失敗というやつ?

仕事なら、即座にやめるべき案件なんでしょうけど。趣味の場合、ボードを作るまでやり遂げることが重要なのか、改めて自問自答しています。

Raspberry Pi Zero

「金がない」という葛藤の中、さらに運の悪いことにRaspberry Pi Zeroという新製品が出てしまいました。一応GPIOピンに互換性はあるものの、フォームファクター的に従来のHAT基板の外形が合わなくなってしまったことも、悩みを深めた原因です。

sk_raspberry_01

個人がセンサー1チップ調達するのと同じ値段で、Linuxが動く完全な32bit ARM SBCが変えてしまう・・・・そう考えると益々個人が何をやるべきなのか問われそうです。

USBにHDMIまでついたマイコンボードが600円弱という社会的インパクトは大きいですね。消費電力にこだわる用途以外では、ほぼこのボードで賄えてしまうでしょうから、mbed含めたショボイマイコンボードはすべて吹き飛んでしまうかもしれません。

 

Eagle CADのフレーム(小ネタ)

そんなところにあったのか!Eagle CADのフレーム

他人の書いた回路図をみていると、ちょうど地図みたいいに横がA,B,C,D…縦が1,2,3..という枠に囲まれて、右下に署名がはいっているものを良く目にします。それをEagleで実現したくて、ページ設定のようなものがないかなーとメニューを探して数ヶ月。どうしても見つからなくて半ば諦めていたのです。

現在、リフローオーブンをArduinoで作っているのですが、開発元のボードの回路を確認したくてスイッチサイエンスさんの書いた回路図を見たら、Eagleで書かれているのにがついてるじゃないですか!

まさか!と思って再調査したところ、あっさり見つかりました。部品ライブラリの中に・・・・

sheet1

frames.lbrってずばりのファイルがあったよ。トランジスタなどと同じところにこんな枠が並んで入っているの酷くない?

わかっかっつーの!!!!(怒)

PID制御は試行錯誤の連続

PID制御は試行錯誤の連続

制御理論に挑戦したかったのです。例えば、ボイラーから特定の温度のお湯を得たいとか。特定の位置でタイヤや関節を止めるとか。全てに制御理論がある訳です。今回のリフロー炉もそうで、基本的にON/OFFしかできないヒーターで、いかに所望の温度プロファイルを実現するか、がカギな訳です。

reflow0

上記は、ある表面実装部品の温度プロファイルです。140-170度の平坦部分がプリヒートとかソークとかいうクリームはんだの濡れ性を確保する領域で、少なくとも60秒必要。そこからガッとリフロー領域にはいって210-220度、但し183度以上は50秒しか許されていない、という感じです。

今回採用したPID制御には、Kp,Ki,Kdという3つのパラメータがあり、それぞれ比例制御、積分制御、微分制御のパラメータで、本当は決めるのにいくつも推定方法があるのですが、それらを真似してもあまりうまくいかず。場当たり的にパラメータを変えてはオーブンちーん!を繰り返しているところです。

まだリレー回路を組んでいないのでコンソールを見ながらの手動の温度コントロールですが、ここまで追い込んでいます。

reflow1

しかし、色々問題が。今回買った小泉のオーブントースター、密閉性が良過ぎて冷えるのがとても遅いわけです。するとリフロー領域で180度以上の区間がとても長くなってしまうわけですね。実は暖めるより、高速に冷やす方が難しい気がします。とりあえず温度勾配を液晶にダンプするように改造したファームで観察する限り、ヒーターON時は2.5度/s、ヒーターOFF時の自然空冷は0.6度/sくらいなので、全然無理っぽい。いっそ上部天板を開けておく前提でパラメータを出した方が良い気がしてきました。

なかなか基板製造にはいれない……