過去記事の改良② LEDマトリックス表示を割り込み化
今回は、Arduino UNO R4 WiFiに搭載されているLEDマトリックス関連の改良をしようと思う。
過去の記事では以下が相当する。
私のブログで紹介しているLEDマトリックス関連のプログラムは、サンプルプログラムを見ることもなく独自で作ったものだ。
自分では満足のいく動作をしているのでいいのだが、実用を考えるとある欠点がある。
それは、LEDマトリックス表示をloop関数内で行っているため、LEDマトリックス表示以外の動作を同時にさせることができないのだ。
LEDマトリックス用に用意されているサンプルプログラムでは、タイマー割り込みを使った制御を行っている。
なので、俺の作ったプログラムでもそのようにしてみようと思う。
やりかたは、サンプルプログラムでも使われている"FspTimer.h"のヘッダーファイルをインクルードする。
そしてタイマー割り込みの設定をして起動。
割り込みが発生したら設定したコールバック関数が実行されるので、そのコールバック関数の中をいままでloop関数で記述してたLEDマトリックス表示プログラムを移す。
・・・だけでは綺麗に表示されない。
タイマー割り込み1回で一つのLEDを制御しているので、割り込み96回でLEDマトリックス全体を表示している。 そのため、そんな制御に会ったプログラムに変えないといけない。
とりあえず一番最初のプログラム、タイ語でI love youをスクロール表示させているプログラムを、タイマー割り込み化してみたので、参考にしてもらえればと思う。
改造箇所で何をしているかわかれば、他の文字列スクロール系のプログラムにも応用できるはずだ。
LEDマトリックスでグラデーションさせているプログラムは、この改良ではうまくいかない。 それはまた別途考えることにする。
#include "Arduino_LED_Matrix.h" #include "FspTimer.h" //スクロール時間 #define SCROLL_TIME 100 //ミリ秒 //表示文字列 unsigned char matrix[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0xd6, 0x56, 0x52, 0x0f, 0x00, //cha 0x10, 0x28, 0x1f, 0x01, 0x02, 0x3d, 0x02, 0x00, //n 0x09, 0x15, 0xd5, 0x55, 0x55, 0x02, 0x00, //ra 0x0b, 0x1c, 0x28, 0x20, 0x10, 0x0f, 0x00, //k 0x3f, 0x01, //e 0x18, 0x2b, 0x29, 0x29, 0x27, 0x20, 0x00, //t 0x13, 0x25, 0x27, 0x21, 0x11, 0x0f, //o 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; unsigned long tm = 0; int idx = 0; int ic1 = 0; static FspTimer fsp_timer; void setup() { //タイマー割り込みの設定 uint8_t timer_type; int8_t timer_ch = FspTimer::get_available_timer(timer_type); if (timer_ch < 0) { Serial.println("get_available_timer() failed."); return; } fsp_timer.begin(TIMER_MODE_PERIODIC, timer_type, timer_ch, 10000.0, 50.0, timer_callback, nullptr); fsp_timer.setup_overflow_irq(); fsp_timer.open(); fsp_timer.start(); pinMode(LED_BUILTIN, OUTPUT); } void loop() { digitalWrite(LED_BUILTIN, HIGH); delay(100); digitalWrite(LED_BUILTIN, LOW); delay(500); } void timer_callback(timer_callback_args_t *arg) { //スクロール時間が経過したらスライドさせる。末端に到達したら始めに戻る if(tm + SCROLL_TIME <= millis()) { if (idx < 55) idx++; else{ idx = 0; } //経過時間を再計測 tm = millis(); } //12x8LED View turnLed(ic1, matrix[idx + ic1 % 12] >> (7 - ic1 / 12) & 0x01); ic1++; if(ic1 > 96) ic1 = 0; }