//★NeoPixelライブラリのヘッダーファイル読み込み
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
// Digital IO pin connected to the button. This will be driven with a
// pull-up resistor so the switch pulls the pin to ground momentarily.
// On a high -> low transition the button press logic will execute.
//★Arduino Nano Everyで何番ピンをNeoPixel制御に使いうかの設定、今回は1番ピンを使用
#define LED_PIN 1 // Digital IO pin connected to the NeoPixels.
#define LED_W 8 //Nember of NeoPixels @ Width
#define LED_H 8 //Nember of NeoPixels @ Height
#define LED_COUNT (LED_W * LED_H) // Number of NeoPixels
//★文字用配列の幅設定、1文字幅8画素(=LEDシート幅)、11文字なので8*11
#define STR_W (LED_W * 11) // Number of Strings pixel @ Width
//★文字用配列の高さ設定、1文字高さ8画素(=LEDシート高さ)
#define STR_H LED_H // Number of Strings pixel @ Height
//★”ありがとうございます。”を示す文字配列、点灯箇所を1にセット
boolean pix_str[STR_H][STR_W] = {
{0,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0},
{0,0,1,0,0,0,0,0,0,1,1,0,0,1,0,0,1,1,1,1,0,1,0,0,0,0,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0},
{0,0,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,1,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,1,1,1,1,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0},
{0,1,1,0,1,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0},
{1,0,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0},
{0,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,1,1,1,1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic ‘v1’ (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
float wait_correction = 1.0;
unsigned long pixelPrevious = 0;
//★LED処理間隔用変数に50[msec]をセット
//★画素Queue用変数を初期化(シアター・文字表示時に使用)
//★画素Cycle用変数を初期化(raibow時に使用)
uint16_t pixelCurrent = 0;
//★総画素数用変数に総画素数(=総LED数)をセット
uint16_t pixelNumber = LED_COUNT;
//★画素Chase配列を初期化(7点追尾時に使用)
uint16_t pixelChase[7] = {0};
int square_logidx[] = {0,1,2,3,4,5,6,7,15,23,31,39,47,55,63,62,61,60,59,58,57,56,48,40,32,24,16,8};
int circle_logidx[] = {4,13,14,22,31,39,46,54,53,60,59,50,49,41,32,24,17,9,10,3};
int triangle_logidx[] = {4,12,20,21,29,37,38,46,54,55,63,62,61,60,59,58,57,56,48,49,41,33,34,26,18,19,11,3};
int cross_logidx[] = {4,12,20,28,29,30,31,39,38,37,36,44,52,60,59,51,43,35,34,33,32,24,25,26,27,19,11,3};
//★Arduino Nano Every起動時に一回だけ実行される
Serial.begin(9600); //★シリアル通信のボーレートを9600にセット
while (!Serial); //★初期化完了するまでwait
strip.begin(); // Initialize NeoPixel strip object (REQUIRED) //★strip(NeoPixel)の起動
strip.show(); // Initialize all pixels to ‘off’ //★念のためshow実行、ただしすべてoffのまま
//★比較用文字変数に”SERIAL_COMM:”をセット
String comp_str = “SERIAL_COMM:”;
unsigned long currentMillis = millis();
receive_str = Serial.readString(); //★受信データをreceive_strにセット
//★receive_str先頭とcomp_strが一致であれば
if(receive_str.startsWith(comp_str)){
sub_str = receive_str.substring(comp_str.length()); //★sub_strにcomp_str以降の文字列をセット
//★receive_str先頭とcomp_strが一致しなければ(LED制御用データでなければ)
sub_str = “”; //★sub_strを初期化
Serial.print(“Receive Strings:”);
Serial.println(receive_str); //★受信した文字列をすべてコンソールに表示
Serial.print(“Sub Strings:”);
Serial.println(sub_str); //★sub_strの文字列をコンソールに表示
//★受信した文字の先頭が”SERIAL_COMM:”であれば
if(receive_str.startsWith(comp_str)) {
//★”STOP”時の処理→停止なので各変数を初期化
if(sub_str.startsWith(“STOP”)){
mode = 0; //★表示モード用変数を初期化
pixel_val = 15; //★LED輝度用変数に15をセット
wait_correction = 1.0; //★wait時間補正用変数に1をセット
//★”UP”時の処理→LEDの輝度を上げるための変数調整
if(sub_str.startsWith(“UP”)){
if (color != 0 && mode !=14 && mode !=15){
pixel_val += 16; //★LEDの輝度を+16
if(pixel_val > 255) pixel_val = 255; //★輝度が255超であれば、255をセット
//★”DOWN”時の処理→LEDの輝度を下げるための変数調整
if(sub_str.startsWith(“DOWN”)){
if (color != 0 && mode !=14 && mode !=15){
pixel_val -= 16; //★LEDの輝度を-16
if(pixel_val < 0) pixel_val = 15; //★輝度がマイナス値であれば、15をセット
//★”COLOR”時の処理→LEDの色を変更するための変数調整
if(sub_str.startsWith(“COLOR”)){
if(color > 7) color = 1; //★最後の色を超えたら1(白)に戻す(0(黒)ではない)
pixelCurrent = 0; //★表示順変数を初期化
pixelQueue = 0; //★画素Queue用変数を初期化
//★”MODE”時の処理→表示モードを変更するための変数調整
if(sub_str.startsWith(“MODE”)){
mode++; //★表示モード用変数をインクリメント
if(mode > 17) mode = 0; //★最後の表示モードを超えたら0に戻す
pixelCurrent = 0; //★表示順変数を初期化
pixelQueue = 0; //★画素Queue用変数を初期化
int temp_size = sizeof(pixelChase) / sizeof(uint16_t);
for(int i = 0; i < temp_size; i++){
strip.clear(); //★表示モード変更であれば一度strip(NeoPixel)を初期化
strip.setBrightness(255); //★ブライトネスを最大値に戻す ※ブライトネス調整していると必要
//★”FAST”時の処理→描画速度を速くするための変数調整
if(sub_str.startsWith(“FAST”)){
if(color != 0 && mode != 0){
if(wait_correction > 1.0){
wait_correction -= 1.0; //★wait時間補正用変数を-1する
wait_correction /= 2.0; //★wait時間補正用変数を半分にする
if(wait_correction < 0.125) wait_correction = 0.125; //★wait時間補正用変数が0.125未満であれば、0.125をセット
//★”SLOW”時の処理→描画速度を遅くするための変数調整
if(sub_str.startsWith(“SLOW”)){
if(color != 0 && mode != 0){
if(wait_correction > 1.0){
wait_correction += 1.0; //★wait時間補正用変数を+1する
wait_correction *= 2.0; //★wait時間補正用変数を倍にする
if(wait_correction > 5.0) wait_correction = 5.0; //★wait時間補正用変数が5超であれば、5をセット
//★色用変数にあわせてLEDの色設定→R・G・B各輝度用変数の値をセット
case 0: //★0であれば黒(消灯)→RGBすべてに0をセット
r_val = 0; g_val = 0; b_val = 0;
case 1: //★1であれば白→RGBすべてにpixel_valをセット
r_val = pixel_val; g_val = pixel_val; b_val = pixel_val;
case 2: //★2であれば赤→Rのみpixel_val、GとBは0をセット
r_val = pixel_val; g_val = 0; b_val = 0;
case 3: //★3であれば緑→Gのみpixel_val、RとBは0をセット
r_val = 0; g_val = pixel_val; b_val = 0;
case 4: //★4であれば青→Bのみpixel_val、RとGは0をセット
r_val = 0; g_val = 0; b_val = pixel_val;
case 5: //★5であれば黄色→RとGはpixel_val、Bのみ0をセット
r_val = pixel_val; g_val = pixel_val; b_val = 0;
case 6: //★6であればシアン→GとBはpixel_val、Rのみ0をセット
r_val = 0; g_val = pixel_val; b_val = pixel_val;
case 7: //★7であればマゼンタ→RとBはpixel_val、Gのみ0をセット
r_val = pixel_val; g_val = 0; b_val = pixel_val;
//★RGBのうちの最大値をMAX輝度用変数にセット
max_val = max(r_val, g_val);
max_val = max(max_val, b_val);
//★現時刻-前回処理時刻が設定したLED処理間隔を超えた場合に表示処理
if(currentMillis – pixelPrevious >= pixelInterval) { // Check for expired time
pixelPrevious = currentMillis; // Run current frame
//★NeoPixcel色設定用変数(32bit)にRGBの値をセット
uint32_t main_color = strip.Color(r_val, g_val, b_val);
//★表示用モード変数に合わせて表示用関数&引数設定
switch(mode) { // Start the new animation…
wait_val = (int)(10.0 * wait_correction); //★基準wait時間10msecに補正をかけて
colorWipe(main_color, wait_val); //★色・wait時間設定して、colorWipe関数を実行
wait_val = (int)(100.0 * wait_correction); //★基準wait時間100msecに補正をかけて
temp_size = sizeof(square_logidx) / sizeof(int); //★square_logidx配列のサイズを求める
colorDraw(square_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDraw関数を実行
wait_val = (int)(20.0 * wait_correction); //★基準wait時間20msecに補正をかけて
temp_size = sizeof(square_logidx) / sizeof(int); //★square_logidx配列のサイズを求める
colorDot(square_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDot関数を実行
wait_val = (int)(50.0 * wait_correction); //★基準wait時間50msecに補正をかけて
temp_size = sizeof(square_logidx) / sizeof(int); //★square_logidx配列のサイズを求める
colorChase(square_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorChase関数を実行
wait_val = (int)(100.0 * wait_correction); //★基準wait時間100msecに補正をかけて
temp_size = sizeof(circle_logidx) / sizeof(int); //★circle_logidx配列のサイズを求める
colorDraw(circle_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDraw関数を実行
wait_val = (int)(20.0 * wait_correction); //★基準wait時間20msecに補正をかけて
temp_size = sizeof(circle_logidx) / sizeof(int); //★circle_logidx配列のサイズを求める
colorDot(circle_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDot関数を実行
wait_val = (int)(50.0 * wait_correction); //★基準wait時間50msecに補正をかけて
temp_size = sizeof(circle_logidx) / sizeof(int); //★circle_logidx配列のサイズを求める
colorChase(circle_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorChase関数を実行
wait_val = (int)(100.0 * wait_correction); //★基準wait時間100msecに補正をかけて
temp_size = sizeof(triangle_logidx) / sizeof(int); //★triangle_logidx配列のサイズを求める
colorDraw(triangle_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDraw関数を実行
wait_val = (int)(20.0 * wait_correction); //★基準wait時間20msecに補正をかけて
temp_size = sizeof(triangle_logidx) / sizeof(int); //★triangle_logidx配列のサイズを求める
colorDot(triangle_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDot関数を実行
wait_val = (int)(50.0 * wait_correction); //★基準wait時間50msecに補正をかけて
temp_size = sizeof(triangle_logidx) / sizeof(int); //★triangle_logidx配列のサイズを求める
colorChase(triangle_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorChase関数を実行
wait_val = (int)(100.0 * wait_correction); //★基準wait時間100msecに補正をかけて
temp_size = sizeof(cross_logidx) / sizeof(int); //★cross_logidx配列のサイズを求める
colorDraw(cross_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDraw関数を実行
case 11: //★11であれば十字(1点のみ)
wait_val = (int)(20.0 * wait_correction); //★基準wait時間20msecに補正をかけて
temp_size = sizeof(cross_logidx) / sizeof(int); //★cross_logidx配列のサイズを求める
colorDot(cross_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDot関数を実行
case 12: //★12であれば十字(7点追尾)
wait_val = (int)(50.0 * wait_correction); //★基準wait時間50msecに補正をかけて
temp_size = sizeof(cross_logidx) / sizeof(int); //★cross_logidx配列のサイズを求める
colorChase(cross_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorChase関数を実行
wait_val = (int)(50.0 * wait_correction); //★基準wait時間50msecに補正をかけて
theaterChase(main_color, wait_val); //★色・wait時間設定してtheaterChase関数を実行
wait_val = (int)(50.0 * wait_correction); //★基準wait時間50msecに補正をかけて
rainbow(max_val, wait_val); //★輝度・wait時間設定してrainbow関数を実行
wait_val = (int)(50.0 * wait_correction); //★基準wait時間50msecに補正をかけて
theaterChaseRainbow(max_val, wait_val); //★輝度・wait時間設定してtheaterChaseRainbow関数を実行
wait_val = (int)(500.0 * wait_correction); //★基準wait時間500msecに補正をかけて
strDisp(main_color, wait_val); //★色・wait時間設定してstrDisp関数を実行
wait_val = (int)(100.0 * wait_correction); //★基準wait時間100msecに補正をかけて
strScroll(main_color, wait_val); //★色・wait時間設定してstrScroll関数を実行
// 0, 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, 29, 30, 31,
//32, 33, 34, 35, 36, 37, 38, 39,
//40, 41, 42, 43, 44, 45, 46, 47,
//48, 49, 50, 51, 52, 53, 54, 55,
//56, 57, 58, 59, 60, 61, 62, 63,
//★phyidxは(LEDシートの)物理インデックス
//phyidx(physical index, 8×8 NeoPixel index)
// 7, 6, 5, 4, 3, 2, 1, 0,
// 8, 9, 10, 11, 12, 13, 14, 15,
//23, 22, 21, 20, 19, 18, 17, 16,
//24, 25, 26, 27, 28, 29, 30, 31,
//39, 38, 37, 36, 35, 34, 33, 32,
//40, 41, 42, 43, 44, 45, 46, 47,
//55, 54, 53, 52, 51, 50, 49, 48,
//56, 57, 58, 59, 60, 61, 62, 63,
//★論理インデックス→物理インデックス変換関数、引数は論理インデックス
int logidx2phyidx(int logidx){
//★論理インデックスの下位4itの値が8以上の場合(8~15)
phyidx = logidx; //★物理インデックスは論理インデックスと同じ
//★論理インデックスの下位4itの値が8未満の場合(0~7)
phyidx = (logidx & 0xfffffff0) | (~logidx & 0x7); //★下位3bitのみbit反転(0->7,1->6,…,7->0)
return(phyidx); //★物理インデックスを返す
void colorWipe(uint32_t color, int wait) {
//★pixelInterval(LED処理間隔)とwait時間が異なる場合、pixelIntervalにwait時間をセット
if(pixelInterval != wait)
pixelInterval = wait; // Update delay time
strip.setPixelColor(pixelCurrent, color); // Set pixel’s color (in RAM) //★表示順変数の示すLEDの色設定
strip.show(); // Update strip to match //★点灯
pixelCurrent++; // Advance current pixel //★表示順変数をインクリメント
//★最終LEDまで行ったら表示順変数を0クリア(先頭LEDに戻す)
if(pixelCurrent >= pixelNumber) // Loop the pattern from the first LED
//★描画用関数、引数は配列・サイズ・色・wait時間
void colorDraw(int draw_logidx[], int draw_size, uint32_t main_color, int wait) {
//★pixelInterval(LED処理間隔)とwait時間が異なる場合、pixelIntervalにwait時間をセット
if(pixelInterval != wait)
//★表示順変数が0であれば、すべてのLEDをOFFにする
//★表示順変数を用いてdraw_logidx配列から論理インデックス取得->物理インデックスに変換してその位置のLEDの色設定
strip.setPixelColor(logidx2phyidx(draw_logidx[pixelCurrent]), main_color);
pixelCurrent++; //★表示順変数インクリメント
//★表示順変数が最後(サイズ以上)であれば、表示順変数を0クリア
if(pixelCurrent >= draw_size)
//★1点表示用関数、引数は配列・サイズ・色・wait時間
void colorDot(int draw_logidx[], int draw_size, uint32_t main_color, int wait) {
//★pixelInterval(LED処理間隔)とwait時間が異なる場合、pixelIntervalにwait時間をセット
if(pixelInterval != wait)
strip.clear(); //★すべてのLEDをOFF
//★表示順変数を用いてdraw_logidx配列から論理インデックス取得->物理インデックスに変換してその位置のLEDの色設定
strip.setPixelColor(logidx2phyidx(draw_logidx[pixelCurrent]), main_color);
pixelCurrent++; //★表示順変数インクリメント
//★表示順変数が最後(サイズ以上)であれば、表示順変数を0クリア
if(pixelCurrent >= draw_size)
//★7点追尾用関数、引数は配列・サイズ・色・wait時間
void colorChase(int draw_logidx[], int draw_size, uint32_t main_color, int wait) {
//★pixelInterval(LED処理間隔)とwait時間が異なる場合、pixelIntervalにwait時間をセット
if(pixelInterval != wait)
//★表示順変数を用いてdraw_logidx配列から論理インデックス取得->物理インデックスに変換してその位置のLEDの色設定
strip.setPixelColor(logidx2phyidx(draw_logidx[pixelCurrent]), main_color);
int temp_size = sizeof(pixelChase) / sizeof(uint16_t);
//★画素Chase配列から最も古い表示順変数取得->この値を用いてdraw_logidx配列から論理インデックス取得->物理インデックスに変換してその位置のLEDを黒(消灯)に
strip.setPixelColor(logidx2phyidx(draw_logidx[pixelChase[temp_size-1]]), strip.Color(0, 0, 0));
for(int i = temp_size-1; i >0; i–){
pixelChase[i] = pixelChase[i-1];
pixelChase[0] = pixelCurrent; //★画素Chase配列の[0]に現表示順変数の値をセット
pixelCurrent++; //★表示順変数インクリメント
//★表示順変数が最後(サイズ以上)であれば、表示順変数を0クリア
if(pixelCurrent >= draw_size)
//★シアター用関数、基の記述から変更ないため説明省略
void theaterChase(uint32_t color, int wait) {
if(pixelInterval != wait)
pixelInterval = wait; // Update delay time
for(int i = 0; i < pixelNumber; i=i+3) {
strip.setPixelColor(i + pixelQueue, color); // Set pixel’s color (in RAM)
strip.show(); // Update strip to match
for(int i=0; i < pixelNumber; i=i+3) {
strip.setPixelColor(i + pixelQueue, strip.Color(0, 0, 0)); // Set pixel’s color (in RAM)
pixelQueue++; // Advance current pixel if(pixelQueue >= 3)
pixelQueue = 0; // Loop the pattern from the first LED
//★虹用関数、追記コメント箇所以外は基の記述から変更なし
void rainbow(int bright_val, uint8_t wait) {
if(pixelInterval != wait)
for(uint16_t i=0; i < pixelNumber; i++) {
strip.setPixelColor(i, Wheel((i + pixelCycle) & 255)); // Update delay time
strip.setBrightness(bright_val); //★輝度を設定
strip.show(); // Update strip to match
pixelCycle++; // Advance current cycle
pixelCycle = 0; // Loop the cycle back to the begining
//★虹+シアター用関数、追記コメント箇所以外は基の記述から変更なし
void theaterChaseRainbow(int bright_val, uint8_t wait) {
//★pixelInterval(LED処理間隔)とwait時間が異なる場合、pixelIntervalにwait時間をセット
if(pixelInterval != wait)
pixelInterval = wait; // Update delay time
for(int i=0; i < pixelNumber; i=i+3) {
strip.setPixelColor(i + pixelQueue, Wheel((i + pixelCycle) % 255));
strip.setBrightness(bright_val); //★輝度を設定
for(int i=0; i < pixelNumber; i=i+3) {
strip.setPixelColor(i + pixelQueue, strip.Color(0, 0, 0));
pixelQueue++; // Advance current queue
pixelCycle++; // Advance current cycle
// Input a value 0 to 255 to get a color value.
// The colours are a transition r – g – b – back to r.
//★虹系関数内で使用するWheel関数、基の記述から変更ないため説明省略
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 – WheelPos;
return strip.Color(255 – WheelPos * 3, 0, WheelPos * 3);
return strip.Color(0, WheelPos * 3, 255 – WheelPos * 3);
return strip.Color(WheelPos * 3, 255 – WheelPos * 3, 0);
//★文字スクロール用関数、引数は色・wait時間
//★画素Queue用変数は、文字用配列にて表示開始する幅側(横方向)の開始位置に使用
void strScroll(uint32_t main_color, int wait) {
int sw = STR_W; //表示内容の幅ピクセル
int dh = LED_H; //ディスプレーの高さピクセル
int dw = LED_W; // ディスプレーの幅ピクセル
//★pixelInterval(LED処理間隔)とwait時間が異なる場合、pixelIntervalにwait時間をセット
if(pixelInterval != wait)
for (int h = 0; h < dh; h++) { // 上の行から
for (int w = 0; w < dw; w++) { // 左の列から
if (((pixelQueue + w) < dw) || ((pixelQueue + w) >= (dw + sw))) { // 表示範囲外
continue; //★1文字分そろっていないor表示完了なので、次の列に進む
else if (pix_str[h][w – dw + pixelQueue] == 1) { // 表示位置の データが 1 のとき
temp_color = main_color; //★色設定
else { // 表示位置のデータが 0 のとき
temp_color = strip.Color(0, 0, 0); //★黒(表示 OFF)
//★行・列から論理インデックスを求める->物理インデックスに変換してその位置のLEDの色設定
strip.setPixelColor(logidx2phyidx(h * dw + w), temp_color);
pixelQueue++; // Advance current pixel //★画素Queue用変数をインクリメント(文字用配列の列の位置を一つ右に移動)
//★画素Queue用変数が最後(文字用配列の幅+LEDシートの幅の値以上)であれば、画素Queue用変数を0クリア
if(pixelQueue >= (sw + dw))
pixelQueue = 0; // Loop the pattern from the first LED
//★追記コメント部以外、文字スクロール用関数と同じ
void strDisp(uint32_t main_color, int wait) {
int sw = STR_W; // 表示内容の幅ピクセル
int dh = LED_H; // ディスプレーの高さピクセル
int dw = LED_W; // ディスプレーの幅ピクセル
if(pixelInterval != wait)
for (int h = 0; h < dh; h++) { // 上の行から
for (int w = 0; w < dw; w++) { // 左の列から
if (((pixelQueue + w) < dw) || ((pixelQueue + w) >= (dw + sw))) { // 表示範囲外
else if (pix_str[h][w – dw + pixelQueue] == 1) { // 表示位置の データが 1 のとき
else { // 表示位置のデータが 0 のとき
temp_color = strip.Color(0, 0, 0);
strip.setPixelColor(logidx2phyidx(h * dw + w), temp_color);
pixelQueue+=dw; // Advance current pixel //★画素Queue用変数をLEDシートの幅分加える(文字用配列の列の位置を一文字分移動する)
if(pixelQueue >= (sw + dw))
pixelQueue = 0; // Loop the pattern from the first LED
//★NeoPixelライブラリのヘッダーファイル読み込み
#include
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
// Digital IO pin connected to the button. This will be driven with a
// pull-up resistor so the switch pulls the pin to ground momentarily.
// On a high -> low transition the button press logic will execute.
//★Arduino Nano Everyで何番ピンをNeoPixel制御に使いうかの設定、今回は1番ピンを使用
#define LED_PIN 1 // Digital IO pin connected to the NeoPixels.
//★LEDシートの幅&高さ設定
#define LED_W 8 //Nember of NeoPixels @ Width
#define LED_H 8 //Nember of NeoPixels @ Height
//★LEDの数量設定
#define LED_COUNT (LED_W * LED_H) // Number of NeoPixels
//★文字用配列の幅設定、1文字幅8画素(=LEDシート幅)、11文字なので8*11
#define STR_W (LED_W * 11) // Number of Strings pixel @ Width
//★文字用配列の高さ設定、1文字高さ8画素(=LEDシート高さ)
#define STR_H LED_H // Number of Strings pixel @ Height
//★”ありがとうございます。”を示す文字配列、点灯箇所を1にセット
boolean pix_str[STR_H][STR_W] = {
{0,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0},
{0,0,1,0,0,0,0,0,0,1,1,0,0,1,0,0,1,1,1,1,0,1,0,0,0,0,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0},
{0,0,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,1,0,1,0,1,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,1,1,1,1,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0},
{0,1,1,0,1,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0},
{1,0,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0},
{0,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,1,0,0,0,0,0,0,1,1,1,1,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
};
// Declare our NeoPixel strip object:
//★NeoPixcelをstripとして宣言
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic ‘v1’ (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
//★表示モード用変数を初期化
int mode = 0;
//★色用変数を初期化
int color = 0;
//★LED輝度用変数に15をセット
int pixel_val = 15;
//★wait時間補正用変数に1をセット
float wait_correction = 1.0;
//★前回処理時刻用変数を初期化
unsigned long pixelPrevious = 0;
//★LED処理間隔用変数に50[msec]をセット
int pixelInterval = 50;
//★画素Queue用変数を初期化(シアター・文字表示時に使用)
int pixelQueue = 0;
//★画素Cycle用変数を初期化(raibow時に使用)
int pixelCycle = 0;
//★表示順変数を初期化
uint16_t pixelCurrent = 0;
//★総画素数用変数に総画素数(=総LED数)をセット
uint16_t pixelNumber = LED_COUNT;
//★画素Chase配列を初期化(7点追尾時に使用)
uint16_t pixelChase[7] = {0};
//★四角用の論理インデックス表示順配列の設定
int square_logidx[] = {0,1,2,3,4,5,6,7,15,23,31,39,47,55,63,62,61,60,59,58,57,56,48,40,32,24,16,8};
//★円用の論理インデックス表示順配列の設定
int circle_logidx[] = {4,13,14,22,31,39,46,54,53,60,59,50,49,41,32,24,17,9,10,3};
//★三角用の論理インデックス表示順配列の設定
int triangle_logidx[] = {4,12,20,21,29,37,38,46,54,55,63,62,61,60,59,58,57,56,48,49,41,33,34,26,18,19,11,3};
//★十字用の論理インデックス表示順配列の設定
int cross_logidx[] = {4,12,20,28,29,30,31,39,38,37,36,44,52,60,59,51,43,35,34,33,32,24,25,26,27,19,11,3};
//★setup関数
//★Arduino Nano Every起動時に一回だけ実行される
void setup() {
Serial.begin(9600); //★シリアル通信のボーレートを9600にセット
while (!Serial); //★初期化完了するまでwait
strip.begin(); // Initialize NeoPixel strip object (REQUIRED) //★strip(NeoPixel)の起動
strip.show(); // Initialize all pixels to ‘off’ //★念のためshow実行、ただしすべてoffのまま
}
//★loop関数
//★通常処理はloop関数内に記載
void loop() {
//★比較用文字変数に”SERIAL_COMM:”をセット
String comp_str = “SERIAL_COMM:”;
//★受信文字列格納用変数
String receive_str;
//★抽出文字格納用変数
String sub_str;
//★R・G・B各輝度用変数
uint8_t r_val;
uint8_t g_val;
uint8_t b_val;
//★MAX輝度用変数
uint8_t max_val;
//★wait時間用変数
unsigned int wait_val;
//★現時刻取得
unsigned long currentMillis = millis();
//★シリアル通信で何らかの受信があれば
if(Serial.available()){
receive_str = Serial.readString(); //★受信データをreceive_strにセット
//★receive_str先頭とcomp_strが一致であれば
if(receive_str.startsWith(comp_str)){
sub_str = receive_str.substring(comp_str.length()); //★sub_strにcomp_str以降の文字列をセット
}
//★receive_str先頭とcomp_strが一致しなければ(LED制御用データでなければ)
else {
sub_str = “”; //★sub_strを初期化
}
//★以下シリアルデータ受信後の処理
Serial.print(“Receive Strings:”);
Serial.println(receive_str); //★受信した文字列をすべてコンソールに表示
Serial.print(“Sub Strings:”);
Serial.println(sub_str); //★sub_strの文字列をコンソールに表示
//★受信した文字の先頭が”SERIAL_COMM:”であれば
if(receive_str.startsWith(comp_str)) {
//★以下、sub_strの内容に従って処理
//★”STOP”時の処理→停止なので各変数を初期化
if(sub_str.startsWith(“STOP”)){
mode = 0; //★表示モード用変数を初期化
color = 0; //★色用変数を初期化
pixel_val = 15; //★LED輝度用変数に15をセット
wait_correction = 1.0; //★wait時間補正用変数に1をセット
}
//★”UP”時の処理→LEDの輝度を上げるための変数調整
if(sub_str.startsWith(“UP”)){
//★色が黒以外かつ表示モードが虹系以外であれば
if (color != 0 && mode !=14 && mode !=15){
pixel_val += 16; //★LEDの輝度を+16
if(pixel_val > 255) pixel_val = 255; //★輝度が255超であれば、255をセット
}
}
//★”DOWN”時の処理→LEDの輝度を下げるための変数調整
if(sub_str.startsWith(“DOWN”)){
//★色が黒以外かつ表示モードが虹系以外であれば
if (color != 0 && mode !=14 && mode !=15){
pixel_val -= 16; //★LEDの輝度を-16
if(pixel_val < 0) pixel_val = 15; //★輝度がマイナス値であれば、15をセット
}
}
//★”COLOR”時の処理→LEDの色を変更するための変数調整
if(sub_str.startsWith(“COLOR”)){
color++; //★色用変数をインクリメント
if(color > 7) color = 1; //★最後の色を超えたら1(白)に戻す(0(黒)ではない)
pixelCurrent = 0; //★表示順変数を初期化
pixelQueue = 0; //★画素Queue用変数を初期化
}
//★”MODE”時の処理→表示モードを変更するための変数調整
if(sub_str.startsWith(“MODE”)){
//★色が黒以外であれば
if(color != 0) {
mode++; //★表示モード用変数をインクリメント
if(mode > 17) mode = 0; //★最後の表示モードを超えたら0に戻す
pixelCurrent = 0; //★表示順変数を初期化
pixelQueue = 0; //★画素Queue用変数を初期化
//★画素Chase配列を初期化
int temp_size = sizeof(pixelChase) / sizeof(uint16_t);
for(int i = 0; i < temp_size; i++){
pixelChase[i] = 0;
}
strip.clear(); //★表示モード変更であれば一度strip(NeoPixel)を初期化
strip.setBrightness(255); //★ブライトネスを最大値に戻す ※ブライトネス調整していると必要
}
}
//★”FAST”時の処理→描画速度を速くするための変数調整
if(sub_str.startsWith(“FAST”)){
//★色が黒以外かつ全面表示以外であれば
if(color != 0 && mode != 0){
//★wait時間補正用変数が1超であれば
if(wait_correction > 1.0){
wait_correction -= 1.0; //★wait時間補正用変数を-1する
}
//★wait時間補正用変数が1以下であれば
else {
wait_correction /= 2.0; //★wait時間補正用変数を半分にする
}
if(wait_correction < 0.125) wait_correction = 0.125; //★wait時間補正用変数が0.125未満であれば、0.125をセット
}
}
//★”SLOW”時の処理→描画速度を遅くするための変数調整
if(sub_str.startsWith(“SLOW”)){
//★色が黒以外かつ全面表示以外であれば
if(color != 0 && mode != 0){
//★wait時間補正用変数が1超であれば
if(wait_correction > 1.0){
wait_correction += 1.0; //★wait時間補正用変数を+1する
}
//★wait時間補正用変数が1以下であれば
else {
wait_correction *= 2.0; //★wait時間補正用変数を倍にする
}
if(wait_correction > 5.0) wait_correction = 5.0; //★wait時間補正用変数が5超であれば、5をセット
}
}
//★色用変数にあわせてLEDの色設定→R・G・B各輝度用変数の値をセット
switch(color){
case 0: //★0であれば黒(消灯)→RGBすべてに0をセット
r_val = 0; g_val = 0; b_val = 0;
break;
case 1: //★1であれば白→RGBすべてにpixel_valをセット
r_val = pixel_val; g_val = pixel_val; b_val = pixel_val;
break;
case 2: //★2であれば赤→Rのみpixel_val、GとBは0をセット
r_val = pixel_val; g_val = 0; b_val = 0;
break;
case 3: //★3であれば緑→Gのみpixel_val、RとBは0をセット
r_val = 0; g_val = pixel_val; b_val = 0;
break;
case 4: //★4であれば青→Bのみpixel_val、RとGは0をセット
r_val = 0; g_val = 0; b_val = pixel_val;
break;
case 5: //★5であれば黄色→RとGはpixel_val、Bのみ0をセット
r_val = pixel_val; g_val = pixel_val; b_val = 0;
break;
case 6: //★6であればシアン→GとBはpixel_val、Rのみ0をセット
r_val = 0; g_val = pixel_val; b_val = pixel_val;
break;
case 7: //★7であればマゼンタ→RとBはpixel_val、Gのみ0をセット
r_val = pixel_val; g_val = 0; b_val = pixel_val;
break;
}
//★RGBのうちの最大値をMAX輝度用変数にセット
max_val = max(r_val, g_val);
max_val = max(max_val, b_val);
}
}
//★現時刻-前回処理時刻が設定したLED処理間隔を超えた場合に表示処理
if(currentMillis – pixelPrevious >= pixelInterval) { // Check for expired time
//★前回処理時刻用変数に現時刻をセット
pixelPrevious = currentMillis; // Run current frame
//★NeoPixcel色設定用変数(32bit)にRGBの値をセット
uint32_t main_color = strip.Color(r_val, g_val, b_val);
int temp_size;
//★表示用モード変数に合わせて表示用関数&引数設定
switch(mode) { // Start the new animation…
case 0: //★0であれば全面表示
wait_val = (int)(10.0 * wait_correction); //★基準wait時間10msecに補正をかけて
colorWipe(main_color, wait_val); //★色・wait時間設定して、colorWipe関数を実行
break;
case 1: //★1であれば四角(描画)
wait_val = (int)(100.0 * wait_correction); //★基準wait時間100msecに補正をかけて
temp_size = sizeof(square_logidx) / sizeof(int); //★square_logidx配列のサイズを求める
colorDraw(square_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDraw関数を実行
break;
case 2: //★2であれば四角(1点のみ)
wait_val = (int)(20.0 * wait_correction); //★基準wait時間20msecに補正をかけて
temp_size = sizeof(square_logidx) / sizeof(int); //★square_logidx配列のサイズを求める
colorDot(square_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDot関数を実行
break;
case 3: //★3であれば四角(7点追尾)
wait_val = (int)(50.0 * wait_correction); //★基準wait時間50msecに補正をかけて
temp_size = sizeof(square_logidx) / sizeof(int); //★square_logidx配列のサイズを求める
colorChase(square_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorChase関数を実行
break;
case 4: //★4であれば円(描画)
wait_val = (int)(100.0 * wait_correction); //★基準wait時間100msecに補正をかけて
temp_size = sizeof(circle_logidx) / sizeof(int); //★circle_logidx配列のサイズを求める
colorDraw(circle_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDraw関数を実行
break;
case 5: //★5であれば円(1点のみ)
wait_val = (int)(20.0 * wait_correction); //★基準wait時間20msecに補正をかけて
temp_size = sizeof(circle_logidx) / sizeof(int); //★circle_logidx配列のサイズを求める
colorDot(circle_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDot関数を実行
break;
case 6: //★6であれば円(7点追尾)
wait_val = (int)(50.0 * wait_correction); //★基準wait時間50msecに補正をかけて
temp_size = sizeof(circle_logidx) / sizeof(int); //★circle_logidx配列のサイズを求める
colorChase(circle_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorChase関数を実行
break;
case 7: //★7であれば三角(描画)
wait_val = (int)(100.0 * wait_correction); //★基準wait時間100msecに補正をかけて
temp_size = sizeof(triangle_logidx) / sizeof(int); //★triangle_logidx配列のサイズを求める
colorDraw(triangle_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDraw関数を実行
break;
case 8: //★8であれば三角(1点のみ)
wait_val = (int)(20.0 * wait_correction); //★基準wait時間20msecに補正をかけて
temp_size = sizeof(triangle_logidx) / sizeof(int); //★triangle_logidx配列のサイズを求める
colorDot(triangle_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDot関数を実行
break;
case 9: //★9であれば三角(7点追尾)
wait_val = (int)(50.0 * wait_correction); //★基準wait時間50msecに補正をかけて
temp_size = sizeof(triangle_logidx) / sizeof(int); //★triangle_logidx配列のサイズを求める
colorChase(triangle_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorChase関数を実行
break;
case 10: //★10であれば十字(描画)
wait_val = (int)(100.0 * wait_correction); //★基準wait時間100msecに補正をかけて
temp_size = sizeof(cross_logidx) / sizeof(int); //★cross_logidx配列のサイズを求める
colorDraw(cross_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDraw関数を実行
break;
case 11: //★11であれば十字(1点のみ)
wait_val = (int)(20.0 * wait_correction); //★基準wait時間20msecに補正をかけて
temp_size = sizeof(cross_logidx) / sizeof(int); //★cross_logidx配列のサイズを求める
colorDot(cross_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorDot関数を実行
break;
case 12: //★12であれば十字(7点追尾)
wait_val = (int)(50.0 * wait_correction); //★基準wait時間50msecに補正をかけて
temp_size = sizeof(cross_logidx) / sizeof(int); //★cross_logidx配列のサイズを求める
colorChase(cross_logidx, temp_size, main_color, wait_val); //★配列・サイズ・色・wait時間設定してcolorChase関数を実行
break;
case 13:
wait_val = (int)(50.0 * wait_correction); //★基準wait時間50msecに補正をかけて
theaterChase(main_color, wait_val); //★色・wait時間設定してtheaterChase関数を実行
break;
case 14:
wait_val = (int)(50.0 * wait_correction); //★基準wait時間50msecに補正をかけて
rainbow(max_val, wait_val); //★輝度・wait時間設定してrainbow関数を実行
break;
case 15:
wait_val = (int)(50.0 * wait_correction); //★基準wait時間50msecに補正をかけて
theaterChaseRainbow(max_val, wait_val); //★輝度・wait時間設定してtheaterChaseRainbow関数を実行
break;
case 16:
wait_val = (int)(500.0 * wait_correction); //★基準wait時間500msecに補正をかけて
strDisp(main_color, wait_val); //★色・wait時間設定してstrDisp関数を実行
break;
case 17:
wait_val = (int)(100.0 * wait_correction); //★基準wait時間100msecに補正をかけて
strScroll(main_color, wait_val); //★色・wait時間設定してstrScroll関数を実行
break;
}
}
}
//★logidxは論理インデックス
//logidx(logical index)
// 0, 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, 29, 30, 31,
//32, 33, 34, 35, 36, 37, 38, 39,
//40, 41, 42, 43, 44, 45, 46, 47,
//48, 49, 50, 51, 52, 53, 54, 55,
//56, 57, 58, 59, 60, 61, 62, 63,
//★phyidxは(LEDシートの)物理インデックス
//phyidx(physical index, 8×8 NeoPixel index)
// 7, 6, 5, 4, 3, 2, 1, 0,
// 8, 9, 10, 11, 12, 13, 14, 15,
//23, 22, 21, 20, 19, 18, 17, 16,
//24, 25, 26, 27, 28, 29, 30, 31,
//39, 38, 37, 36, 35, 34, 33, 32,
//40, 41, 42, 43, 44, 45, 46, 47,
//55, 54, 53, 52, 51, 50, 49, 48,
//56, 57, 58, 59, 60, 61, 62, 63,
//★論理インデックス→物理インデックス変換関数、引数は論理インデックス
int logidx2phyidx(int logidx){
int phyidx;
//★論理インデックスの下位4itの値が8以上の場合(8~15)
if((logidx & 0xf) >= 8){
phyidx = logidx; //★物理インデックスは論理インデックスと同じ
}
//★論理インデックスの下位4itの値が8未満の場合(0~7)
else {
phyidx = (logidx & 0xfffffff0) | (~logidx & 0x7); //★下位3bitのみbit反転(0->7,1->6,…,7->0)
}
return(phyidx); //★物理インデックスを返す
}
//★全面表示用関数、引数は色・wait時間
void colorWipe(uint32_t color, int wait) {
//★pixelInterval(LED処理間隔)とwait時間が異なる場合、pixelIntervalにwait時間をセット
if(pixelInterval != wait)
pixelInterval = wait; // Update delay time
strip.setPixelColor(pixelCurrent, color); // Set pixel’s color (in RAM) //★表示順変数の示すLEDの色設定
strip.show(); // Update strip to match //★点灯
pixelCurrent++; // Advance current pixel //★表示順変数をインクリメント
//★最終LEDまで行ったら表示順変数を0クリア(先頭LEDに戻す)
if(pixelCurrent >= pixelNumber) // Loop the pattern from the first LED
pixelCurrent = 0;
}
//★描画用関数、引数は配列・サイズ・色・wait時間
void colorDraw(int draw_logidx[], int draw_size, uint32_t main_color, int wait) {
//★pixelInterval(LED処理間隔)とwait時間が異なる場合、pixelIntervalにwait時間をセット
if(pixelInterval != wait)
pixelInterval = wait;
//★表示順変数が0であれば、すべてのLEDをOFFにする
if(pixelCurrent == 0){
strip.clear();
}
//★表示順変数を用いてdraw_logidx配列から論理インデックス取得->物理インデックスに変換してその位置のLEDの色設定
strip.setPixelColor(logidx2phyidx(draw_logidx[pixelCurrent]), main_color);
strip.show(); //★点灯
pixelCurrent++; //★表示順変数インクリメント
//★表示順変数が最後(サイズ以上)であれば、表示順変数を0クリア
if(pixelCurrent >= draw_size)
pixelCurrent = 0;
}
//★1点表示用関数、引数は配列・サイズ・色・wait時間
void colorDot(int draw_logidx[], int draw_size, uint32_t main_color, int wait) {
//★pixelInterval(LED処理間隔)とwait時間が異なる場合、pixelIntervalにwait時間をセット
if(pixelInterval != wait)
pixelInterval = wait;
strip.clear(); //★すべてのLEDをOFF
//★表示順変数を用いてdraw_logidx配列から論理インデックス取得->物理インデックスに変換してその位置のLEDの色設定
strip.setPixelColor(logidx2phyidx(draw_logidx[pixelCurrent]), main_color);
strip.show(); //★点灯
pixelCurrent++; //★表示順変数インクリメント
//★表示順変数が最後(サイズ以上)であれば、表示順変数を0クリア
if(pixelCurrent >= draw_size)
pixelCurrent = 0;
}
//★7点追尾用関数、引数は配列・サイズ・色・wait時間
void colorChase(int draw_logidx[], int draw_size, uint32_t main_color, int wait) {
//★pixelInterval(LED処理間隔)とwait時間が異なる場合、pixelIntervalにwait時間をセット
if(pixelInterval != wait)
pixelInterval = wait;
//★表示順変数を用いてdraw_logidx配列から論理インデックス取得->物理インデックスに変換してその位置のLEDの色設定
strip.setPixelColor(logidx2phyidx(draw_logidx[pixelCurrent]), main_color);
//★画素Chase配列のサイズを取得
int temp_size = sizeof(pixelChase) / sizeof(uint16_t);
//★画素Chase配列から最も古い表示順変数取得->この値を用いてdraw_logidx配列から論理インデックス取得->物理インデックスに変換してその位置のLEDを黒(消灯)に
strip.setPixelColor(logidx2phyidx(draw_logidx[pixelChase[temp_size-1]]), strip.Color(0, 0, 0));
strip.show(); //★点灯
//★画素Chase配列のデータシフト
for(int i = temp_size-1; i >0; i–){
pixelChase[i] = pixelChase[i-1];
}
pixelChase[0] = pixelCurrent; //★画素Chase配列の[0]に現表示順変数の値をセット
pixelCurrent++; //★表示順変数インクリメント
//★表示順変数が最後(サイズ以上)であれば、表示順変数を0クリア
if(pixelCurrent >= draw_size)
pixelCurrent = 0;
}
//★シアター用関数、基の記述から変更ないため説明省略
void theaterChase(uint32_t color, int wait) {
if(pixelInterval != wait)
pixelInterval = wait; // Update delay time
for(int i = 0; i < pixelNumber; i=i+3) {
strip.setPixelColor(i + pixelQueue, color); // Set pixel’s color (in RAM)
}
strip.show(); // Update strip to match
for(int i=0; i < pixelNumber; i=i+3) {
strip.setPixelColor(i + pixelQueue, strip.Color(0, 0, 0)); // Set pixel’s color (in RAM)
}
pixelQueue++; // Advance current pixel if(pixelQueue >= 3)
pixelQueue = 0; // Loop the pattern from the first LED
}
//★虹用関数、追記コメント箇所以外は基の記述から変更なし
//★引数に輝度を追加
void rainbow(int bright_val, uint8_t wait) {
if(pixelInterval != wait)
pixelInterval = wait;
for(uint16_t i=0; i < pixelNumber; i++) {
strip.setPixelColor(i, Wheel((i + pixelCycle) & 255)); // Update delay time
}
strip.setBrightness(bright_val); //★輝度を設定
strip.show(); // Update strip to match
pixelCycle++; // Advance current cycle
if(pixelCycle >= 256)
pixelCycle = 0; // Loop the cycle back to the begining
}
//★虹+シアター用関数、追記コメント箇所以外は基の記述から変更なし
//★引数に輝度を追加
void theaterChaseRainbow(int bright_val, uint8_t wait) {
//★pixelInterval(LED処理間隔)とwait時間が異なる場合、pixelIntervalにwait時間をセット
if(pixelInterval != wait)
pixelInterval = wait; // Update delay time
for(int i=0; i < pixelNumber; i=i+3) {
strip.setPixelColor(i + pixelQueue, Wheel((i + pixelCycle) % 255));
}
strip.setBrightness(bright_val); //★輝度を設定
strip.show();
for(int i=0; i < pixelNumber; i=i+3) {
strip.setPixelColor(i + pixelQueue, strip.Color(0, 0, 0));
}
pixelQueue++; // Advance current queue
pixelCycle++; // Advance current cycle
if(pixelQueue >= 3)
pixelQueue = 0; // Loop
if(pixelCycle >= 256)
pixelCycle = 0; // Loop
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r – g – b – back to r.
//★虹系関数内で使用するWheel関数、基の記述から変更ないため説明省略
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 – WheelPos;
if(WheelPos < 85) {
return strip.Color(255 – WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 – WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 – WheelPos * 3, 0);
}
//★文字スクロール用関数、引数は色・wait時間
//★画素Queue用変数は、文字用配列にて表示開始する幅側(横方向)の開始位置に使用
void strScroll(uint32_t main_color, int wait) {
int sw = STR_W; //表示内容の幅ピクセル
int dh = LED_H; //ディスプレーの高さピクセル
int dw = LED_W; // ディスプレーの幅ピクセル
uint32_t temp_color;
//★pixelInterval(LED処理間隔)とwait時間が異なる場合、pixelIntervalにwait時間をセット
if(pixelInterval != wait)
pixelInterval = wait;
for (int h = 0; h < dh; h++) { // 上の行から
for (int w = 0; w < dw; w++) { // 左の列から
if (((pixelQueue + w) < dw) || ((pixelQueue + w) >= (dw + sw))) { // 表示範囲外
continue; //★1文字分そろっていないor表示完了なので、次の列に進む
}
else if (pix_str[h][w – dw + pixelQueue] == 1) { // 表示位置の データが 1 のとき
temp_color = main_color; //★色設定
}
else { // 表示位置のデータが 0 のとき
temp_color = strip.Color(0, 0, 0); //★黒(表示 OFF)
}
//★行・列から論理インデックスを求める->物理インデックスに変換してその位置のLEDの色設定
strip.setPixelColor(logidx2phyidx(h * dw + w), temp_color);
}
}
strip.show(); //★点灯
pixelQueue++; // Advance current pixel //★画素Queue用変数をインクリメント(文字用配列の列の位置を一つ右に移動)
//★画素Queue用変数が最後(文字用配列の幅+LEDシートの幅の値以上)であれば、画素Queue用変数を0クリア
if(pixelQueue >= (sw + dw))
pixelQueue = 0; // Loop the pattern from the first LED
}
//★1文字表示用関数、引数は色・wait時間
//★追記コメント部以外、文字スクロール用関数と同じ
void strDisp(uint32_t main_color, int wait) {
int sw = STR_W; // 表示内容の幅ピクセル
int dh = LED_H; // ディスプレーの高さピクセル
int dw = LED_W; // ディスプレーの幅ピクセル
uint32_t temp_color;
if(pixelInterval != wait)
pixelInterval = wait;
for (int h = 0; h < dh; h++) { // 上の行から
for (int w = 0; w < dw; w++) { // 左の列から
if (((pixelQueue + w) < dw) || ((pixelQueue + w) >= (dw + sw))) { // 表示範囲外
continue;
}
else if (pix_str[h][w – dw + pixelQueue] == 1) { // 表示位置の データが 1 のとき
temp_color = main_color;
}
else { // 表示位置のデータが 0 のとき
temp_color = strip.Color(0, 0, 0);
}
strip.setPixelColor(logidx2phyidx(h * dw + w), temp_color);
}
}
strip.show();
pixelQueue+=dw; // Advance current pixel //★画素Queue用変数をLEDシートの幅分加える(文字用配列の列の位置を一文字分移動する)
if(pixelQueue >= (sw + dw))
pixelQueue = 0; // Loop the pattern from the first LED
}
この記事の監修者
コーンズテクノロジー編集部
コーンズテクノロジーでは先進的な製品・技術を日本産業界へ紹介する技術専門商社として、通信計測・自動車・防衛セキュリティ・電子機器装置・航空宇宙・産業機械といった技術分野のお役立ち情報を紹介しています。