カラーLEDテープを手に入れた
出窓 の新アトラクションに
・GitHub - KenKenMkIISR/Bouncing-LED: NeoPixel互換のLEDテープを利用したLEDが跳ねるアニメーション
はいかがかと(モータ駆動系のはうるさいんで)、カラーLEDテープを
手に入れてみました。
うまいこと光るもんですなぁ。
・「シリアルLEDスティック」光らせてみた! ? スイッチサイエンス マガジン
※7年くらい前に遡れるようです。
制御ICの制御方法がなるほどです。
WS2812B の制御タイミングを見ますと、短パルスと長パルスで
データの0と1を表現。
RGBそれぞれ8ビットのデータをドバ~っとの連続送出。
そのタイミング、データシートにはけっこうキビシイ値が記されていますが、実際は・・・
といいますのが、この記事
・NeoPixel(WS2812B)の制御: 猫にコ・ン・バ・ン・ワ (WS2812B)の制御をライブラリ無しで行ってみました。
・NeoPixel(WS2812B)の制御 その2 SPIで
Adafruit_NeoPixelライブラリーを使わず、自前で出力ポートを直叩き。
そして、SPIでもってハード的にパルス列を出そうという試み。
自前で制御すれば、Arduinoから離れられます。
28ピンのATmega328Pを使わないでもっと小さいマイコンで制御できるわけ
です。
※表示用バッファにRAMが必要ですが、1メートル60LEDの
ものだと、1LEDに3バイトで240バイトのバッファ。
ATtiny85だと512バイトでなんとかなりそう。
ということで、制御波形を見てみました。
まず、これがAdafruit_NeoPixelライブラリーでの制御波形。
これもI/O直叩きですが、Hパルス、Lパルスのパルス幅が仕様通りに
出ている感じです。
これが「猫にコ・ン・バ・ン・ワ」さんのI/O直叩き。
Lレベル部分がずいぶん長くなっていますが、これでもちゃんと制御
されています。
これもずいぶんLレベル部分が長い。
WS2812Bの制御、Hレベル部分の長短が重要でLレベル部が少々延びても
問題ないのかな?
昔のデータシートと新しいデータシートで値が変わっています。
パルス列のデューティーで判断してるんじゃ「TH」のパルス幅で
0/1を見ているのかな?
T0L、T1Lとももっと長くしてもOKなようです。
※ATmega328pのSPIについて
SPIを使っての転送タイミングを見ていて・・・
「送信後の待ちってこんなにかかるの?」
っと、疑問に思ったんでちょっとテストプログラムを
書いてみました。
まず、関連するI/Oポート
PORTB = 0b00010011; // data/pull up
DDRB = 0b00101100; // port in/out指定
// |||||+---- PB0 IO8 in -
// ||||+----- PB1 IO9 in -
// |||+------ PB2 IO10 out /SS (L)
// ||+------- PB3 IO11 out MOSI →★LED接続
// |+-------- PB4 IO12 in MISO (pull up)
// +--------- PB5 IO13 out SCK
そしてSPI回りのイニシャル。
SPCR = 0b01010100;
// ||||||++---- SPR fosc/2
// |||||+------ CPHA sck位相 SCH↑で出力確定
// ||||+------- CPOL sck極性 mode1
// |||+-------- MSTR 主装置で
// ||+--------- DODR MSBから出力
// |+---------- SPE SPI許可
// +----------- SPIE 割り込みなしで
SPSR = 0b00000001;
// || +---- SPI2X fosc/2で
// |+---------- WCOL
// +----------- SPIF SPI完了割り込みはなし
LEDデータバッファの転送ルーチン
void ledshow(void)
{
word i;
byte j;
byte d;
cli(); // 割り込み禁止
for(i = 0; i < (LED_N * 3); i++){ // LEDの数*G,R,B
d = led_bff[i];
for(j = 0; j < 8; j++){ // 8bit loop
if(d & 0x80) SPDR = LED_1; // H
else SPDR = LED_0; // L
d <<= 1; // MSBから出力
PD7_H; // (!!!)
while(!(SPSR & (1 << SPIF))); // SPI送信完了待ち
PD7_L; // (!!!)
}
}
sei(); // 割込許可
}
送信完了待ちのタイミング、D7ポートをH/Lして待ち時間を
見られるようにしています
その結果。
SPI完了の待ち時間だけでなく8回loopの処理時間も
大きいようです。 (しかし、どうしようもない)
クロックパルスが8MHzですんで。
これが限界かな。
※D7ポートへのテストパルス、これのH/Lだけで
2クロック+2クロック、0.25usかかっています。
「猫にコ・ン・バ・ン・ワ」さんのSPIでの描画ルーチンは
こんな具合。
void NeoUpdate() {
// ピクセル数x24ビット送信
for (uint8_t i = 0; i < PIXCELNUM*3; i++) {
for (uint8_t j = 0; j < 8; j++) {
SPDR = buf[i] & (0x80>>j) ? NEOSPI_1:NEOSPI_0; // SPIデータ送信
while(!(SPSR & (1 << SPIF))) ; // 送信完了待ち
}
}
}
8回ループ内にバッファメモリの読み出しと0x80のシフト操作が
入っています。
毎回これが実行されるので遅くなっているのでしょう。
自由にタイミングを作れる出力ポート直叩きのほうが
よさそうです。
| 固定リンク
「出窓」カテゴリの記事
- 出窓:鯉のぼりを振る(2023.05.04)
- 出窓:鯉のぼりを振れたらというリクエスト(2023.04.26)
- 「壊れたオルゴールの人形」を回せ!(2022.05.17)
- 「ダイソーの観覧車」を回せ! 回路図(2022.05.08)
- 緊急指令! 「ダイソーの観覧車」を回せ!(2022.05.04)
「LED」カテゴリの記事
- LEDの絶対最大定格:逆電圧(Vr)への反論(2023.01.31)
- 逆富士型40W蛍光灯2灯相当のLEDランプが不調(2023.01.21)
- 7セグメントLED駆動用IC「TM1637」(2022.12.21)
- ガレージのLED表示デジタル時計がダウン(2022.12.20)
- ダイソーの400円LED電球、寿命! 昨晩、切れちゃいました(2022.12.01)
「電子工作」カテゴリの記事
- 予告:「マイコン型導通チェッカー」「電池電圧チェッカー」値上げします(2022.11.16)
- 三和の針式テスター「GP-5」不調(2022.10.18)
- 「ダイソー ミニケース 5個組」が見つからない #2(2022.10.12)
- 「ダイソー ミニケース 5個組」が見つからない(2022.09.29)
- オペアンプの出力につなぐ大容量コンデンサ ほんとにいいの?(2022.02.26)
「Arduino」カテゴリの記事
- 初めて買ったArduino UNO・・・今は(2023.05.25)
- 液晶表示コントローラ HD44780で迎撃(2023.05.16)
- Arduino UNOで3相モーターを回す(2023.05.01)
- Arduino サーミスタを使った温度測定で 【ゼロ除算問題】(2023.03.23)
- A/Dコンバータでサーミスタの抵抗値を読む サーミスタをつなぐ場所は?(2023.03.21)
コメント