先日、M5Stackに12個の外付けスイッチをつなぎ、それぞれのON/OFFをM5Stackで認識させることができました(記事は こちら)。
今回は、これらのスイッチを使ってカウンタをつくりたいと思います。
リンク
スイッチを押すたびに、そのスイッチに対応する数字が 1 ずつカウントダウンするものです。
消耗品の残数管理することをイメージしています。例えば引き出しから「消しゴム」を取り出すたびに「消しゴム」スイッチを押すことで、引き出しの中に残っている消しゴムの数が把握できます。
スイッチは12個使えますので、12種類の消耗品の残数を管理できます。
スケッチは以下のとおりです。
#include <M5Stack.h>
int CPIN[4] = {16, 17, 2, 5};
int RPIN[3] = {26, 22, 21};
int prv[3][4] = { {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1} };
int cnt[3][4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0} };
void setup() {
M5.begin();
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setTextColor(BLACK);
M5.Lcd.setTextSize(4);
for(int c=0; c<4; c++) {
for(int r=0; r<3; r++) {
drawCell(r, c);
}
}
for(int c=0; c<4; c++) pinMode(CPIN[c], OUTPUT);
for(int r=0; r<3; r++) pinMode(RPIN[r], INPUT_PULLUP);
}
void loop() {
M5.update();
for(int c=0; c<4; c++) {
digitalWrite(CPIN[0], HIGH);
digitalWrite(CPIN[1], HIGH);
digitalWrite(CPIN[2], HIGH);
digitalWrite(CPIN[3], HIGH);
digitalWrite(CPIN[c], LOW);
for(int r=0; r<3; r++) {
if(digitalRead(RPIN[r]) == LOW){
if(prv[r][c] == 1) {
if(M5.BtnA.isPressed()) cnt[r][c]++;
else cnt[r][c]--;
if(cnt[r][c] < 0) cnt[r][c] = 0;
if(cnt[r][c] > 99) cnt[r][c] = 99;
drawCell(r, c);
}
prv[r][c] = 0;
} else {
prv[r][c] = 1;
}
}
}
delay(50);
}
void drawCell(int raw, int col) {
int x = col*80;
int y = raw*60;
if(cnt[raw][col] <= 3) M5.Lcd.fillRect(x+2, y+2, 76, 56, RED);
else M5.Lcd.fillRect(x+2, y+2, 76, 56, WHITE);
if(cnt[raw][col] < 10) M5.Lcd.setCursor(x+42, y+16);
else M5.Lcd.setCursor(x+18, y+16);
M5.Lcd.print(cnt[raw][col]);
}
12個の外付けスイッチのON/OFFを認識する仕組みは、先日のスケッチと同じです。
「cnt[3][4]」という変数で、3×4 の計12個のスイッチのカウントを管理します。
スイッチを押すたびに、該当する変数の値をカウントダウンします。
なお、M5Stackの「ボタンA」を押しながらスイッチを押すと、カウントアップします。
変数は 0 〜 99 の間でしか変動しないようにしています。
スイッチを押しっぱなしにしたときに、値が 1 しか変動しないようにするために、「prv[3][4]」という変数で、直前のスイッチの状態を保持しています。
直前のスイッチの状態が「HIGH」で、今回の状態が「LOW」の時だけ、カウントダウン/アップします。
値が変動した時だけ、該当する値の表示を再描画します。
値が 3 以下のときは、その数値の背景を赤色にします。
動作結果は以下のとおりです。
問題なく動作しました。
なお、M5Stackの電源をオフにしたり、リセットしたりすると、カウントした数値が初期化されてしまうので、注意が必要です。
リンク