M5 Stick C Plus と一緒にENV II HATを購入したので、以前購入しておいたGROVE接続のGPSモジュールと一緒につなげてAmbient Ambientにデータをアップロードするようにプログラミングしてみた。参考にしたのはこの辺りのページ。
Arduino ESP8266で温度・湿度を測定し、Ambientに送ってグラフ化する – Ambient (ambidata.io)
M5StickCPlusとGPS UNITで位置情報を取得 - modalsoul’s blog (hatenablog.com)
M5 Stick C用のENV II HATのサンプルプログラムをベースにしてヘッダをM5 Stick C Plus用に変更、その状態でまずは動作確認、そこからAmbientへ書き込むように修正。
WiFiのSSID、Ambientの書き込みチャネルIDは適宜修正が必要。
そこからGrove接続のGPSモジュールを使用できるように追加。
Groveは32、33を指定。なお、気圧はオリジナルだとパスカル表示なので100で割ってヘクトパスカルとした。
/*
note: need add library Adafruit_BMP280 from library manage
Github: https://github.com/adafruit/Adafruit_BMP280_Library
*/
#include <M5StickCPlus.h>
#include "SHT3X.h"
#include <Wire.h>
#include "Adafruit_Sensor.h"
#include "Adafruit_BMP280.h"
#include "bmm150.h"
#include "bmm150_defs.h"
#include "Ambient.h"
#include <WiFi.h>
#include <TinyGPS++.h>
SHT3X sht3x;
BMM150 bmm = BMM150();
bmm150_mag_data value_offset;
Adafruit_BMP280 bme;
HardwareSerial GPSRaw(2);
TinyGPSPlus gps;
Ambient ambient;
WiFiClient client;
unsigned int channelId = 12345; //channel ID
const char* writeKey = "**************"; // Write Key
const char* ssid = "SSID";
const char* password = "PASSWORD";
float tmp = 0.0;
float hum = 0.0;
float pressure = 0.0;
uint8_t setup_flag = 1;
void calibrate(uint32_t timeout)
{
int16_t value_x_min = 0;
int16_t value_x_max = 0;
int16_t value_y_min = 0;
int16_t value_y_max = 0;
int16_t value_z_min = 0;
int16_t value_z_max = 0;
uint32_t timeStart = 0;
bmm.read_mag_data();
value_x_min = bmm.raw_mag_data.raw_datax;
value_x_max = bmm.raw_mag_data.raw_datax;
value_y_min = bmm.raw_mag_data.raw_datay;
value_y_max = bmm.raw_mag_data.raw_datay;
value_z_min = bmm.raw_mag_data.raw_dataz;
value_z_max = bmm.raw_mag_data.raw_dataz;
delay(100);
timeStart = millis();
while ((millis() - timeStart) < timeout)
{
bmm.read_mag_data();
/* Update x-Axis max/min value */
if (value_x_min > bmm.raw_mag_data.raw_datax)
{
value_x_min = bmm.raw_mag_data.raw_datax;
// Serial.print("Update value_x_min: ");
// Serial.println(value_x_min);
}
else if (value_x_max < bmm.raw_mag_data.raw_datax)
{
value_x_max = bmm.raw_mag_data.raw_datax;
// Serial.print("update value_x_max: ");
// Serial.println(value_x_max);
}
/* Update y-Axis max/min value */
if (value_y_min > bmm.raw_mag_data.raw_datay)
{
value_y_min = bmm.raw_mag_data.raw_datay;
// Serial.print("Update value_y_min: ");
// Serial.println(value_y_min);
}
else if (value_y_max < bmm.raw_mag_data.raw_datay)
{
value_y_max = bmm.raw_mag_data.raw_datay;
// Serial.print("update value_y_max: ");
// Serial.println(value_y_max);
}
/* Update z-Axis max/min value */
if (value_z_min > bmm.raw_mag_data.raw_dataz)
{
value_z_min = bmm.raw_mag_data.raw_dataz;
// Serial.print("Update value_z_min: ");
// Serial.println(value_z_min);
}
else if (value_z_max < bmm.raw_mag_data.raw_dataz)
{
value_z_max = bmm.raw_mag_data.raw_dataz;
// Serial.print("update value_z_max: ");
// Serial.println(value_z_max);
}
Serial.print(".");
delay(1);
}
value_offset.x = value_x_min + (value_x_max - value_x_min) / 2;
value_offset.y = value_y_min + (value_y_max - value_y_min) / 2;
value_offset.z = value_z_min + (value_z_max - value_z_min) / 2;
}
void showLocation() {
if (gps.location.isValid()) {
M5.Lcd.setCursor(10, 80, 2);
M5.Lcd.printf("lat:%.4f\n", gps.location.lat() );
M5.Lcd.setCursor(10, 100, 2);
M5.Lcd.printf("lng:%.4f\n", gps.location.lng() );
} else {
M5.Lcd.setCursor(10, 80, 2);
M5.Lcd.println("wait gps");
}
}
void setup() {
// put your setup code here, to run once:
M5.begin();
Wire.begin(0, 26);
M5.Lcd.setRotation(3);
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setCursor(10, 0, 2);
M5.Lcd.print("ENV TEST ");
pinMode(M5_BUTTON_HOME, INPUT);
// GPS Initialize
GPSRaw.begin(9600, SERIAL_8N1, 33, 32);
// BMM150 Initialize
if (bmm.initialize() == BMM150_E_ID_NOT_CONFORM) {
Serial.println("Chip ID can not read!");
while (1);
} else {
Serial.println("Initialize done!");
}
// BMP280 Initialize
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BMP280 sensor, check wiring!");
while (1);
}
calibrate(10);
Serial.print("\n\rCalibrate done..");
// WiFi Initialize
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
M5.Lcd.println(WiFi.localIP());
// Ambient Initialize
ambient.begin(channelId, writeKey, &client);
// end of setup
}
void loop() {
// put your main code here, to run repeatedly:
if (sht3x.get() == 0) {
tmp = sht3x.cTemp;
hum = sht3x.humidity;
}
while (GPSRaw.available() > 0) {
if (gps.encode(GPSRaw.read())) {
break;
}
}
showLocation();
M5.Lcd.setCursor(10, 20, 2);
M5.Lcd.printf("Temp: %2.1f Humi: %2.0f", tmp, hum);
bmm150_mag_data value;
bmm.read_mag_data();
value.x = bmm.raw_mag_data.raw_datax - value_offset.x;
value.y = bmm.raw_mag_data.raw_datay - value_offset.y;
value.z = bmm.raw_mag_data.raw_dataz - value_offset.z;
float xyHeading = atan2(value.x, value.y);
float zxHeading = atan2(value.z, value.x);
float heading = xyHeading;
if (heading < 0)
heading += 2 * PI;
if (heading > 2 * PI)
heading -= 2 * PI;
float headingDegrees = heading * 180 / M_PI;
float xyHeadingDegrees = xyHeading * 180 / M_PI;
float zxHeadingDegrees = zxHeading * 180 / M_PI;
Serial.print("Heading: ");
Serial.println(headingDegrees);
Serial.print("xyHeadingDegrees: ");
Serial.println(xyHeadingDegrees);
Serial.print("zxHeadingDegrees: ");
Serial.println(zxHeadingDegrees);
M5.Lcd.setCursor(10, 40, 2);
M5.Lcd.printf("headingDegrees: %2.1f", headingDegrees);
float pressure = bme.readPressure() / 100;
M5.Lcd.setCursor(10, 60, 2);
M5.Lcd.printf("pressure: %2.3f", pressure);
ambient.set(1, tmp);
ambient.set(2, hum);
ambient.set(3, pressure);
ambient.set(4, gps.location.lat());
ambient.set(5, gps.location.lng());
ambient.set(6, headingDegrees);
ambient.send();
// delay(100);
delay(120000);
if (!setup_flag) {
setup_flag = 1;
if (bmm.initialize() == BMM150_E_ID_NOT_CONFORM) {
Serial.println("Chip ID can not read!");
while (1);
} else {
Serial.println("Initialize done!");
}
if (!bme.begin(0x76)) {
Serial.println("Could not find a valid BMP280 sensor, check wiring!");
while (1);
}
calibrate(10);
Serial.print("\n\rCalibrate done..");
}
if (digitalRead(M5_BUTTON_HOME) == LOW) {
setup_flag = 0;
while (digitalRead(M5_BUTTON_HOME) == LOW);
}
}



























