使ったもの
参考にしたサイト
注意点
- Mac版のAruduino1.8.3で標準で使えるM5-CoreInkライブラリは0.0.1でshutdown()が使えないので、GitHubからzipをダウンロードする必要がある。
- 既存のライブラリをzipで固めるなどバックアップして削除
- ダウンロードしたzipをライブラリに追加
やりたいこと
step1
- BLEServer(ペリフェラル)として動作する
- アドバタイズ開始
- 1秒間接続待ち
- 接続したら書き込み待ち
- 接続しなければシャットダウン(9秒後に起動)
- 書き込まれた文字列を表示する
- EXTボタンで画面クリア
- 接続中に電源ボタンでシャットダウン(9秒後に起動)
- 電源ボタンを押されたら起動する
- MIDボタンを押されるとBLEで通知する(notify)
step2(別記事にする予定)->こちら
step1に以下を加える
- 1時間に一回バッテリー電圧を確認して表示する
- 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()が実行されるのサンプルのままでは画面が一度黒くなる
- 書換え時にのみ初期化処理を行うようにした