2021年11月30日火曜日

M5Stackで1D100ダイスを作る

 1年前のクリスマスに自分用プレゼントとして買ったM5Stack Grayでようやく少し遊び始めました.

今回は表題通り,コロナ禍があけて対面でクトゥルフTRPGができるようになった時のために使えるか分かりませんが,1D100ダイスを作ってみようと思います.

先に断っておきますが,出来たもののあんまり満足していません


さて,ボタンを押してただ乱数を表示させるものでもいいのですが,折角9軸センサを搭載したM5Stack Grayを買ったので,今回はM5Stackをフリフリして数字を表示させるダイスを作ります.ダイスだけに.

ただ,ネットにいくつかあるソースコードを利用しようとしましたが,対応しているのがMPU9250を搭載しているもので,自分が買ったものはMPU6886搭載のものなので微妙に対応していないようです.

よって今回は1から作っています.ただ,私がハイパス・ローパスフィルタなどの使い方をわかっていないため,かなり稚拙な制御になってします.

以降はそれをご承知でご覧ください.


まずは加速度センサを利用して,振ったときにどれくらいGがかかっているのか計測します.

#define M5STACK_MPU6886
#define TFT_GREY 0x5AEB

#include "BluetoothSerial.h" 
#include >m5stack .h>
float accX = 0.0F;
float accY = 0.0F;
float accZ = 0.0F;
int mode = -1;

BluetoothSerial bts;

void setup() {
  // put your setup code here, to run once:
  M5.begin();
  M5.IMU.Init();
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  M5.update();
  M5.IMU.getAccelData(&accX,&accY,&accZ);

  if(mode == -1 || M5.BtnA.wasReleased()){
    mode++;
    mode = mode % 3;
    if(mode == 0){
      Serial.printf("accX,accY,accZ\n");
      }
    }
  if(mode == 0){
    Serial.printf("%5.2f,%5.2f,%5.2\n", accX, accY, accZ);
    }
  delay(10);
}

 シリアルプロッタで確認したものが以下です.


大体3超えるぐらいのようです.

これより以下のプログラムを作りました.
#define M5STACK_MPU6886
#define TFT_GRAY 0x5AEB

#include <M5Stack.h>

int randNumber;

float accX = 0.0F;
float accY = 0.0F;
float accZ = 0.0F;

void setup() {
  // put your setup code here, to run once:
  M5.begin();
  M5.Power.begin();
  dacWrite(25, 0);

  randNumber = 0;

  M5.IMU.Init();
  M5.Speaker.setVolume(1);
  
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setCursor(140, 100);
  M5.Lcd.setTextColor(BLUE);
  //M5.Lcd.setTextFont(6);
  M5.Lcd.setTextSize(7);
  M5.Lcd.printf("0");
  delay(1000);

}

void loop() {
  // put your main code here, to run repeatedly:
  M5.update();
  M5.IMU.getAccelData(&accX,&accY,&accZ);
  
  //if (M5.BtnA.wasReleased()){
  if (accX > 3.0F || accX < -3.0F || M5.BtnA.wasReleased()){
    randNumber = random(1, 101);
    M5.Lcd.fillScreen(BLUE);

    if(accX < 0.5F || accX > -0.5F){


      if (randNumber < 6){
        M5.Lcd.fillScreen(WHITE);
        M5.Speaker.tone(1046, 100);
        delay(100);
        M5.Speaker.tone(1568, 500);
        M5.Lcd.drawString(String(randNumber), 140, 100);
        }
      else if (randNumber > 95){
        M5.Lcd.fillScreen(RED);
        M5.Lcd.drawString(String(randNumber), 140, 100);
        M5.Speaker.tone(131, 100);
        delay(100);
        M5.Speaker.tone(131, 500);
        }
      else {
        M5.Lcd.fillScreen(BLACK);
        M5.Lcd.drawString(String(randNumber), 140, 100);
        }
    }
  }

}

ディスプレイをクリティカルで白色,ファンブルで赤色で光らせるようにしています.

簡易的に音も鳴るようにしています.

 

実際に動かしてみました.

振って数字が変わるという挙動はできていますが,振っている最中は数字が変わり続けるのでイカサマ感が残ります.
そのため一応ボタンでも数字が変わるようにしています.

色々対策・その他のアルゴリズムも考えてみましたが,今回は個人的タイムリミットなのでここまでにします.
フィルタを組み込んだちゃんとしたものが作れる方はぜひご教授ください!


0 件のコメント:

コメントを投稿