いうことで、この投稿ではWS2812をArduinoから遊ぶ方法について私なりのまとめというか備忘録として書いておきます。WS2812というのは、5mm角のパッケージの中にRGBそれぞれのLEDチップとそれを制御するICが乗った、なんといいますか、LEDモジュールですかね。Google先生にWS2812の画像を探してもらうと、こんなものが出てきます。?これ見ただけでもなんかわくわくしますよね。長かったり丸かったり面だったりテープだったりと多彩な使われ方をしております。かんたんなスケッチで自在に光らせることができるのです。WS2812のデータシートはこちらにあります。cost-effective..ポイントは4番目あたりから下かな。RGBの三原色ともに256段階の輝度変化ができるので、16万色出せるよ。付加回路無しで5m以上のデータ伝送できるよ。英語怪しすぎ)とか、1024個つないでも30fpsで駆動できるんだぜ。いったことが書いてあります。イルミネーションと共に、ディスプレイとしての利用も想定してある感じ、というか30fpsとか書いてあるあたりからディスプレイとして使えよという意気込みが伝わってきます(笑で、データシートの後ろの方には「んじゃどうやって色を変えるか」が書いてあります。書くと、まず1bitのデータを送る時間を1.25usに決めて、その中でH/Lを変化させる。その時にHの時間が短い時は0、長い時は1と約束する。データ送り出し元に最も近いWS2812をピクセル1(D1)とし、以下離れるにしたがってピクセル2(D2)、ピクセル3(D3).....とする。データは上に書いてあった通りRGBいずれも256段階の変化なので、それぞれ8bitの情報量。よって、1ピクセルあたり24bitの情報で一つの発光色が決まることになる。こっからがなかなか荒っぽくて、このピクセル毎の24bitデータを、ヘッダもフッタもチェックサムもなんも無しにとにかく繋いでだーっと流す。流れてきたデータをピクセル1(下の図のD1)が頭の24bit抜いて残りをピクセル2(下のD2)に渡す、ピクセル2は同じように頭の24bitを抜いて次に渡す。下の図では24bitx3セットしかデータがないので、D4は何ももらえない。状態が変わらない(=点いてたらその色で点きっぱなし)。データの流れが50usec以上途絶えたらそれまでの話はご破算になって、次にデータが流れて来たらその頭の24bitはピクセル1に対する情報と解釈される。50us以上長いあいだデータが来ないときは「あ、もう終わりなわけね」と話を白紙に戻して最初からやり直すことにする。前の投稿ではテスト用紙配りで説明しましたが、今回はそうめん流しで説明しましょう(笑そうめん流しの竹に沿ってピクセル君たちがずらっと並びます。先生が上流からそうめんを240本流します。ピクセル1君はその中から24本だけ麺をすくいます。ピクセル2君も24本すくいます。以下同じで、この場合はピクセル10君までがそうめんを食べられます。これは単純な場合です。先生がそうめんを24000本流します。ピクセル1君はやはり24本すくってそれを食べます。食べ終わって前を見るとまだそうめんが流れています。24000本も流しますからそう簡単に流れていかないのです。ピクセル1君はそのそうめんをもう一度すくってはいけません。いつ次のそうめんをすくってよいのか。それはそうめんが流れ終わってから50usecたった後に再びそうめんが流れてくる場合です。そうめんの流れが途切れても、途切れた時間が50usecに満たない場合はそれをすくってはいけません。それは自分より後ろの、たぶんピクセル101君が食べるそうめんなのです。すくったそうめん24本の中身はどうなっているのかというと、こうなっています。いうことで、こうやって見ると非常に面倒な制御が必要に見えますが、これらをまとめてライブラリ化がなされていますので実際に使うときは全く気にする必要がありません。それがAdafruit_NeoPixelライブラリです。スケッチで使うためには、インクルードする必要がありますが、IDEからZIPファイル指定するだけなので簡単です。やり方の公式はこちら。他にもGoogle先生に聞けばいくらでも教えてくれます。Adafruit_NeoPixelライブラリをちらと覗いてみます。keywords.txtにはこういう記載があります。KEYWORD2使える命令はこれにつきます。setPixelColorですね。説明はAdafruitのここにありますので、ざっと見ておくと良いです。setup(),setBrightnessと言われると「はいはい明るさの設定ね」と思いがちです。いや実際そうなのですが、これは都度都度使うものではなく、スケッチ全体に対して最初に「上限の明るさはこれね」といったことを決める為のものです。そもそもスケッチ内でいつでもRGB各LEDに対して0-255の明るさ設定ができるのですから、Brightnessを別に設定する必要はないのです。考え方として、NeoPixelの使い方は「色と明るさを指定する」のではなく「RGBそれぞれの明るさを決めることで色が決まる」方式であることを理解することです。pins?というのも役立ちそうです。これは「一度に二つ以上のWS2812グループを駆動することができますか」という質問と同義です。答えは「できる」です。ライブラリの使用を宣言したら、何らかの名前を付けたオブジェクトを作ります。これを複数作ればよいのです。サイバーコンソールではライトバーとUVクリアリングの二つのインスタンスを作っています。一つのスケッチの中で複数のインスタンスを使うことで協調動作をさせることが楽にできます。逆に「バラバラに動いているように見せる」のは難しくなります。pin?これも参考になります。「Arduinoの一つのピンにたくさんWS2812のグループをぶらさげて同じ動作をさせたいけどできる?」という質問です。サイバーコンソールではシートサイドのバーを左右2本使っていますが、二本の入力は同じピンに繋いでいて問題なく動作しています。上記質問に対する答えは「まあ、4つくらいまでならぶら下げてもいいかな」です。親切なことに「4つ以上ぶら下げたいときは、まず一つのピンに4つのピクセル(例えばABCD)をぶら下げて、その4つにそれぞれ4つまでぶら下げればいいよ。Aの下に4つ、Bの下に4つ....といった具合です。この場合は16グループまで一つのピンにぶら下げられることになります。そんなつなぎ方をするときは枝分かれの最初の部分(ABCD)は「バッファとしてのみ使って実際には光らせないといいよ」とあります。ABCDはピンから見ると一番近いピクセル(#0)なので、「最初のピクセルはいつも消灯、それ以降のピクセルはこれこれ、」といった命令を送れとのこと。RAM」なんて記述もありますが、私がする程度のスケールでは関係ありません。フルHDのディスプレイとか作る人は考えとくべき。今回作った動作について説明していきます。スケッチを一度に全部書くとわけわからんくなるので、頭から順に切り出していきます。あと、LCD駆動とか関係ないのも全部落としてWS2812駆動の部分だけにしています。<Adafruit_NeoPixel.h>何はともあれこれです。「NeoPixel使うんだぜ」宣言です。NEO_KHZ800);二つのインスタンスを作ります。サイドバーとUVクリアリングです。サイドバーは「20個のピクセル、8番ピン」UVクリアリングは「4ピクセル、9番ピン」なんとなくわかりますね。ここからはコメントで書いていきます。{//beginはpinMode(pin,mode)みたいなもんです。SideBar.begin();ClearRing.begin();//show命令でデータが送り出されます。ここではまだデータがセットされていないので、全ピクセルが輝度0、つまり消灯します。SideBar.show();ClearRing.show();}セットアップはこんだけ。実際の動作は関数の形で動作ごとにいくつか作りましたので、単純なものから見ていきますが、その前に全体を通じて使っている色指定関数を説明します。それはWheel関数です。Adafruitライブラリについてくるサンプルスケッチの中に入っています。非常に便利なので私もそのまま使わせていただいております。0);}面倒そうですが、ビジュアルで見ると結構簡単です。色の指定には様々方法がありますが、その中の一つに色環による方法があります。色環とはこれのことです。Wheelという名称からも想像できるように、この関数は上の色環を回転方向に256分割し、その値で色を決めようというものです。上の絵で12時方向を0として右回りに256(8bit)分割したとすると、0は黄色を、64は緑を、128は紫?かな、192はオレンジを、といった具合に決まることになります。ここで色が決まっても、これをWS2812のRGBそれぞれ8bitのLEDの輝度に変換してやらないと実際の発色はできないですよね。この変換をやってくれるのがWheel関数なのです。いうことで、Wheelの引数はByte型、つまり8bit=256段階であって、これが上の絵のどれかの色の位置を決めます。するとこの関数は宣言にあるようにunit32_t型で値を返します。これは32bitの値でRの8bit、Gの8bit、Bの8bit、そして実際は使いませんが、Wの8bitからなります。「色を指定すれば、WS2812でその色を出すための各LEDの輝度を教えてくれる」という非常に便利な関数です。これを使うことで、例えば8bitのランダム値を引数として与えれば「色環ルーレットをくるっと回して止まったところの色を出す」といったようなランダムな色変更が簡単にできるようになりますし、8bitをインクリメントしていけば色環をたどるように順に色を変更することも簡単になります。いくつかの動作例を見ていきます。簡単なColorGlowです。スケッチは以下の通り。発光色の指定はアナログポートに接続したボリュームから読み込む10bitアナログ値をWheel用に8bitに圧縮(map関数)して行っています。1);}SideBar.show();ClearRing.show();delay(SpeedDelay);}//別に書いている全部消し関数を呼び出す。turnOffRing();//設定時間待って次の動作へdelay(ReturnDelay);}ポイントは//輝度変更のためにRGBに分解しておくのあたりですかね。先のWheelは便利な関数ですが、戻り値が32bitでRGBの値が一塊になっています。これはこれで便利なのですが、ColowGlowのように「そのままの色でぼわーっとあかるくしたり暗くしたりする」場合にはどうしてもRGB各LEDの個別制御が必要になりますので、一旦32bitの塊をRGBそれぞれ8bitずつにばらしておきたいわけです。そんなことをやっています。あとは、//サインカーブで輝度が上下するようにするこれ。試行錯誤した結果ここに落ち着いています。LEDを「自然な感じに」明るさを上下させるのは結構難しいです。RGBの輝度256段階はPWMのタイミングコントロールですので、光エネルギー的にはリニアな変化をします。一方で人間の感覚は対数的に反応します。これは自然現象の広いダイナミックレンジに対応するための進化の結果ともいえます。対数的な感覚のところにリニアな変化を持ち込むと「急に明るくなる」「明るいまんまで変化が少ない」といった印象を与えることになります。このようなことは別に視覚に限られたことではなく、聴覚でも同じです。ボリュームには抵抗値がリニアに変化するBカーブの他に人間の聴覚感に合わせたAカーブなんてのが存在します。この辺りもGoogle先生がいくらでも教えてくれます。ru);とSideBar.show();だけということになります。これは「引数に従ってRGBの輝度をセットしろ」という命令です。引数の中は(ピクセル番号、R輝度、G輝度、B輝度)になっています。今回のサイドバーのようにピクセルが複数ある場合はfor~nextを回しながらピクセルの数だけRGB輝度をセットしていくことになります。.showでそれを一気にそうめんにして流し込むというわけです。OneWayと名付けた動作です。なんてあたりはすごい邪道なことをやっているような気がしますが、ピクセルが20ですからまあお許しください。ここでのポイントは、//————-で区切られた上下でSideBarとClearRingという二つのインスタンスが協調しつつも別動作をしているところです。ランダムな色変更も一例出しておきます。増えているだけで、あとは同じです。こんな簡単な一行でランダムな色変更ができるようになるのです。最後に現状の全スケッチを下につけておきます。LCDの駆動、アナログボリュームによる動作の選定等いろいろ入っていますのでごちゃごちゃしていますが、参考になるところがありましたらお使いくださいませ。CNC加工機ステッピングモーターのテストステッピングモーターの結線調査とテストを実施。ケーブルは4本出ていますので。二相のバイポーラ駆動と推定。あれば導通するのは二本ずつ二組になっているはず。地デジアンテナを作る姪が小さなテレビを買ったのですが、テレビを置く部屋にアンテナ線の引き込みがありません。アンテナジャックはキッチンを挟んだ反対側。ケーブルを引き回すと10mを超えそうです。何よりかっこ悪いし、危険です。アルミの太い針金(針アルミ?)を買ってきました。磁石もフェライトでドーナツ型の物を探したのですが見つかりませんでした。いうことで今回もネオジム磁石を使います。こんな感じでいく...電子工作LEDライトスタンドの作製レーザ加工機の排気系を改造しましたので、そのテストを兼ねてLEDライトスタンドを作ってみました。LEDライトはここで作ったAitendoのキットを使い、セルスタで買った自在スタンドに取り付けることにします。CO2レーザの計画を話したところ、会社の同好の士がテレビと部品を提供してくださいました。ありがたやありがたや。いうことで、これです。目的はフライバックトランスです。