編集履歴一覧に戻る
Asi_aのアイコン画像

Asi_a が 2023年01月08日22時58分33秒 に編集

初版

タイトルの変更

+

シリアル通信で制御するLED(NeoPixel系)をSPI+外付け回路でうまくやる方法

タグの変更

+

Neopixel

+

WS2812

+

WS2812B

+

ロジックIC

+

SPI

メイン画像の変更

メイン画像が設定されました

記事種類の変更

+

製作品

Lチカの変更

Lチカが設定されました

ライセンスの変更

+

(MIT) The MIT License

本文の変更

+

[AN1606 - PIC16F1509 の構成可能なロジックセル (CLC) を使ったWS2811 LED ドライバ インターフェイスの作成 ](http://ww1.microchip.com/downloads/jp/AppNotes/00001606A_JP.pdf) このドキュメントは、現代的な8bitPICが大体持ってるSPI・PWM・CLC(色々設定可能な内蔵ロジック回路)の機能を使って、信号タイミングがシビアなシリアルLED(NeoPixelの親戚)を扱う方法が書かれている。とは言えこれってSPIの`(短くしたCLK) | (CLK & DATA)`を作れればいいよねってことなので、実はロジックIC1枚で受ければできてしまうんじゃないかと思ったのでやったらうまく行ってしまった。というのがこの記事。 冒頭の記事はWS2811を対象にしているが、この記事はWS2812を対象にする(部品の定数とSPIの速度を変えれば同じ構成で動くと思うけど)。 ## テスト回路 ![キャプションを入力できます](https://camo.elchika.com/fdf144984642fd49eb636ce3402e229ca6c1ad40/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38636432306531632d396431612d343236662d623163382d3566386430633030613733332f64646432616235622d653833662d346439352d386636342d313233386562333236663537/) * マイコンは3.3V、ロジックも3.3V、WS2812だけ5V(マイコンとロジックのレベルがあってたら同じ定数で行けるのではなかろうか)。 * CとRは、時定数を考えると`22pF * 10kΩ = 220ns`で、Hiレベルになるには63%よりはちょっと高いだろうから、おそらく妥当。 * WS2812のHigh Voltage InputのMinは2.7V、Low Voltage InputのMaxは0.7Vなので、出てくる信号が3.3Vでも動く。ただ、WS2812自体のVccは3.7Vが下なので、5Vを入れている(3.3Vでも動いちゃうことあるけどね)。 * 多分シュミットトリガなICを使うのが筋だと思うが、とりあえずそこらへんに転がってた74HC00を使った。動いたのでヨシ! * SPIの発生源にはRaspberry Pi Picoを使用している(まあこいつ自体はPIOあるからやるとしたらそれでやれって話になるが……)。 ## テストプログラム ```c++ #include <hardware/spi.h> void setup() { gpio_set_function(2, GPIO_FUNC_SPI); gpio_set_function(3, GPIO_FUNC_SPI); gpio_set_function(4, GPIO_FUNC_SPI); spi_init(spi0, 800 * 1000); } void loop() { uint8_t buffer[4][3] = { { 0x0a, 0x0a, 0x0a }, { 0x00, 0x00, 0x0a }, { 0x00, 0x0a, 0x00 }, { 0x0a, 0x00, 0x00 } }; while (1) { for (int i = 0; i < 4; i++) { spi_write_blocking(spi0, buffer[i], 3); delay(500); } } } ``` 雑なテスト。Arduino IDE 2.0→Pico Probe→テストで使ったRaspberry Pi Picoという接続をしている。オシロで波形を見るには0xaaとかが0,1交互に出て都合が良いが、LEDがめっちゃ眩しくなる。 ## テスト風景 @[youtube](https://www.youtube.com/watch?v=jFzDkAK37-s) * 22pFは手持ちにリードが生えているやつがなかったのでチップをピンヘッダにはんだ付けして使っている。 * WS2812Cは無理やりユニバーサル基板の切れ端に乗っけてピンヘッダを生やした。 WS2812に入ってくる信号線にオシロを当ててみた図。メモリは時間軸が1250ns、電圧が1Vになっている。0が240ns、1が610ns程度なのでデータシート上の要件は守れている。 ![キャプションを入力できます](https://camo.elchika.com/b08f94a1937e7dd0d83a5cce39f4a69f96eaef99/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38636432306531632d396431612d343236662d623163382d3566386430633030613733332f36326139616437642d363763652d343831322d613938302d333130626264643466623463/) ![キャプションを入力できます](https://camo.elchika.com/95e6e89cf81b884d8a1cd36d3c24e45de8b91db0/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f38636432306531632d396431612d343236662d623163382d3566386430633030613733332f63373936646563352d396437392d346662662d613461632d346561353932396538363631/) オーバーシュートしてるのでダンピング抵抗入れたほうがいいのかな? ## まとめ * なんかできた。 * できそうだからやってみた、という記事なので実用性を問われると困る。一応貧弱なマイコンとか、冒頭のドキュメントみたいにやりたいけどSPI+CLCは割けてもPWM(というかタイマー)が割けないとかの状況で役に立ちそうだとは思う。 * なんかこう、NAND1枚でできたり、22pF+10KΩという定番定数が使えたりするのすごく都合が良くてビビった。まさかそこまで考えて作られているんだろうか? * チップセレクトもうまく組み込めたら良かったけどなぁ……