カラー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のシフト操作が
入っています。
毎回これが実行されるので遅くなっているのでしょう。
自由にタイミングを作れる出力ポート直叩きのほうが
よさそうです。
| 固定リンク
「出窓」カテゴリの記事
- 「壊れたオルゴールの人形」を回せ!(2022.05.17)
- 「ダイソーの観覧車」を回せ! 回路図(2022.05.08)
- 緊急指令! 「ダイソーの観覧車」を回せ!(2022.05.04)
- 温湿度センサーDHT11、ライブラリを使うと氷点下の温度がおかしくなるぞ!(2022.03.10)
- DHT11を使った出窓の結露対策用ヒータ制御回路 この1週間(2022.03.08)
「LED」カテゴリの記事
- あちゃ~。電池押さえのスポンジがモロモロに(2021.11.16)
- LED劣化調査実験、新回路案(2021.10.16)
- 顕微鏡用LEDリングライトのLED交換(2021.10.04)
- 顕微鏡用LEDリングライトのLED、そろそろ交換か(2021.09.27)
- 「ぶつかるLED」(2021.04.16)
「電子工作」カテゴリの記事
- オペアンプの出力につなぐ大容量コンデンサ ほんとにいいの?(2022.02.26)
- オペアンプ ICL7611(2022.02.24)
- 「シャカシャカ・ホイップ」衝撃検出回路(2022.02.18)
- 単安定マルチバイブレータ 「74123」と「4538」の挙動(2022.02.09)
- 「シャカシャカ・ホイップ」予備実験 #5(2022.02.04)
「Arduino」カテゴリの記事
- 「UART←→IrDA」変換IC、MCP2122のクロック供給(2022.06.20)
- 秋月の赤外光送受信モジュール(AE-RPM851A)を使ってみる(IrDAを試す) #2(2022.06.18)
- 秋月の赤外光送受信モジュール(AE-RPM851A)を使ってみる(IrDAを試す)(2022.06.17)
- 4046・VCO回路の直線性改善方法その2(2022.06.13)
- 「ダイソーの観覧車」を回せ! 回路図(2022.05.08)
コメント