フォト
2025年2月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28  
無料ブログはココログ

« タマちゃんが15歳になりました(*´ω`*) | トップページ | 一部の記事の削除 »

2024年9月15日 (日)

NeoPixel(WS2812B)の制御 その5

NeoPixel(WS2812B)の制御 その4」に関して質問がありました。
流通しているNeoPixelマトリックの配列には様々なタイプがあるようです。

そこで、前回のスケッチをもう少し見直して、 XYtoNo()関数の修正でレイアウトの差異を吸収できるよう、修正しました。
スクロール処理を行うNeoScroll()関数を、処理速度を少々犠牲にしてXYtoNo()を使って処理を行うようにしました。
試した感じでは、処理速度的には問題ないようです。

修正版 

■ 修正の補足
 NeoScroll()関数は、縦x横のドットデータを左に1ドットずらす処理を行っています。
 従来版は速度重視のためmemmove()、memset()を使っていたのですが縦並びのLEDに対応出来ません。
 そこで XYtoNo()を使てのデータ操作に修正しました。

 これにより、XYtoNo()関数にてパネルのレイアウトに対応するだけで差異を吸収できます。

 文字の縦の表示開始位置は、次の定数を変更することで調整出来ます。
  #define Y_OFFSET 0 // フォントの縦先頭位置  

ここで、「NeoPixel(WS2812B)の制御 その4」でZuhiさんがご質問されました、
横32ドットx縦8ドットで「パネルの左上起点に下上になっている」パネルについて対応してみましょう。
256個のLEDが数珠つなぎ(0~255)になっているのですが、並びは次の感じだと思われます。
左上が起点で↓向きでスタート、8個目で↑向きに折り返しで256個がつながっています。
Photo_20240914203101
上記において、任意の(x,y)の位置のLEDを操作するためには、そのLEDの先頭からの番号が必要となります。
計算式としては、次のようになります。

xが偶数の場合:
 no = x * 8 + y
xが偶数の場合:
 no = x * 8 -y + 8 -1

定数を踏まえると..
xが偶数の場合:
 no = x * PXCEL_H + y
xが偶数の場合:
 no = x * PXCEL_H -y + PXCEL_H - 1
となります。

修正版のスケッチをZuhiさんのパネルに対応する場合、以下の修正でいけると思います。
 ①定数の変更

  #define PXCEL_W 32 // 横ピクセル数
  #define PXCEL_H 8  // 縦ピクセル数


 ②XYtoNo()の変更
  noを参考にして修正すると、関数内のreturn文を下記のように修正します

  return x&1 ? x*PXCEL_H-y+PXCEL_H-1: x*PXCEL_H+y; // 左上起点下上方向並び


 (※修正版にコメント化して記述しています)

横32ドットx縦8ドットパネルは所有していないので、動作確認出来ないのですが、たぶん大丈夫でしょう(;^_^
(うまくいかない場合、連絡ください)

« タマちゃんが15歳になりました(*´ω`*) | トップページ | 一部の記事の削除 »

arduino」カテゴリの記事

AVR」カテゴリの記事

表示器制御関連」カテゴリの記事

コメント

初めてコメントさせていただきます。
この投稿を見て、横32ドットx縦8ドットパネルに表示させることができました。
この横幅を変えれば、パネル2枚つなげた幅64ドットでも表示できるのではないかと試したところ、32ドットの範囲内でフォントが横広になって表示されてしまいました。
どこかに32ドット縛りの制約が入っているのでしょうか?
32ドットパネルは複数枚所有していますので、こちらで動作確認はできます。
よろしくお願いします。

あずまさん

このスケッチでは、ピクセル番号の扱いがuint8_t型であるため、横64x縦8ドットだとオーバーフローしてしまいます。
汎用化した割には、変数の取りうる範囲を考えていませんでした(>_<)

ピクセル番号を処理する関数のいくつかで、オーバーフローしないための修正が必要だと思います。

(修正) uint8_t をuint16_tにする
・void NeoSetRGB(uint8_t no, uint8_t R, uint8_t G, uint8_t B, uint8_t flgUpdate=false)
 を
 void NeoSetRGB(uint16_t no, uint8_t R, uint8_t G, uint8_t B, uint8_t flgUpdate=false)
 に修正

・inline uint8_t XYtoNo(uint8_t x, uint8_t y)
 を
 inline uint16_t XYtoNo(uint16_t x, uint16_t y)
 に修正

上記以外にも、もしかしたら uint8_t をuint16_tにする 修正が必要となるかもしれません。

横64ドットに表示させることができました。
ありがとうございました。

コメントを書く

(ウェブ上には掲載しません)

« タマちゃんが15歳になりました(*´ω`*) | トップページ | 一部の記事の削除 »