月別アーカイブ: 4月 2016

さくらインターネットもう駄目かも

さくらインターネットもう駄目かも

cpu-year

自宅サーバは、さくらのVPS 4GBで2年以上運用しているわけですが・・・・昨年11月くらいから徐々にstealが増え始めました。stealは、仮想マシンがホストOSに「CPUパワーくれよん」と言ったとき、ホスト「あげられないなー」と言われた割合みたいなもんですね。

cpu-month

それでも耐えてたんですが、さらにここ2週間くらいでiowaitも激増。このくらいになると端末叩いていてもディスクの遅さが体感できるようになり、SSDプランを借りていてもHDDとあんま変わらない感じで萎える。

まあ、同じホストにすごい面倒な客が引っ越してきちゃったかなー。

年間で払っているので簡単に退去できるわけではないんだけど、そろそろ代替プロバイダ探さないと駄目かもしれませんね。

さようなら、さくらインターネット・・・・君のことは5秒は忘れないよ。

 

ESP8266からWS2812Bを光らす

ESP8266からWS2812Bを光らす

マイコンに表示機器が一切ないとデバッグ用にシリアルラインでもつながないと状態が全くわかりません。そこでフルカラーLEDでもつければ、遠くからでも様子がわかるなーと思って、電子工作界隈では有名なWS2812Bをつけてみようと思ったわけです。

こいつの特徴は、マイコンが内蔵されており、わずか1本のデータ線でRGBすべての制御ができ、かつデイジーチェインが可能で数十個数珠繋ぎになったLEDテープを一挙に制御可能ということ。使えれば工作の幅が広がりそうです。

VDDが3.5~5.3VでかつHysteresis voltageが0.35Vだから、ちょっと3.3Vオンリーで動作させるのは厳しい…ESP8266は5Vトレラントではないから信号線の3.3V→5Vレベルシフト回路が必要です。

世間の作例だと、3.3Vのまま動かしていたり3.7VのLiPOバッテリーを電源に使ったりしてレベル変換もせず動かしているものが多いのですが、点滅が不安定とかデイジーチェインの1個めだけ光らないとか、不具合も多いよう。

普通に正攻法でBSS138 MOSFETを使ってレベル変換回路かけばいいんちゃうか?と思って、以下のような回路を作って基板を起こしました。

WS2816B_BSS138

まー普通に動くでしょ?こんなの・・・と思ってたら見事に動かず。かなり苦労しました。
ライブラリは世間一般に使われているAdafruit NeoPixelでは動かなくて、Makuna NeoPixelBusのBitbangモードでだけ動き、しかも特定の組み合わせの色が白になってしまう。

不安定すぎんだろ!!

データシートを見る限り、1ビットのH信号を出すために、850nsのHを出した後450nsのLを出力、誤差は150ns以内ということですから、いくらARMコアが速くてもソフトだけでこのタイミングを生成するのは相当荷が重いでしょう。Bitbangモードは、使えるIOピンを選ばない利点がありますが、この微小なタイミング生成をソフトでやるので、ESP8266が忙しくなりすぎてWiFi通信が不安定になったり勝手にリセットがかかったりするそうです。やはりSPIやUARTのようなハード的なバッファを持ったモードで動作させたくなりますね。

うーん。いわゆるハッキング、マッシュアップのレベルでは「簡単にできた」と表現されるWS2812Bですが、実物はかなりの難物との印象です(少なくとも私のような素人には)

結局どうしたの?

結論だけ聞くと簡単そうに聞こえるでしょうが、「BSS138のプルアップ抵抗を100kΩ→1kΩにしただけ」で動きました(≧▽≦;)

参考になった記事はTesting level shifters for running Adafruit NeoPixel strips from a 3.3 Volt Teensyでした。どうもBSS138をはさむことで信号が鈍るようなんです。

私みたいにソフト・サーバ屋から電子回路に入ってきた人間には想像もつかないことですが、本来コンデンサではないはずの部品や回路配線自体に寄生容量というものが存在するそうです。これがコンデンサとして働いてしまう。この寄生容量(C)とプルアップ抵抗(R)で、RC遅延回路が形成されてしまう。すると信号の立ち上がりに遅れが生じて、方形が山形状の波形に鈍ってしまうと。

Bitbangモードだけで動いた、その理由は具体的にはわからないのですが、オシロで確認した限りでは生成された波形にかなり違いがありました。ちなみに出している信号はR=128, G=0, B=0です。Rの上位1ビットだけがHということですね。

int PixelPin = 5;
NeoPixelBus<NeoGrbFeature, NeoEsp8266BitBang800KbpsMethod> 
strip(PixelCount, PixelPin);

neopixel_bitbang_io5

int PixelPin = 2;
NeoPixelBus<NeoGrbFeature, NeoEsp8266Uart800KbpsMethod> 
strip(PixelCount, PixelPin);

neopixel_uart1

この違い、わかります?全体の長さも違いますが、Bitbangモードの方がH信号の山部分が平坦かつ長いんですね。つまりBitbangの方が正確なんですよ。UARTバッファモードは、元々シリアル通信の生成に使うハードウェア機能を流用して作られたものですから、本来の信号のためのクロックをだましだまし使うということになります。そりゃそうだ、WS2812B専用の回路を持つマイコンなんて存在しないから。

これが影響しているんじゃないかなー・・・・と個人的には思っているのですが、宮仕え先のオシロは仕事の都合で返してしまったので、結局調べられていません。

オシロほしいですね・・・・・まともなものは10万くらいしますから到底買えませんけども・・・お金ほしいですね・・・お金ください!!!(血涙

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。