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);}
    
  }
  
} 


どうでしょうか?

前回作った、タッチ&振動より少し高級な感じでしょ?💯

と自画自賛したとこで😆

では✋







この記事が気に入ったらサポートをしてみませんか?