やりたいこと
M5AtomのIOユニットで取得したデータをLTE回線からAmbientへアップロードします。
LTE回線はmineoのDプランを利用しました。
参考元
反省点(注意点)
- LTE接続を確立したのちEXT-IO2の値読取りを行うと、LTEが切断されてしまう事象が発生しました。知識不足でこちらは解消できず、値読取り後に毎回LTE接続を行うため、読取りからデータ送信まで10~30秒ほどかかります。
- 本当はMQTTでAzure Iot Hubに送信したかったのですが、MQTTをTLSで暗号化してデータ送信する方法が分らず、ひとまずHttpで送信可能なAmbientにデータを送信することにしました。
前提条件
機器構成
使用ライブラリ
- M5Atom
- TinyGSM
- ArduinoHttpClient
ソースコード
// TinyGSM(LTE接続用)
#define TINY_GSM_MODEM_SIM7080
#define TINY_GSM_RX_BUFFER 650
#define TINY_GSM_DEBUG SerialMon
#define GSM_AUTOBAUD_MIN 9600
#define GSM_AUTOBAUD_MAX 115200
#define SerialAT Serial1
#include <TinyGsmClient.h>
// ArduinoHttpClient(Http通信用)
#include <ArduinoHttpClient.h>
#define SerialMon Serial
// M5EXTIO2(IO入力用)
#include "M5_EXTIO2.h"
// SIMカードのAPN設定
const char apn[] = "mineo-d.jp";
const char gprsUser[] = "mineo@k-opti.com";
const char gprsPass[] = "mineo";
// 接続先設定
const char server[] = "ambidata.io";
const char chanelid[] = "12345"
const char writekey[] = "abcdefghijklmnop";
const char resource[] = "/api/v2/channels/" + chanelid + "/data";
const int port = 80;
// ADCユニット設定
M5_EXTIO2 extio;
// TinyGSM設定
TinyGsm modem(SerialAT);
TinyGsmClient client(modem);
// HttpClient設定
HttpClient http(client, server, port);
// LTE接続
void ConnectLTE() {
SerialMon.println("restart modem");
modem.restart();
SerialMon.println("wait for network connected ");
// Set GSM module baud rate
SerialAT.begin(115200, SERIAL_8N1, 32, 26);
TinyGsmAutoBaud(SerialAT, GSM_AUTOBAUD_MIN, GSM_AUTOBAUD_MAX);
delay(6000);
// Restart takes quite some time
// To skip it, call init() instead of restart()
SerialMon.println("Initializing modem...");
modem.restart();
modem.gprsConnect(apn, gprsUser, gprsPass);
SerialMon.print("Waiting for network...");
if (!modem.waitForNetwork()) {
SerialMon.println(" fail");
delay(10000);
return;
}
SerialMon.println(" success");
if (modem.isNetworkConnected()) {
SerialMon.println("Network connected");
}
return;
}
// 初期設定
void setup() {
// Set console baud rate
M5.begin();
SerialMon.begin(115200);
M5.dis.drawpix(0,CRGB::Blue);
delay(10);
// EXTIO2設定
Wire.begin(26, 32);
extio.begin(&Wire, 26, 32, 0x45);
extio.setAllPinMode(ADC_INPUT_MODE);
}
void loop() {
// LEDを緑色に点灯する
M5.dis.drawpix(0,CRGB::Green);
// ADCの入力値を取得する
double d1 = extio.getAnalogInput(0, _12bit);
double d2 = extio.getAnalogInput(1, _12bit);
double d3 = extio.getAnalogInput(2, _12bit);
// LTE接続確認
if(!modem.isGprsConnected()) { // 未接続の場合、接続処理
// LEDを青色に点灯する
M5.dis.drawpix(0,CRGB::Blue);
// 接続処理
ConnectLTE();
}
// Http通信(POST)
if(modem.isGprsConnected()) { // LTE接続確認
// LEDを白色に点灯する
M5.dis.drawpix(0,CRGB::White);
// POST送信設定
String contentType = "application/json";
String postData = ""
"{"
"\"writeKey\" : \"" + (String)writekey + "\","
"\"d1\" : \"" + (String)d1 + "\","
"\"d2\" : \"" + (String)d2 + "\","
"\"d3\" : \"" + (String)d3 + "\""
"}";
SerialMon.print(F("POST data : "));
SerialMon.println(postData);
// 送信実行
SerialMon.print(F("Performing HTTP GET request... "));
int err = http.post(resource,contentType,postData);
// 送信成否判定
if (err != 0) {
SerialMon.println(F("failed to connect"));
return;
}
// 結果取得
int status = http.responseStatusCode();
SerialMon.print(F("Response status code: "));
SerialMon.println(status);
if (!status) {
return;
}
// Responceヘッダ取得
SerialMon.println(F("Response Headers:"));
while (http.headerAvailable()) {
String headerName = http.readHeaderName();
String headerValue = http.readHeaderValue();
SerialMon.println(" " + headerName + " : " + headerValue);
}
// 受信データ取得
int length = http.contentLength();
if (length >= 0) {
SerialMon.print(F("Content length is: "));
SerialMon.println(length);
}
if (http.isResponseChunked()) {
SerialMon.println(F("The response is chunked"));
}
String body = http.responseBody();
SerialMon.println(F("Response:"));
SerialMon.println(body);
SerialMon.print(F("Body length is: "));
SerialMon.println(body.length());
// Http接続終了
http.stop();
SerialMon.println(F("Server disconnected"));
delay(60000);
} else {
// LEDを青色に点灯する
M5.dis.drawpix(0,CRGB::Blue);
// 接続処理
ConnectLTE();
}
}