Line Things + テルミンでDrunken UFO 【ご褒美もらえるVer】


前回

前回は、Line Thingsを利用して距離センサのテルミンで
Flappy Bird的なゲームを作ってみました。
Flappy Birdの鳥をUFOにしてコントローラをテルミンに置き換えただけだったので、
今回は前回作成したものをもう一捻りしてみました。

何を作ったか

スコア伸ばしてくだけじゃモチベーションが上がらないので、物理的なご褒美もらえるようにしたい。
ご褒美といえば酒です。頑張ったらお酒飲める。モチベーション上がる。です。
それに前回作ったやつをみていただくといいのですが、このUFOの動きふわふわしてて酔っ払っているように見えなくもない。

ということで、ゲームの画面上にビールを出現させてそれをゲットすると、ビール注いでくれるみたいなのを作ってみました。

実装

ゲームの部分は前回作成したものを流用して、
ビール注ぎマシーンは、サーボを利用します。

苦労したところ

サーボのスピードをコントロールするために、delay()を使っているので、
loop内の距離測定の処理を止めないようサーボを動かすタスクは、xTaskCreateという関数で非同期で実行してメインのループをブロックしないようにしました。
(arduino全くの無知なので他のいいやり方あれば是非ご教授いただけると..)

ソース一部抜粋(M5Stack)

//Liffからの書き込みコールバック
class writeCallback: public BLECharacteristicCallbacks {
  void onWrite(BLECharacteristic *bleWriteCharacteristic) {
    std::string value = bleWriteCharacteristic->getValue();
    if ((char)value[0] <= 1) {
      if ((char)value[0] == 1) {
        M5.Lcd.clear(WHITE);
        M5.Lcd.setTextColor(BLACK);
        M5.Lcd.setTextSize(4);
        M5.Lcd.setCursor(135, 100);
        M5.Lcd.println("ON");
        calcDistance = true;
      }
      else {
        M5.Lcd.clear(BLACK);
        M5.Lcd.setTextColor(WHITE);
        M5.Lcd.setTextSize(4);
        M5.Lcd.setCursor(130, 100);
        M5.Lcd.println("OFF");
        calcDistance = false;
      }
    }
    if ((char)value[0] == 2) {
      shouldServoMove = true;
    }
  }
};

//省略

void loop() {

  M5.update();

  // Disconnection
  if (!deviceConnected && oldDeviceConnected) {
    delay(500); // Wait for BLE Stack to be ready
    thingsServer->startAdvertising(); // Restart advertising
    oldDeviceConnected = deviceConnected;
    M5.Lcd.clear(BLACK);
    M5.Lcd.setTextColor(YELLOW);
    M5.Lcd.setTextSize(2);
    M5.Lcd.setCursor(65, 10);
    M5.Lcd.println("Ready to Connect");
  }
  // Connection
  if (deviceConnected && !oldDeviceConnected) {
    oldDeviceConnected = deviceConnected;
    M5.Lcd.clear(BLACK);
    M5.Lcd.setTextColor(GREEN);
    M5.Lcd.setTextSize(2);
    M5.Lcd.setCursor(100, 10);
    M5.Lcd.println("Connected");
  }
  //距離測定
  if (calcDistance) {
    float HCSR04_d_d = hcsr04.distance();
    char buf[24];
    snprintf(buf, 24, "%.0f", HCSR04_d_d * 10);
    notifyCharacteristic->setValue(buf);
    notifyCharacteristic->notify();
    Serial.println(buf);
    delay(100);
  }

 //ビールゲットでサーボ動かす
  if (shouldServoMove && !isServoMoving) {
    xTaskCreate(moveServo,"moveServo", 4096, NULL, 1, NULL);
  }
}

//サーボ関数
void moveServo(void *pvParameter) {
  int maxDeg = 120;
  int minDeg = 10;
  int val;

  isServoMoving = true;
  servo.attach(Servo_Sig, minUs, maxUs);

  //傾ける
  for (val = 0; val <= maxDeg; val += 1) {
    servo.write(val);
    delay(20);
  }

  //一定時間注ぐ
  delay(900);

  //起こす
  for (val = maxDeg; val >= minDeg; val -= 1) {
    servo.write(val);
    delay(20);
  }

  servo.detach();
  isServoMoving = false;
  sholdServoMove = false;
  vTaskDelete( NULL );
}

githubにソースあげております。
M5Stack
Liff

こうなりました

2テイク分入ってます。
1テイク目は予想以上に一杯の量が多く溢れ。。
2テイク目はビールがなくなるという残念な結果に。。
いずれうまくいってるバージョンに差し替えるかもしれません。

デモ動画サムネイル

終わり

前回作ったやつよりも楽しくなったかな。
やってて気づいたのですが、サーボと距離センサって、前々回投稿で作ったものと全く同じ構成でやってました。。
前々回の腹筋にビール組み合わせるのも勢いでやっちゃうかもしれません。
そろそろ違うセンサに手を出さなきゃ。