【主な機能】
- M5Stackの内蔵BLEを使って、厚労省の接触確認アプリCocoaを検出するもの。
- BLE全体で検出した台数と内数としてのCoCoa台数を表示する。
- 検出した情報は、microSDにログファイルとして記録する。
- M5Stack Basicに温度湿度気圧センサであるENV.2 UnitをGROVE経由で接続し、
それらの情報もついでに表示・記録する。 - GPS Unitを接続し、検出した時の位置情報と日時を記録する。
【付加機能】
- ボタンA(左)を押すと、Cocoa検出時のBeep音をon/offさせる。
- ボタンB(中)を押すと、LCDのサイクリックに変わる。
- ボタンC(右)を押すと、画面とログファイルに「memo」と出力する。
何か気付いたことがあった時のイベント記録用。
【余談】
追加で購入したGPS UnitのGROVEコネクタはUARTだった。
M5StackのGROVEコネクタはENV.2 Sensorで埋まっているし、
そもそもI2Cしか使えないようだし。
ということで、UART2ポートに無理やり接続。
最初は動かなくて悩んだが、M5Stack側TX2にGPS側RX、
M5Stack側RX2にGPS側TXを繋ぐと動いた(^^;
#UART(シリアル通信)なんで、考えてみれば当たり前なんだが、
#こんなこともパッと思い出せないほどオッサン化が...。
電池が届いたら、RTCも接続するかな。
[code]
/*
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp
Ported to Arduino ESP32 by Evandro Copercini
*/
/*
Thanks to https://gist.github.com/ksasao/0da6437d3eac9b2dbd675b6fee5d1117
by https://gist.github.com/ksasao
*/
/*
This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
by Mikal Hart
*/
/*
SD card wrie routine
https://raspberrypi.mongonta.com/howto-write-csv-to-sdcard-on-m5stack/
*/
//////////////////////////////////////////////////////////////////////////////////
#include <M5Stack.h>
#include <TinyGPS++.h>
#include <BLEDevice.h>
//////////////////////////////////////////////////////////////////////////////////
/*
note: need add library Adafruit_BMP280 & Adafruit_SHT31 from library manage
*/
#include <Adafruit_SHT31.h>
#include <Wire.h> //The SHT31 uses I2C comunication.
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
//////////////////////////////////////////////////////////////////////////////////
#include <SPI.h>
#include <SD.h>
//////////////////////////////////////////////////////////////////////////////////
Adafruit_SHT31 sht31 = Adafruit_SHT31();
Adafruit_BMP280 bme;
//time out in seconds
int scanTime = 5;
BLEScan* pBLEScan;
const int chipSelect = 4;
TinyGPSPlus gps; // The TinyGPS++ object
HardwareSerial hsGps(2);// The serial connection to the GPS device
//接触確認アプリのUUID
const char* uuid = "0000fd6f-0000-1000-8000-00805f9b34fb";
int cocoaCnt = 0;
//log file name
const char* logfile = "/log.txt";
//文字列
const char* sumdevStr = "Sum";
const char* cocoaStr = " Cocoa";
const char* envStr = "Tmp: %3.1fC\r\nHum: %3.1f%%\r\nPrs: %3.0fhPa\r\n";
const char* locStr = "Loc: %lf %lf\r\n";
const char* dateStr = "%d/%02d/%02d ";
const char* timeStr = "%02d:%02d:%02d.%02d UTC\r\n";
//RTCまたはGPS
//bool hasRTC = false;
bool hasGPS = false;
//Sensor flag
bool hasSHT31 = false;
bool hasBMP280 = false;
float tmp = 100;
float hum = 0;
float pressure = 0;
//Other flags,Params
bool onBeep = true;
unsigned char bright = 0x03;
unsigned char brightPitch = 0x10;
static const uint32_t GPSBaud = 9600;
//////////////////////////////////////////////////////////////////////////////////
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
if (advertisedDevice.haveServiceUUID()) {
if (strncmp(advertisedDevice.getServiceUUID().toString().c_str(), uuid, 36) == 0) {
cocoaCnt++;
if (onBeep) {
M5.Speaker.beep();
delay(10);
M5.Speaker.mute();
}
M5.Lcd.setCursor(0, 110);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(GREEN, BLACK);
M5.Lcd.printf("%d ", cocoaCnt);
M5.Lcd.setTextSize(1);
}
}
M5.Lcd.println(advertisedDevice.toString().c_str());
M5.Lcd.setTextSize(1);
M5.Lcd.setTextColor(WHITE, BLACK);
}
};
//////////////////////////////////////////////////////////////////////////////////
void setup() {
// Initialize the M5Stack
M5.begin();
M5.Power.begin();
M5.Lcd.setBrightness(bright);
M5.Lcd.setTextSize(1);
M5.Lcd.println("Hello!, COCOA Scan");
Serial.begin(115200);
//BLE setup
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(100);
pBLEScan->setWindow(99); // less or equal setInterval value
//ENV sensor on I2C setup
Wire.begin();
Serial.println(F("ENV.2 Chk"));
if (sht31.begin(0x44)) { // Set to 0x45 for alternate i2c addr
hasSHT31 = true;
Serial.println("SHT31 Ok");
Serial.print("Heater: ");
if (sht31.isHeaterEnabled())
Serial.println("Enable");
else
Serial.println("Disable");
}
if (bme.begin(0x76)) {
hasBMP280 = true;
Serial.println("BMP280 Ok");
}
//GPS setup
hsGps.begin(GPSBaud);
delay(500);
if (hsGps.available() > 0) {
hasGPS = true;
Serial.println("GPS Ok");
}
}
void loop() {
// print all found BLE devices
M5.Lcd.setTextSize(1);
if (hasGPS) {
while (hsGps.available() > 0) {
gps.encode(hsGps.read());
}
Serial.printf(locStr, gps.location.lat(), gps.location.lng());
Serial.printf(dateStr, gps.date.year(), gps.date.month(), gps.date.day() );
Serial.printf(timeStr, gps.time.hour(), gps.time.minute(), gps.time.second(), gps.time.centisecond());
}
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
// clear screen and set cursor to the top
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(0, 0);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(WHITE, BLACK);
M5.Lcd.printf(dateStr, gps.date.year(), gps.date.month(), gps.date.day() );
M5.Lcd.printf(timeStr, gps.time.hour(), gps.time.minute(), gps.time.second(), gps.time.centisecond());
// print counts of BLE devices
int sumdev = foundDevices.getCount();
M5.Lcd.setTextSize(3);
M5.Lcd.print(sumdevStr);
M5.Lcd.setTextColor(RED, BLACK);
M5.Lcd.print(sumdev);
// print count of cocoa APPs
M5.Lcd.setTextColor(WHITE, BLACK);
M5.Lcd.print(cocoaStr);
M5.Lcd.setTextColor(GREEN, BLACK);
M5.Lcd.println(cocoaCnt);
// print env2 data
if (hasSHT31) {
tmp = sht31.readTemperature();
hum = sht31.readHumidity();
}
if (hasBMP280) {
pressure = bme.readPressure() / 100;
// hPa = Pa / 100;
}
M5.Lcd.setTextColor(WHITE, BLACK);
M5.Lcd.printf(envStr, tmp, hum, pressure);
// print to the serial port too
Serial.print(sumdevStr);
Serial.print(sumdev);
Serial.print(cocoaStr);
Serial.println(cocoaCnt);
Serial.printf(envStr, tmp, hum, pressure);
Serial.println();
// SDカードへの書き込み処理(ファイル追加モード)
// SD.beginはM5.begin内で処理されているので不要
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dfile = SD.open(logfile, FILE_APPEND);
// if the file is available, write to it:
if (dfile) {
dfile.printf(locStr, gps.location.lat(), gps.location.lng());
dfile.printf(dateStr, gps.date.year(), gps.date.month(), gps.date.day() );
dfile.printf(timeStr, gps.time.hour(), gps.time.minute(), gps.time.second(), gps.time.centisecond());
dfile.print(sumdevStr);
dfile.print(sumdev);
dfile.print(cocoaStr);
dfile.println(cocoaCnt);
dfile.printf(envStr, tmp, hum, pressure);
dfile.println();
}
//Button controll
M5.Lcd.setTextSize(3);
M5.Lcd.println();
M5.Lcd.setTextColor(BLUE, WHITE);
M5.Lcd.println("A: Beep on/off");
M5.Lcd.println("B: Brightness");
M5.Lcd.println("C: Memo");
int timer = 100;
while (timer--) {
if (M5.BtnA.wasReleased()) { //Aボタンでbeepをon/off切り替える
onBeep = !onBeep;
} else if (M5.BtnB.wasReleased()) { //Bボタンで輝度を変更
bright += brightPitch;
M5.Lcd.setBrightness(bright);
} else if (M5.BtnC.wasReleased()) { //Cボタンでevent記録
dfile.println("Memo");
M5.Lcd.setTextColor(YELLOW, BLACK);
M5.Lcd.println("Wrote");
}
delay(70);
M5.update(); // update button state
}
//init for next loop
dfile.close();
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
cocoaCnt = 0;
M5.Lcd.setTextColor(WHITE, BLACK);
M5.Lcd.setCursor(0, 110);
M5.Lcd.setTextSize(1);
}
// Arranged and written by 柴田(ひ)
[/code]
/*
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp
Ported to Arduino ESP32 by Evandro Copercini
*/
/*
Thanks to https://gist.github.com/ksasao/0da6437d3eac9b2dbd675b6fee5d1117
by https://gist.github.com/ksasao
*/
/*
This sample sketch demonstrates the normal use of a TinyGPS++ (TinyGPSPlus) object.
by Mikal Hart
*/
/*
SD card wrie routine
https://raspberrypi.mongonta.com/howto-write-csv-to-sdcard-on-m5stack/
*/
//////////////////////////////////////////////////////////////////////////////////
#include <M5Stack.h>
#include <TinyGPS++.h>
#include <BLEDevice.h>
//////////////////////////////////////////////////////////////////////////////////
/*
note: need add library Adafruit_BMP280 & Adafruit_SHT31 from library manage
*/
#include <Adafruit_SHT31.h>
#include <Wire.h> //The SHT31 uses I2C comunication.
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
//////////////////////////////////////////////////////////////////////////////////
#include <SPI.h>
#include <SD.h>
//////////////////////////////////////////////////////////////////////////////////
Adafruit_SHT31 sht31 = Adafruit_SHT31();
Adafruit_BMP280 bme;
//time out in seconds
int scanTime = 5;
BLEScan* pBLEScan;
const int chipSelect = 4;
TinyGPSPlus gps; // The TinyGPS++ object
HardwareSerial hsGps(2);// The serial connection to the GPS device
//接触確認アプリのUUID
const char* uuid = "0000fd6f-0000-1000-8000-00805f9b34fb";
int cocoaCnt = 0;
//log file name
const char* logfile = "/log.txt";
//文字列
const char* sumdevStr = "Sum";
const char* cocoaStr = " Cocoa";
const char* envStr = "Tmp: %3.1fC\r\nHum: %3.1f%%\r\nPrs: %3.0fhPa\r\n";
const char* locStr = "Loc: %lf %lf\r\n";
const char* dateStr = "%d/%02d/%02d ";
const char* timeStr = "%02d:%02d:%02d.%02d UTC\r\n";
//RTCまたはGPS
//bool hasRTC = false;
bool hasGPS = false;
//Sensor flag
bool hasSHT31 = false;
bool hasBMP280 = false;
float tmp = 100;
float hum = 0;
float pressure = 0;
//Other flags,Params
bool onBeep = true;
unsigned char bright = 0x03;
unsigned char brightPitch = 0x10;
static const uint32_t GPSBaud = 9600;
//////////////////////////////////////////////////////////////////////////////////
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
if (advertisedDevice.haveServiceUUID()) {
if (strncmp(advertisedDevice.getServiceUUID().toString().c_str(), uuid, 36) == 0) {
cocoaCnt++;
if (onBeep) {
M5.Speaker.beep();
delay(10);
M5.Speaker.mute();
}
M5.Lcd.setCursor(0, 110);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(GREEN, BLACK);
M5.Lcd.printf("%d ", cocoaCnt);
M5.Lcd.setTextSize(1);
}
}
M5.Lcd.println(advertisedDevice.toString().c_str());
M5.Lcd.setTextSize(1);
M5.Lcd.setTextColor(WHITE, BLACK);
}
};
//////////////////////////////////////////////////////////////////////////////////
void setup() {
// Initialize the M5Stack
M5.begin();
M5.Power.begin();
M5.Lcd.setBrightness(bright);
M5.Lcd.setTextSize(1);
M5.Lcd.println("Hello!, COCOA Scan");
Serial.begin(115200);
//BLE setup
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(100);
pBLEScan->setWindow(99); // less or equal setInterval value
//ENV sensor on I2C setup
Wire.begin();
Serial.println(F("ENV.2 Chk"));
if (sht31.begin(0x44)) { // Set to 0x45 for alternate i2c addr
hasSHT31 = true;
Serial.println("SHT31 Ok");
Serial.print("Heater: ");
if (sht31.isHeaterEnabled())
Serial.println("Enable");
else
Serial.println("Disable");
}
if (bme.begin(0x76)) {
hasBMP280 = true;
Serial.println("BMP280 Ok");
}
//GPS setup
hsGps.begin(GPSBaud);
delay(500);
if (hsGps.available() > 0) {
hasGPS = true;
Serial.println("GPS Ok");
}
}
void loop() {
// print all found BLE devices
M5.Lcd.setTextSize(1);
if (hasGPS) {
while (hsGps.available() > 0) {
gps.encode(hsGps.read());
}
Serial.printf(locStr, gps.location.lat(), gps.location.lng());
Serial.printf(dateStr, gps.date.year(), gps.date.month(), gps.date.day() );
Serial.printf(timeStr, gps.time.hour(), gps.time.minute(), gps.time.second(), gps.time.centisecond());
}
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
// clear screen and set cursor to the top
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(0, 0);
M5.Lcd.setTextSize(2);
M5.Lcd.setTextColor(WHITE, BLACK);
M5.Lcd.printf(dateStr, gps.date.year(), gps.date.month(), gps.date.day() );
M5.Lcd.printf(timeStr, gps.time.hour(), gps.time.minute(), gps.time.second(), gps.time.centisecond());
// print counts of BLE devices
int sumdev = foundDevices.getCount();
M5.Lcd.setTextSize(3);
M5.Lcd.print(sumdevStr);
M5.Lcd.setTextColor(RED, BLACK);
M5.Lcd.print(sumdev);
// print count of cocoa APPs
M5.Lcd.setTextColor(WHITE, BLACK);
M5.Lcd.print(cocoaStr);
M5.Lcd.setTextColor(GREEN, BLACK);
M5.Lcd.println(cocoaCnt);
// print env2 data
if (hasSHT31) {
tmp = sht31.readTemperature();
hum = sht31.readHumidity();
}
if (hasBMP280) {
pressure = bme.readPressure() / 100;
// hPa = Pa / 100;
}
M5.Lcd.setTextColor(WHITE, BLACK);
M5.Lcd.printf(envStr, tmp, hum, pressure);
// print to the serial port too
Serial.print(sumdevStr);
Serial.print(sumdev);
Serial.print(cocoaStr);
Serial.println(cocoaCnt);
Serial.printf(envStr, tmp, hum, pressure);
Serial.println();
// SDカードへの書き込み処理(ファイル追加モード)
// SD.beginはM5.begin内で処理されているので不要
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dfile = SD.open(logfile, FILE_APPEND);
// if the file is available, write to it:
if (dfile) {
dfile.printf(locStr, gps.location.lat(), gps.location.lng());
dfile.printf(dateStr, gps.date.year(), gps.date.month(), gps.date.day() );
dfile.printf(timeStr, gps.time.hour(), gps.time.minute(), gps.time.second(), gps.time.centisecond());
dfile.print(sumdevStr);
dfile.print(sumdev);
dfile.print(cocoaStr);
dfile.println(cocoaCnt);
dfile.printf(envStr, tmp, hum, pressure);
dfile.println();
}
//Button controll
M5.Lcd.setTextSize(3);
M5.Lcd.println();
M5.Lcd.setTextColor(BLUE, WHITE);
M5.Lcd.println("A: Beep on/off");
M5.Lcd.println("B: Brightness");
M5.Lcd.println("C: Memo");
int timer = 100;
while (timer--) {
if (M5.BtnA.wasReleased()) { //Aボタンでbeepをon/off切り替える
onBeep = !onBeep;
} else if (M5.BtnB.wasReleased()) { //Bボタンで輝度を変更
bright += brightPitch;
M5.Lcd.setBrightness(bright);
} else if (M5.BtnC.wasReleased()) { //Cボタンでevent記録
dfile.println("Memo");
M5.Lcd.setTextColor(YELLOW, BLACK);
M5.Lcd.println("Wrote");
}
delay(70);
M5.update(); // update button state
}
//init for next loop
dfile.close();
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
cocoaCnt = 0;
M5.Lcd.setTextColor(WHITE, BLACK);
M5.Lcd.setCursor(0, 110);
M5.Lcd.setTextSize(1);
}
// Arranged and written by 柴田(ひ)
[/code]
0 件のコメント:
コメントを投稿