Adafruit_NeoPixelとFastLEDライブラリのサンプルを撮ってみた<LEDテープ編>
WS2812B LEDテープを愛用している私。
ArduinoだとAdafruit_NeoPixelとFastLEDライブラリが基本と思います。
LEDテープの点灯パターンの参考になりそうなサンプルスケッチを片っ端から動作させてみて動画記録してみました。
環境
WS2812B 32個
Seeeduino XIAO
Adafruit_NeoPixel Ver.1.8.0
FastLED Ver.3.4.0
LEDを撮影するのは難しく、なるべく色変化がわかりやすいように透明プラ板を横に置いて反射させてみました。
BRIGHTNESSの設定は20くらいに下げています。
目次
Adafruit_NeoPixel
FastLED
Adafruit_NeoPixel
Adafruit_NeoPixelとFastLEDライブラリのサンプルスケッチの動作動画をあげていこうと思います。まずは
— PikaPikaらいと (@KPmilk3) 2021年5月15日
Adafruit_NeoPixelのRGBWstrandtest pic.twitter.com/Hr07JM3UyM
Adafruit_NeoPixelのstrandtest pic.twitter.com/As3loF4ity
— PikaPikaらいと (@KPmilk3) 2021年5月15日
Adafruit_NeoPixelのstrandtest_wheel pic.twitter.com/eB5xbVqgXK
— PikaPikaらいと (@KPmilk3) 2021年5月15日
FastLED
FastLEDのColorPalette pic.twitter.com/F8pq71gmSg
— PikaPikaらいと (@KPmilk3) 2021年5月15日
FastLEDのColorTemperature pic.twitter.com/jTS12UKLv5
— PikaPikaらいと (@KPmilk3) 2021年5月15日
FastLEDのCylon pic.twitter.com/185w4Kqj1S
— PikaPikaらいと (@KPmilk3) 2021年5月15日
FastLED の DemoReel100 pic.twitter.com/2bTOtSDuBR
— PikaPikaらいと (@KPmilk3) 2021年5月15日
FastLED の Fire2012 pic.twitter.com/PXLZkVE2na
— PikaPikaらいと (@KPmilk3) 2021年5月15日
FastLED の Pacifica pic.twitter.com/hkZ04UOp2a
— PikaPikaらいと (@KPmilk3) 2021年5月15日
FastLED の Pride2015 pic.twitter.com/Wdk86Efbfz
— PikaPikaらいと (@KPmilk3) 2021年5月15日
FastLED の RGBSetDemo pic.twitter.com/pozKWeZaYr
— PikaPikaらいと (@KPmilk3) 2021年5月15日
FastLED の TwinkleFox pic.twitter.com/L31Bg8dUVN
— PikaPikaらいと (@KPmilk3) 2021年5月15日
【作品まとめ】M5Stackでかめはめ波
ホログラム で面白いことできないかなと思っていた時にこれを見ました。 www.youtube.com
こんな凄いことは簡単にはできないけど、M5Stackを使ってそれっぽいことはできるんじゃないかと思って作った作品。
M5Stackでホログラム その6
— PikaPikaらいと (@KPmilk3) 2021年3月7日
すごい動画みて、かめはめ波に挑戦したくなった。
あらゆるレベルの低さを痛感しつつも、最初の一歩として記録。ここからマイコンならではのエフェクトを考えてみようhttps://t.co/nyve34I9Jo @YouTubeより#M5Stack #ホログラム #LovyanGFX pic.twitter.com/SZaAH00HsO
M5Stackでホログラム その7
— PikaPikaらいと (@KPmilk3) 2021年3月10日
かめはめ波のあのシーンに挑戦。
マイコンの基本技、Lチカを活用。
日本語表示、さらに鏡に写すため反転表示という難題もLovyanGFXの力でなんなくクリア。
もう少し時間かけて作品に仕上げたい。#M5Stack #ホログラム #LovyanGFX pic.twitter.com/S1gsviEZFV
M5Stackでかめはめ波
— PikaPikaらいと (@KPmilk3) 2021年3月28日
影絵バージョン#M5Stack #かめはめ波 #影絵 pic.twitter.com/iQCbFjO9oU
LEDテープでメビウスの輪を作った
1メートルのRGB LEDテープを点灯させて遊んでいたら、ふと思いついた。
「これでメビウスの輪を作ったら面白そう。」
作ってみました。
ふと思いついてLEDテープでメビウスの輪を作ってみた。
— PikaPikaらいと (@KPmilk3) 2021年5月10日
WS2812B 144個をM5Atomで制御するのはFastLEDライブラリじゃないと無理でした😓 pic.twitter.com/In177S3MhV
材料
WS2812B LEDテープ
Arduinoマイコンボード M5Atom Lite www.switch-science.com M5Atom Lite との接続にはGroveケーブルを使用しました。
LEDテープをメビウスの輪の形にする
まず最初にLEDテープについているごっついコネクタケーブルを外して、M5Atomに簡単に接続できるGroveケーブルに付けなおします。
まっすぐ半田付けすると切れやすいので、あえて逆方向につけて折り返すという小技を使っています。
メビウスの輪にするなら裏表にLEDが配置されるようにしないと意味ないので、テープを半分の長さで折り曲げます。最初は単純に折り曲げてしまおうと思ったのですが、このLEDテープはちょうど半分のところではんだ付けされていました。
72個分のLEDがのっている基板を2枚つないで作られています。冷静に考えると、こんな長い基板どうやって作ってどうやって部品実装しているのだろう??
ハンダをいったん外して裏表にしてはんだ付けしなおします。基板の裏側にもランドがあるので、簡単でした。
両面テープで貼りつけましたが、シリコンチューブだと粘着が弱いので、ところどころセロテープでぐるぐる巻いてみました。
これをひとひねりしてメビウスの輪になるように端と端をつなぎます。セロテープだけでつなぐのは無理だったので、プラバンを補強板にしてセロテープで巻きました。
点灯プログラム
メビウスの輪なのでLED1灯がエンドレスでぐるぐる回るような動きをさせたい。単色では味気ないので、レインボウカラーに変化しながら。
これをM5AtomLiteでプログラムするわけですが、、、
前から気付いていました、M5Stack(ESP32)でAdafruit_NeoPixelライブラリは完璧には動かない事を。
LEDの数が少ない場合はまぁまぁ動きますが、LEDの数が多いと誤動作が目立ちます。
これまでLEDの数が多い場合は別のマイコン(XIAOとか)を使うなどしてしのいでいましたが、この機に向き合うことにしました。
ネット情報からESP32ではFastLEDライブラリを使うといいらしい。
https://github.com/FastLED/FastLED
とりあえずこのライブラリをインストールし、スケッチ例を適当に開いて、ピン番号とLED数だけ変えてM5Atomで動かしてみると、ちゃんとそれらしい動きでLEDが点灯しました
スケッチ例のCylonを動かすとレインボウに変化する点灯動作をしたので、色の変化はこれをマネすれば行けそうです。
あとは1灯を順番に点灯させていくだけですが、メビウスの輪になっているので単純に0~143をつければいいわけではありません。
図に書いて見るとこんな感じになります。
この変則的な並びをいったん配列に入れておいて、loop()はなるべくシンプルになるようにしてみました。
#include <FastLED.h> #define NUM_LEDS 144 #define DATA_PIN 26 #define DELAYVAL 20 #define BRIGHTNESS 200 CRGB leds[NUM_LEDS]; uint16_t array_conv[NUM_LEDS] ; void setup() { LEDS.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS); LEDS.setBrightness(BRIGHTNESS); uint16_t j = 0; for (int i = 0; i < NUM_LEDS / 2; i++) { array_conv[j] = i; j++; } for (int i = NUM_LEDS - 1 ; i > NUM_LEDS / 2 - 1; i--) { array_conv[j] = i; j++; } } void loop() { static uint8_t hue = 0; for (int i = 0; i < NUM_LEDS; i++) { FastLED.clear(); leds[array_conv[i]] = CHSV(hue++, 255, 255); FastLED.show(); delay(DELAYVAL); } }
虹色を作っているのは CHSV(hue++, 255, 255)
これでどうやってレインボウカラーの変化になるのか理解してません ^^;
FastLEDに関してはこれからじっくり触っていきたいと思います。
TWELITE CUEとM5Atomで玄関のカギの開閉状態監視システムを作った
初めに
外出先で「玄関のカギかけたっけ?」となる心配性な私。鍵の状態をスマホでチェックすることができたら超便利だと思う。
Qrio みたいなスマートロックを付けるという方法もあるが、開け閉めまでできなくてもいい(なんか不安だし。そんな私は心配性)
単純にカギかかっているかだけを確認できる仕組みが欲しい。
今年のゴールデンウィークもどこにも行けそうになくてヒマそうなので、自作してみた。
設計図
うちの玄関ドアのカギは2か所についているので2つモニターする必要あり。
開発環境、アプリバージョン
windows10
ArduinoIDE v1.8
TWE Programmer v3.7.5
App_Wings_MONOSTICK_BLUE_L1304_V1-1-4.bin
TWELITEについて
モノをつなぐ無線マイコンモジュール TWELITE-トワイライト - MONO-WIRELESS.COM
TWELITEはIEEE802.15.4(2.4GHz)規格の無線マイコンで、手軽に複数の子機の無線網を構築できるのが特徴です。
自分的には5年ほど前、まだモノワイヤレス株式会社に分社化される前の東京コスモス電機の時代にTWELITEをいくつか使用したことがありました。その時はTWELITE 2525(ニコニコ)という、コイン電池で動いて加速度が取れるモジュールを3Dプリンタのフィラメントロールにつけて、3Dプリンタが途中で止まっていないかをロールの回転による加速度変化でモニターして、止まったらアラームを出すといったことをしたりしてました。
今回、鍵のモニターも2525に磁気センサつければできるなと漠然と考えていて、久しぶりにTWELITEのホームページを見たところ、すごく進化していて、新製品がいっぱいでした。
そして2525はすでに新規採用非推奨品となっていたのですが、なんと後継機TWELITE CUEは磁気センサを搭載しているではないですか。モノワイヤレスさん素晴らしいです。
加速度、磁石センサータグ TWELITE CUE-トワイライトキュー | MONO-WIRELESS.COM
材料
製品名 | 価格 | 用途 |
---|---|---|
M5Atom Lite | 1287円 | Wi-Fiでインターネット接続 |
TWELITE CUE(Blue) | 2481円 x2台 | 無線子機(磁気センサ) |
TWELITE DIP(Blue) | 1980円 | 無線親機 |
TWELITE R2 | 1500円 | TWELITEの設定、アプリ変更に必要 |
価格は2021/5/5現在のものです。
TWELITEには標準出力のBLUEと高出力タイプのREDがあります。値段的にREDのほうが1.5倍くらい高いです。
自分はTWELITE DIP(旧製品の基板アンテナ型)とTWELITE R(2でなく旧型)とM5Atomを持っていたので、今回購入したのはTWELITE CUE2台だけです。
その他必要なもの
- コイン型電池(CR2032) 2個:TWELITE CUE用
- ブレッドボード:TWELITE DIPとM5Atom の接続用
- マジックテープ:TWELITE CUEをドアに貼り付ける用
作り方
TWELITE CUEの設定
設定変更はインタラクティブモードで行います。
TWELITE CUEにTWELITE R2を接続し、TWELITE STAGE APPを使えばできるようです。その辺はホームページに詳しく記載されているので省略します。
自分の場合は旧製品であるTWELITE Rを使ったために、すんなりはいきませんでしたが、ちゃんと旧製品も使えるように詳細情報が記載されていました。モノワイヤレスさんのこういうところは信頼できてよいです。
USBアダプター TWELITE R-トワイライター - MONO-WIRELESS.COM
TWELITEプログラマというソフトを使うことで、TWELITE RでもCUEとの接続ができました。
肝心の設定内容ですが、変更するのは少なくとも4か所です。
これが初期設定値ですが、変更するのは
a アプリケーションID
このIDが同じ端末同士で通信を行います。
初期値のままでもいいですが、もしもご近所でTWELITEを使っている人がいた場合、お互いに迷惑かけることになるので違う番号に変更
したほうがいいでしょう。(もし近所で使っている人がいればお友達になりたいですが)
使える番号には制約があります。詳細はこちら
TWELITE APPS - インタラクティブモード - MONO-WIRELESS.COM
i 論理デバイスID
子機につけるナンバーです。同じセンサーの子機が複数あってもこの番号で個体識別できます。
今回は2台の子機を使うので、1
と2
に設定しておきます。
t 送信間隔の設定
定期送信の送信間隔を秒単位で設定します。1〜4095の値で指定可能。
初期値は5なので5秒おきに通信されます。これはあくまで定期送信の話で、開閉センサーパルモードの場合、磁気センサの値に変化があった場合にも送信してくれます。なので定期送信は別になくてもよく、最大の4095秒(68分)でもいいのですが、 送信受信で取りこぼしが出る可能性を考えると60
秒くらいが適当かと思います。(心配性アゲイン)
p センサ固有パラメータの設定
これは今回、開閉センサーパルモードを使うので、04000000
を設定します。
設定変更後はコマンド S
で忘れずに保存しましょう。
TWELITE CUEの設置
TWELITE DIPの設定
TWELITE DIPはまず親機用のアプリを書き込む必要があります。
書き込むのは親機・中継機アプリ(App_Wings)
です。ホームページではMONOSTICK 用とありますが、TWELITE DIPに書き込んでも特に問題なく動きました。
TWELITE R2とTWELITE STAGE APPを使えば多分簡単にできることでしょう。
アプリを書き込んだらインタラクティブモードで設定変更をします
これが初期設定値です。
変更するのは a アプリケーションID
だけです。CUEに設定した番号と同じものに変更します。
TWELITE DIPとM5AtomLiteの配線
Groveコネクタ使って配線できればよいのですが、TWELITEの電源は3.3VなのでGroveの5V電源は使えません。
M5Atomの背面のソケットピンを使うことになりますが、ブレッドボードを使うのが簡単です。(ワイヤーで結線してももちろんかまいません)
接続はわずか3ピンでOK。電源(3.3V)とGNDとTWELITEのUART TX→M5AtomのUART RXです。
M5AtomLiteのプログラム
電文のデコード
まず受信電文を確認するために、単純に受信した値をそのままprintさせてみます。
#include "M5Atom.h" void setup() { M5.begin(true, false, true); Serial.begin(115200); Serial2.begin(115200, SERIAL_8N1, 21, 25);// RX=21 TX=25(TXは使わないので適当) } void loop() { char c; if (Serial2.available() > 0 ) { c = Serial2.read(); Serial.print(c); } }
CUEに磁石をつけたり離したりして通信が来るのを確認します。
こんな電文が確認できました。
:800000004E0006810BFF090180810311300802099C1130010204A900000001026D42 :80000000480007810BFF090180810311300802099C1130010204A900000001005D59 :800000006C000B810BFF090180810311300802099C1130010204F70000000101B08F :800000006F000C810BFF090180810311300802099C1130010204BA00000001818078
バイナリをアスキーにした電文が来ます。
電文の詳細はホームページに記載されています。パルアプリ - WINGS
必要な情報は3つ
番号5 送信元の論理デバイスID
番号d データ(子機の電池電圧(mV))
番号n データ(磁気センサの状態 )
0x00=近くに磁石がない
0x01=N極が近い
0x02=S極が近い
0x80= 定期送信
今回は磁気センサしか使っていないので、単純に:から始まる電文の文字数で必要なデータを取り出すことができます。
余裕があれば拡張性がある作りにしたいところでしたが、今回はとりあえず決め打ちでプログラムしました。(とりあえずで作ったプログラムが直されることはほぼないが)
IoTサービスへの考慮
センサーからデータ受信するたびにIoTサービスへインターネット通信するのが最も簡単ですが、フリーで使えるIoTサービスはデータの更新間隔や一日のデータ数などに制約があることがほとんどです。
とあるフリーのIoTサービスは1日3,000件(約30秒間隔)、データの送信は最低5秒あける必要があるとの条件でした。それを考えると単純に受信したら投げるという作りにはできません。その条件を満たす実装を考えます。
基本的には1分程度に1回、定期的にその時の状態を送るでいいと思いますが、問題はカギが開き閉めされた時です。
1分に1回だとその間の開き閉めを見逃す可能性があります。それは避けたい。 特にドアの上側のカギはメインで使われるので、ここが閉→開の動きをした場合は確実にデータアップしたい。
そういった考えを盛り込んで最終的なプログラムをしました。コード
Wi-Fi接続およびIoTサービスへのデータ送信に関してはあえて省いています。(あまりにプライベートなものなので) ここまで出来る人であればこの先のIoT化はできるでしょう。
#include "M5Atom.h" #define SENSOR_NUM 2 #define OPEN 1 #define CLOSE 0 uint8_t door_lock[ SENSOR_NUM ] = {0}; uint16_t batt_vol[ SENSOR_NUM ] = {0}; unsigned long send_time = 0; uint8_t door1_before = CLOSE; void setup() { M5.begin(true, false, true); Serial.begin(115200); Serial2.begin(115200, SERIAL_8N1, 21, 25);// RX=21 TX=25 send_time = millis(); } void loop() { char str[70]; //受信用配列 int str_len; unsigned long now_time; if (Serial2.available() > 0 ) { str_len = Serial2RecvStr(str); if (str_len != 69) { return; } //Serial.println(str); char id[] = {str[23], str[24], '\0'}; char bat[] = {str[39], str[40], str[41], str[42], '\0'}; char door[] = {str[64], '\0'}; int id_num = atoi(id); int bat_mv = strtol(bat, 0, 16); int d_num = atoi(door); switch (id_num) { case 1: if (d_num == 0 ) { door_lock[0] = 0; //door close door1_before = CLOSE; M5.dis.drawpix(0, 0x000000); } else { door_lock[0] = 1; //door open M5.dis.drawpix(0, 0x00f000);//開いている場合赤LED点灯 if (door1_before == CLOSE) { while (1) { now_time = millis(); if (send_time > now_time) { //飽和対策 send_time = 5000; } if (now_time - send_time > 5000) { send_mes(); break; } } } door1_before = OPEN; } batt_vol[0] = bat_mv; break; case 2: if (d_num == 0 ) { door_lock[1] = 0; //door close } else { door_lock[1] = 1; //door open } batt_vol[1] = bat_mv; break; } } now_time = millis(); if (send_time > now_time) { //飽和対策 send_time = 60000; } if (now_time - send_time > 60000) { send_mes(); } } void send_mes(void) { Serial.print("door1 = "); Serial.println(door_lock[0]); Serial.print("bat1 = "); Serial.println(batt_vol[0]); Serial.print("door2 = "); Serial.println(door_lock[1]); Serial.print("bat2 = "); Serial.println(batt_vol[1]); /* ここにIoTサービスへのデータ送信を記述すればよい */ send_time = millis(); } int Serial2RecvStr(char *buf) { int i = 0; char c; if (Serial2.available() > 0 ) { c = Serial2.read(); if (i == 0 ) { if (c == ':') { buf[i] = c; i++; } else return 0; } while (1) { if (Serial2.available() > 0 ) { c = Serial2.read(); if ( (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') ) { buf[i] = c; i++; } else { return 0; // ERROR } if (i == 69) { buf[i] = '\0'; return i; } } } } }
動作の様子
カギの開閉状態を無線で取得する事が出来た。
— PikaPikaらいと (@KPmilk3) 2021年5月4日
ここまで出来ればあとはWi-FiでIoTサービスにデータ送れば、カギ監視システムの完成だ。#TWELITE #M5Atom pic.twitter.com/cSZu0mjiuR
TWELITE DIPとM5AtomLiteの設置
電源はM5AtomのUSB端子で給電しますのでUSB電源ポートが必要です。
自分は最初、ドアから距離5mほど高さ2mほどにあるWi-Fiルータ(通称:カニルータ)のそばに置いてみたのですが、下側のカギにつけたセンサからの無線が不安定でした。上側のカギは問題なし。無線機の特性として地面に近いところに設置したものは通信距離が悪くなるので、多分そのせいだと思います。設置場所を変えてドアの近くに設置したら両方とも問題なく受信できました。Wi-Fiはカニルータのおかげもあって余裕でつながりました。
ブレッドボードに挿してあるだけなので、テープで固定してタッパ的なケースに入れて完成としました。
最後に
今回はカギの状態だけを見ていますが、M5AtomのGroveコネクタも空いていることなので、何か他のセンサを追加して本格的なIoTをしてみるのも面白いと思っています。
今回のプログラミングはいわゆるゲートウェイを作るもので普段なじみがなく、我ながら不細工なコードだと思いますが、目標の期間で動くものができたのでよしとします。
TWELITE CUEの電池寿命はホームページページによると「1日に200回の開閉を行なった場合、約4年です。」とありますが、実際にどのくらい持つのか楽しみです。
稼働日:2021/5/4
立方体万華鏡をLEDテープを使ってピカピカさせてみた
立方体万華鏡 CUMOS
ヤマザキミノリ氏
が発明された立方体万華鏡 CUMOS という、鏡を6面組み合わせて作る、とても幻想的な万華鏡があります。
立方体万華鏡CUMOSから光のオブジェ、空間演出デザイン、光のインスタレーションまで一貫して展開。海外国内でふしぎなのぞき箱ワークショップ開催、アートアクティビティも多数。 pic.twitter.com/4ztAdAG5ZH
— ヤマザキミノリ Minori Yamazaki (@MinorinY) 2018年10月21日
私がCUMOSを最初に知ったのはこのツイートです。作り方の動画もありました。
こちらでは色を付けるのにマジックを使っていますが、これをカラーLEDでやったらキレイなんじゃないかと思って実際に作ってみました。先日バズった「立方体万華鏡」ですが、ヤマザキミノリ名誉教授に確認を取り、当館公式YouTubeに作り方を公開させていただけることとなりました!
— 佐賀県立宇宙科学館 (@saga_space) 2020年8月2日
この動画を見て、ぜひおうちでもチャレンジしてみてください!(自分の目で見ると本当に感動します✨)https://t.co/u4jHGonBY1 pic.twitter.com/GXgxnt6END
材料
- 正方形のアクリル鏡 6個
自分は100円ショップ(キャン★ドゥ)で購入しました。 WS2812B LEDテープ
LEDの間隔が狭いもののほうがいいと思います。 自分が使ったのはこちらArduinoマイコンボード
自分が使用したのは M5Atom Lite です。 www.switch-science.com M5Atom Lite との接続にはGroveケーブルを使用しました。
作り方
まずはCUMOSを作成します。
CUMOSの作り方を紹介しているページがありますので、そちらを参考にして作成しました。
おうちで自由研究道場【立方体万華鏡】
国立大学56工学系学部ホームページ
こちらではマジックやセロハンで色を付けていますが、その代わりにLEDテープを使用します。
鏡に線傷をつけたところにWS2812B LEDテープ を貼ります。
WS2812B LEDテープ はハサミで好きなところをカットして分割できるようになっていますので、鏡の大きさに合わせてカットし、ワイヤーをはんだ付けして配線します。 こんな感じです。(雑な工作ですいません)
M5Atom Lite への接続はGroveケーブルの片方を直接LEDテープ にはんだ付けしました。
これでハードは完成です。
コード
ArduinoでプログラムしてLEDテープを点灯させるわけですが、
Adafruit_NeoPixelライブラリのサンプルプログラムをそのまま使うのが簡単です。
ただし、M5Atomに使われているESP32マイコンだとAdafruit_NeoPixelライブラリは完璧には動作しません。LEDの数が多いと誤点灯します。今回は誤点灯してもそれほど影響ないので、このライブラリを使いました。
github.com
githubからライブラリのZIPをダウンロードし、ArduinoIDEにてライブラリインクルードをします。
サンプルプログラムのstrandtestがいい感じの点灯パターンです。
修正するのは2か所だけ。LED制御信号のピン番号とLEDの数の設定だけ直せばOKです。
LED_PIN はM5AtomのGroveポートの26番ピンを使っているので26に、
LED_COUNT は今回72個使っているので、そのように修正します。
// Which pin on the Arduino is connected to the NeoPixels? // On a Trinket or Gemma we suggest changing this to 1: //#define LED_PIN 6 #define LED_PIN 26 // How many NeoPixels are attached to the Arduino? //#define LED_COUNT 60 #define LED_COUNT 72
プログラムを書きこめば完成です。
strandtestによる点灯パターンの様子はこちら
裏側がどうなっているかお見せします。作り方のブログ記事も作成中です。 pic.twitter.com/cnebAc9xuf
— PikaPikaらいと (@KPmilk3) 2021年5月2日
消費電流確認
WS2812B LEDテープを使用するときは消費電流に気を付ける必要があります。
strandtestプログラムで72個使った場合の消費電流を簡易的にUSB電流計で測ってみました。
M5Atomの分も含めて最大320mA@5V でした。結構大きいですが普通のモバイルバッテリーで給電可能な値でした。
これ以上だとちょっと気にしないといけないと思うので、プログラム改造するときはこれ以上明るくしないよう注意必要と思います。
ツイッターにあげた動画
#MFKyoto2021 #作品発表
— PikaPikaらいと (@KPmilk3) 2021年5月1日
立方体万華鏡CUMOS をLEDテープでピカピカさせたものです。
アートという事で。 pic.twitter.com/Hzqrl7YFA1
#立体万華鏡 #cumos はヤマザキミノリ名誉教授の考案だそうです。素晴らしいアイデアに敬服します。
— PikaPikaらいと (@KPmilk3) 2021年2月8日
自分はこちらの動画の作り方を見て、カラーペンの代わりにカラーLEDテープを貼ってプログラムでチカチカできるようにしました https://t.co/n5sWyPivqu pic.twitter.com/lNiy9Gt5WH
こちらの #立体万華鏡 をLEDテープ使って作ってみました。
— PikaPikaらいと (@KPmilk3) 2021年2月5日
点灯パターン変えても面白そう。 https://t.co/07MKSZ71Wc pic.twitter.com/FyeP4kq56B
#立体万華鏡 #万華鏡
— PikaPikaらいと (@KPmilk3) 2021年2月9日
外と内の世界はこんなにも違う pic.twitter.com/1HD0D2qi9W
#万華鏡 #立体万華鏡
— PikaPikaらいと (@KPmilk3) 2021年2月8日
ランダム点灯にしてみた。 https://t.co/i0oAhP1uPX pic.twitter.com/UDl4EVUmPo
#立体万華鏡
— PikaPikaらいと (@KPmilk3) 2021年2月9日
全体が徐々に変化するパターン
これもなかなかいい感じ😃 pic.twitter.com/bdzBZb7Anb
UNIT-VでopenMV使ってIMEモード判別してみた
初めに
ブラインドタッチができない人間(私)が日々悩まされている、「日本語モードだと思って打っていたら英数モードだった(その逆もしかり)問題」の対策として「あ」or「A」を判別させるAIカメラの作成に取り掛かった。
ファーストステップとしてM5StickVのV-Trainingで狙いの動作をさせることができた。詳細は以下の記事にて。
pikapikalight.hatenadiary.com
M5StickVにはLCDとバッテリーがついていて便利なのだが、今回やりたいことに対してはこの機能は不要、むしろいらない機能といえる。 今回の目的に対してはUNIT-Vを使うのが最適なので、セカンドステップとしてUNIT-Vで同じものを作ることにした。
エッジAIの挫折
M5StickVでは割とすんなりできたので、UNIT-Vでも簡単にできると思って始めたのだが、これが予想外の苦戦を強いられる。
V-Trainingは学習曲線を見るかぎり問題なく学習できていそうなのだが、そのKモデルをUNIT-Vにいれて動かすと正答率がすこぶる悪い。カメラの位置、角度をシビアに調整してやっと正解が出るといった具合で、使い物にならないレベル。
写真の撮り方、写真サイズ、ブライトネス、コントラスト、色々変えてみたりしたが、うまくいかず。果てはV-Trainingを使わず、自力で学習してモデル作成するということもやってみたが、それでもやっぱり実機動作で正答率悪し。
そのあたりのいきさつはこちら。
V-TrainingでのUNIT-Vの画像判別がうまくいかないので、自力で学習させる方法ないかと検索したら、からあげ先生の記事に行きつく。
— PikaPikaらいと (@KPmilk3) 2021年4月13日
困った時はだいたいたどり着くからあげ先生。ありがたや。https://t.co/MxS8OZnid1
結局はAIによる判別はあきらめたのですが、Google Colaboratoryを使っての自力学習の方法など非常に得たものは大きかったので、詳細は別の記事にしたいと思います。V-Trainingを使わない、M5UNIT-V用のモデルの自力作成。
— PikaPikaらいと (@KPmilk3) 2021年4月14日
からあげ先生の記事にリンクされていたNabeshinさん作の修正版コードを使わせていただき、なんとか学習とモデル変換できました😁
ただ、学習結果がダメダメ😓これは写真の撮り方が悪いのだと思うのでやり直す。https://t.co/xdN5j6jrvu
openMVに挑戦
色々と試している過程で必然的にMaixPyの機能について調べることとなったのだが、思っていた以上にいろいろな機能があることが分かった。openMVとやらの機能が使えて、フィルターをかけたり、特定の色の領域を判別させたりと、AI使わなくてもひょっとしてできるかもと思い始めた。
さらに調べるとこのような記事を発見
マーカーシールを使ってメーターの針の位置を読み取るというもの。このマーカーシールを使う方法で今回やりたいことを実現することができた。
概要
- マーカーシールを「あ」の真下に貼る
- sensor.set_auto_gain(False) でオートゲインを無効にする
- MaixPyのしきい値エディタでマーカーのしきい値と「あ」「A」のしきい値を確認
- .find_blobsでマーカーシールの領域を特定
- マーカーシールの領域情報から「あ」の領域を特定し、その領域を切り出す
- 切り出した領域に対して.find_blobsで「あ」「A」の領域サイズを判定
- マーカーシールのサイズと「あ」「A」の領域サイズの比から「あ」を判別(「あ」のほうが明らかにサイズが大きいので区別ができる)
しきい値エディタ
MaixPyでフレームバッファにカメラの絵が出ている状態で メニューの「ツール」→「マシンビジョン」→「しきい値エディタ」→ソースイメージの場所 フレームバッファ でしきい値エディタを起動する。 スライドバーを適当に動かして、マーカーシールのみが表示されるしきい値を確認する。 同じように「あ」「A」のしきい値も確認する
コード
import sensor, image, time #import gc, math from board import board_info from Maix import GPIO from fpioa_manager import fm import sys while 1: try: sensor.reset() #Reset sensor may failed, let's try some times break except: time.sleep(0.1) continue sensor.set_hmirror(1) sensor.set_vflip(1) # run automatically, call sensor.run(0) to stop sensor.set_pixformat(sensor.RGB565) # Set pixel format to RGB565 (or GRAYSCALE) sensor.set_framesize(sensor.QVGA) # Set frame size to QVGA (320x240) sensor.skip_frames(time = 1000) # Wait for settings take effect. #sensor.set_brightness(-2) #sensor.set_contrast(-2) sensor.set_auto_gain(False) #これ重要。無効にしないと周りの明るさで大きく変化してしまう。 #clock = time.clock() # Create a clock object to track the FPS. #LED点灯用 fm.register(35, fm.fpioa.GPIOHS0, force=True) pinout35 = GPIO(GPIO.GPIOHS0, GPIO.OUT) pinout35.value(0) mark_threshold = (0, 100, -128, -28, -128, 127) #マークシールのしきい値 text_threshold = (100, 34, -128, 127, 127, -128) #「あ」のしきい値 while True: img=sensor.snapshot() blobs = img.find_blobs([mark_threshold]) if blobs: for b in blobs: if b.area() > 1000: #ゴミとりのため、小さい領域は無視する。 #print(b) tmp = img.draw_rectangle(b[0:4],color=(0,255,0)) tmp = img.draw_cross(b[5], b[6],color=(0,255,0)) mark_x = b[0] mark_y = b[1] mark_w = b[2] mark_area = b.area() try: tmp = img.draw_rectangle(mark_x,mark_y - int(mark_w*1.5),mark_w,mark_w,color=(0,0,255)) #シールの位置から文字の位置を特定 img2 = img.copy((mark_x,mark_y - int(mark_w*1.5),mark_w,mark_w)) #文字の領域を切り出す blobs2 = img2.find_blobs([text_threshold]) #切り出した領域に対してしきい値判定 if blobs2: for b in blobs2: #print(b.area()) if b.area() > 200: #小さい領域は無視する。 img.draw_rectangle(mark_x+b[0],mark_y - int(mark_w*1.5) + b[1],b[2],b[3],color=(255,255,255)) text_area = b.area()/mark_area #比を計算 print(text_area) if text_area > 0.2: #「あ」の判定基準。実機確認の結果より。 pinout35.value(1) else: pinout35.value(0) except: pass
サードステップ
今回の実施条件は照明がほとんど一定の環境下のもの。照明条件が大きく変わるような条件、例えば直射日光が当たるような場所では正しく動かないはずである。
ホワイトバランスをとるような仕組みがあればより安定した動作ができると思う。今後の検討課題である。
また、「あ」と「A」の区別を領域のサイズ比で行ったが、この判定部分をAIにさせることでより精度の高い判定ができそうな気がする。 マシンビジョンとAIの組み合わせ、なんかカッコいいのでトライしてみたい。
【作品まとめ】M5Stackで霹靂一閃
Twitterにあげていた作品のまとめ
ハーフミラーを使って面白もの作れないかと考えていて思いつきました。M5Stackでホログラム その8
— PikaPikaらいと (@KPmilk3) 2021年3月12日
霹靂一閃#M5Stack #ホログラム #LovyanGFX pic.twitter.com/PluWAKEUue
Yin and Yangの絵はM5Stackライブラリの中のサンプルコードより。 M5Stack\examples\Advanced\Display\Sprite\one_bit_Yin_Yang
これをベースにLovyanGFXを使って上側の絵と下側の絵を別のspriteで作成し、パカッという動きを実現させています。
クモの絵はパワーポイントに入っていた素材を使用。M5Stackで 霹靂一閃 六連
— PikaPikaらいと (@KPmilk3) 2021年3月17日
縦撮りバージョン
クリックすれば全面見れるはず https://t.co/gmfCdPFWS6 pic.twitter.com/ozvvp3zvSV
WS2812を144個使用。M5Stackでは144個の制御ができなかったので、WS2812の制御とM5Stack2台へのタイミング信号の送り出しは別のマイコンで実現。
クモの絵のパカッという動きのプログラムはspriteを理解することで実現。 もしリクエストあればコード公開します。(現状、全然整理してないコードなのでとてもお見せできない)
光モノの工作を色々してきたが、ここにきて影の面白さに目覚めた。M5Stackで 霹靂一閃
— PikaPikaらいと (@KPmilk3) 2021年3月24日
影絵バージョン
RGB LEDテープを使った影絵、楽しい。色々な可能性ありそう😊#M5Stack pic.twitter.com/isG1cRRPaM
舞台裏編
M5Stackでホログラム その8
— PikaPikaらいと (@KPmilk3) 2021年3月12日
霹靂一閃の舞台裏
陰陽は上下で2つのspriteを使って表示。それでパカッとする動きを実現。ミラーフィルム使った瞬間移動は想像よりそれっぽくできた😆
思い付いたら作らずにはいられない。PoCを超えたいとは思うのだが🤔#M5Stack #ホログラム #LovyanGFX https://t.co/fgbYAHmnfB pic.twitter.com/WI5NBRGUBL
M5Stackで 霹靂一閃 六連の舞台裏
— PikaPikaらいと (@KPmilk3) 2021年3月16日
WS2812 144個使用
M5Stackは磁石追加で隙間あけてホワイトボードに貼付
クモのspriteを2つのspriteに座標ずらしてpushする事で分断
こそこそ噂話
M5StackでWS2812を144個制御出来なかったので、別のマイコンも使ったらしいですよ#M5Stack #LovyanGFX https://t.co/gmfCdPFWS6 pic.twitter.com/jhH5NWsCP1
M5Stackで 霹靂一閃
— PikaPikaらいと (@KPmilk3) 2021年3月24日
影絵バージョンの舞台裏
ハード、ソフトは前回の構成をほぼ使い回し。ダンボールステージはこれからも活躍予定 https://t.co/HxQtFN7l6i pic.twitter.com/b8xp5HO3ML