2
1

More than 1 year has passed since last update.

M5AtomでTinyGSMを利用してLTE通信(HTTP)を行いAmbientにデータを送信する

Last updated at Posted at 2023-02-19

やりたいこと

 M5AtomのIOユニットで取得したデータをLTE回線からAmbientへアップロードします。
 LTE回線はmineoのDプランを利用しました。

参考元

反省点(注意点)

  • LTE接続を確立したのちEXT-IO2の値読取りを行うと、LTEが切断されてしまう事象が発生しました。知識不足でこちらは解消できず、値読取り後に毎回LTE接続を行うため、読取りからデータ送信まで10~30秒ほどかかります。
  • 本当はMQTTでAzure Iot Hubに送信したかったのですが、MQTTをTLSで暗号化してデータ送信する方法が分らず、ひとまずHttpで送信可能なAmbientにデータを送信することにしました。

前提条件

機器構成

機器構成.png

使用ライブラリ

  • 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();
    }
}
2
1
1

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
2
1