M5StackCore2を動かしてみた!(その3)
Core2の新機能のタッチパネルと振動モーターをもう少し作り込んでみました。💪
今回は『タイマー割り込み』『タッチパネルチェック』『振動モータ』3の機能を盛り込んでいます。
1、タイマー割り込み
タイマー割り込みは以前ESP32用に作ったやつが、そのまま動きますので屋台骨はこれにします。
2、タッチパネルチェック
とりあえず今回は下部3箇所のタッチボタンで反応するように作りました。
タイマー割り込みルーチンに組み込むことを前提としているため、タイマー割り込み毎に呼び出し、処理をしたら他の処理をタスクに渡すように作ってあります。
class BUTTAN
{ #define leftSw 0 #define centerSw 1 #define rightSw 2
private:
int _swCnt[3]={0,0,0};
void _buttanCnt(int num,int px,int x1,int x2)
{
if(x1 < px && px < x2)
_swCnt[num]++;
if(_swCnt[num] > 1000/2){_swCnt[num] =1000/2;}
};
public:
void tuchButtOn(){
TouchPoint_t pos= M5.Touch.getPressPoint();
if(pos.y > 240){
_buttanCnt(leftSw,pos.x,0,109);
_buttanCnt(centerSw,pos.x,109,218);
_buttanCnt(rightSw,pos.x,218,320);
}else {
_swCnt[0] = 0;
_swCnt[1] = 0;
_swCnt[2] = 0;
}
//Serial.printf("%d-%d-%d\n",_swCnt[0],_swCnt[1],_swCnt[2]);
};
int buttanOn(int num)
{
return(_swCnt[num]);
};
};
スイッチルーチンを作成する時だけど、自分はONしている時間をカウンターでカウントするようにしてます。このように作っておくと、チャタリング防止やスイッチONのエッジ、長押し判定なんかも簡単にできます。
今回は組み込んでないけど、OFFカウンターを組み込んでおけは、スイッチを離した時に反応なんてことも簡単にできます。
3、振動モータ
これも処理をしたら、すぐに他の処理に引き渡すように作ってあります。
振動時間を設定すると、その期間振動モータが振動します。
class VIBRATION
{
private:
int _vcount=0;
public:
void vibrationStart(int cnt)
{
_vcount = cnt;
}
void vibration()
{
if(_vcount == 0){
return;
}else
{
power.SetLDOEnable(3, true);
_vcount--;
}
if(_vcount ==0) power.SetLDOEnable(3, false);
};
};
今回はただ振動するだけだけど、最近のスマホなんかを参考に振動のパターンいろいろを作り込んでも面白いと思います。
4、3つの機能の組み込み
3つの機能をドッキングしたプログラムがこんな感じです。
割り込み周期は2msで動かしています。2msくらいで動かしていればモータなんか制御もできると思います。まぁ、このへんは10msでも良いと思います。😃
タイマーの設定部分のパラメータが100/2とか書いてあるのは、2msのタイマー割り込みで100ms動作させるよってことです。
#include <M5Core2.h>
#include <AXP192.h>
AXP192 power;
volatile int timeCounter1;
hw_timer_t *timer1 = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
class VIBRATION
{
private:
int _vcount=0;
public:
void vibrationStart(int cnt)
{
_vcount = cnt;
}
void vibration()
{
if(_vcount == 0){
return;
}else
{
power.SetLDOEnable(3, true);
_vcount--;
}
if(_vcount ==0) power.SetLDOEnable(3, false);
};
};
VIBRATION tuch;
class BUTTAN
{ #define leftSw 0 #define centerSw 1 #define rightSw 2
private:
int _swCnt[3]={0,0,0};
void _buttanCnt(int num,int px,int x1,int x2)
{
if(x1 < px && px < x2)
_swCnt[num]++;
if(_swCnt[num] > 1000/2){_swCnt[num] =1000/2;}
};
public:
void tuchButtOn(){
TouchPoint_t pos= M5.Touch.getPressPoint();
if(pos.y > 240){
_buttanCnt(leftSw,pos.x,0,109);
_buttanCnt(centerSw,pos.x,109,218);
_buttanCnt(rightSw,pos.x,218,320);
}else {
_swCnt[0] = 0;
_swCnt[1] = 0;
_swCnt[2] = 0;
}
//Serial.printf("%d-%d-%d\n",_swCnt[0],_swCnt[1],_swCnt[2]);
};
int buttanOn(int num)
{
return(_swCnt[num]);
};
};
BUTTAN core2;
void IRAM_ATTR onTimer1(){
portENTER_CRITICAL_ISR(&timerMux);
timeCounter1++;
portEXIT_CRITICAL_ISR(&timerMux);
}
void setup() {
M5.begin(true, true, true, true);
Serial.begin(115200);
timer1 = timerBegin(0, 80, true);
timerAttachInterrupt(timer1, &onTimer1, true);
timerAlarmWrite(timer1, 2000, true);
timerAlarmEnable(timer1);
Serial.println("Start!");
}
void loop() {
if (timeCounter1 > 0) {
portENTER_CRITICAL(&timerMux);
timeCounter1--;
portEXIT_CRITICAL(&timerMux);
core2.tuchButtOn();
tuch.vibration();
if(core2.buttanOn(leftSw) == 10){tuch.vibrationStart(100/2);}
if(core2.buttanOn(centerSw) == 10){tuch.vibrationStart(100/2);}
if(core2.buttanOn(rightSw) == 10){tuch.vibrationStart(100/2);}
}
}
どうでしょうか?
前回作った、タッチ&振動より少し高級な感じでしょ?💯
と自画自賛したとこで😆
では✋
この記事が気に入ったらサポートをしてみませんか?