0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

M5Stack-CoreInkにBLE経由で文字列を表示する(その1)

Last updated at Posted at 2021-05-19

使ったもの

参考にしたサイト

注意点

  • Mac版のAruduino1.8.3で標準で使えるM5-CoreInkライブラリは0.0.1でshutdown()が使えないので、GitHubからzipをダウンロードする必要がある。
    • 既存のライブラリをzipで固めるなどバックアップして削除
    • ダウンロードしたzipをライブラリに追加

やりたいこと

step1

  1. BLEServer(ペリフェラル)として動作する
  2. アドバタイズ開始
  3. 1秒間接続待ち
  • 接続したら書き込み待ち
  • 接続しなければシャットダウン(9秒後に起動)
  1. 書き込まれた文字列を表示する
  2. EXTボタンで画面クリア
  3. 接続中に電源ボタンでシャットダウン(9秒後に起動)
  4. 電源ボタンを押されたら起動する
  5. MIDボタンを押されるとBLEで通知する(notify)

step2(別記事にする予定)->こちら

step1に以下を加える

  1. 1時間に一回バッテリー電圧を確認して表示する
  2. DOWNボタンでNTPで調時する(日付を表示できるようにする)

step3(別記事にする予定)

  • M5StickCをBLEClient(セントラル)として動作させる(1)
    • 置く向きよってCoreInkに送る文字列を選択させる
    • ボタン押下でscan、connect、write実行
  • M5StickCをBLEClient(セントラル)として動作させる(2)
    • CoreInkのボタン状態がオンならば、表示、ブザー鳴動させる

ソースコード

BleMessage1.ino
# include <M5CoreInk.h>
# include <BLEDevice.h>
# include <BLEUtils.h>
# include <BLEServer.h>
# include <BLE2902.h>
# include <utility/fontResource.h>
# include <Preferences.h>

Preferences preferences;

Ink_Sprite InkPageSprite(&M5.M5Ink);

// See the following for generating UUIDs:
// https://www.uuidgenerator.net/

# define SERVICE_UUID        "1b62948e-7ccd-4b41-ad1b-181830a5742c"
# define CHARACTERISTIC_UUID "b6727492-b2ff-4563-aa2c-90c08e1bf879"

BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;
bool deviceConnected = false;

# define TIME_ADVERTISE_DURATION_MSEC 1*1000 //< アドバタイズ、接続待ちする時間
# define TIME_SLEEP_SEC 9 //< スリープ時間

unsigned long tStart; // 起動時刻
char message[16];

void initInk() {
  if (!M5.M5Ink.isInit()) {
    Serial.println("Ink init failed");
  }
  M5.M5Ink.clear();
  delay(1000);

  /// create ink Sprite
  if (InkPageSprite.creatSprite(0, 0, 200, 200, true) != 0) {
    Serial.println("Ink Sprite create failed");
  }  
}

void drawString(const char* str) {
  initInk();  
  InkPageSprite.clear(CLEAR_DRAWBUFF | CLEAR_LASTBUFF);
  // TODO: 
  InkPageSprite.drawString(0, 0, str, &AsciiFont24x48);
  InkPageSprite.pushSprite();
  delay(2000);
}

class MyServerCallbacks: public BLEServerCallbacks {
    void onConnect(BLEServer* pServer) {
      Serial.println("#connect");
      deviceConnected = true;
    };

    void onDisconnect(BLEServer* pServer) {
      Serial.println("#disconnect");
      deviceConnected = false;
    }
};

class MyCallbacks: public BLECharacteristicCallbacks {
  void onRead(BLECharacteristic *pCharacteristic) {
    Serial.println("#read");
    pCharacteristic->setValue("Hello World!");
  }

  void onWrite(BLECharacteristic *pCharacteristic) {
    Serial.println("#write");
    std::string value = pCharacteristic->getValue();
    Serial.println(value.c_str());
    // write to EInk
    sprintf(message, "%s", value.c_str());
    // save to preferences
    preferences.putString("message", message);
  }

  void onIndicate(BLECharacteristic *pCharacteristic) {
    Serial.println("#indicate");
  }
};

void setup() {
  /// init
  M5.begin();

  // initInk(); // 起動時に画面を初期化したくないのでコメントアウト

  Serial.println("BLE start.");
  BLEDevice::init("M5StackCoreInk");
  BLEServer *pServer = BLEDevice::createServer();
  pServer->setCallbacks(new MyServerCallbacks());
  BLEService *pService = pServer->createService(SERVICE_UUID);
  pCharacteristic = pService->createCharacteristic(
                                         CHARACTERISTIC_UUID,
                                         BLECharacteristic::PROPERTY_READ |
                                         BLECharacteristic::PROPERTY_WRITE |
                                         BLECharacteristic::PROPERTY_NOTIFY |
                                         BLECharacteristic::PROPERTY_INDICATE
                                       );
  pCharacteristic->setCallbacks(new MyCallbacks());
  pCharacteristic->addDescriptor(new BLE2902());

  pService->start();
  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();

  tStart = millis(); // 起動時刻を取得

  M5.Speaker.setBeep(1200, 1);
}

void beep() {
  M5.Speaker.beep();
  delay(100);
}

void powerDown() {
  M5.shutdown(TIME_SLEEP_SEC);  
}


void loop() {
  // EXTボタンで画面クリア
  if (M5.BtnEXT.wasPressed()) {
    Serial.println("BtnEXT pressed");
    Serial.println("init ink");
    beep();
    delay(100);
    initInk();
  }
  if (deviceConnected) {
    // 強制切断(シャットダウン)
    if (M5.BtnPWR.wasPressed()) {
      Serial.println("BtnPWR pressed");
      beep();
      powerDown();
    }
    // Notify
    if (M5.BtnMID.wasPressed()) {
      Serial.println("BtnMID pressed!");
      pCharacteristic->setValue("BtnMID pressed!");
      pCharacteristic->notify();
      beep();
    }
  } else {
    // 自動シャットダウン(USB給電中は無効)
    if (TIME_ADVERTISE_DURATION_MSEC <= (millis() - tStart)) {
      powerDown();
    }
  }
  
  if (0 < strlen(message)) {
    Serial.println("write message");
    drawString(message);
    memset(message, 0, sizeof(message));
  }

  M5.update();
}

ちょっと工夫した点

  • シャットダウンから起動時にsetup()が実行されるのサンプルのままでは画面が一度黒くなる
  • 書換え時にのみ初期化処理を行うようにした
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?