pdf-icon

Arduino入門

2. デバイス&サンプル

6. アプリケーション

Atom DTU NBIoT2 シリーズ Arduino チュートリアル

1. 準備作業

注意
GitHub から最新のライブラリバージョンをダウンロードする必要があります。ライブラリアドレス: TinyGsmClient - M5Stack GitHub。Arduino Libraryからはダウンロードしないでください。(質問がある場合は、このチュートリアルを参照してください)

2. 注意事項

SIM カード互換性
本モジュールはネットワークサービスを正常に利用するために Micro SIM カードが必要です。現代の IoT SIM カードは Cat-M1 と NB-IOT の両方をサポートしており、またはこれら2つのサービスをサポートする従来の SIM カードを選択することもできます。以下のキャリア認証済みのカードを選択してください: Deutsche Telekom / Vodafone / Telefonica / 中国電信 / 中国移動 / 中国聯通。
注意
SIM カードを異なるデバイスで使用しないでください。SIM カードがロックされる可能性があります。
ピン互換性
各ホストのピン構成が異なるため、M5Stack 公式がピン互換性表を提供しています。実際のピン接続状況に応じてサンプルプログラムを修正してください。

3. HTTP サービス

デフォルトでは SIM カードの CAT モードを使用します。NB-IoT モードに切り替えるには、TinyGsmClientSIM7028.h ファイル内の MODE_NB_IOT マクロ定義のコメントを解除してください。デバッグが必要な場合、TinyGsmClientSIM7028.h ファイル内の DUMP_AT_COMMANDS マクロ定義のコメントを解除できます。

cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
#include "ATOM_DTU_NB.h"
#include <TinyGsmClient.h>
#include <M5AtomS3.h>
#include <sys/time.h>
#include <time.h>
#include <ArduinoHttpClient.h>

//#define MODE_NB_IOT     // By default, CAT mode is used. If using NB-IOT
// mode, open this macro definition or TinyGsmClientSIM7028.h line 32 //#define
// MODE_NB_IOT
//#define DUMP_AT_COMMANDS  // If you need to debug, you can open this macro
                          // definition and TinyGsmClientSIM7028.h line 13
                          // //#define TINY_GSM_DEBUG Serial
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger, ATOM_DTU_SIM7028_RESET);
#else
TinyGsm modem(SerialAT, ATOM_DTU_SIM7028_RESET);
#endif
// Server details
const char server[] = "api.m5stack.com";
const char resource[] = "/v1";
const int  port = 80;
TinyGsmClient client(modem);
HttpClient    http(client, server, port);

void modemConnect(void);

// Your GPRS credentials, if any
const char apn[] = "YourAPN";
const char gprsUser[] = "";
const char gprsPass[] = "";

struct tm now;
char s_time[50];

void log(String info) { SerialMon.println(info); }

void setup() {
  AtomS3.begin(true);  // Init M5AtomS3Lite.
  AtomS3.dis.setBrightness(100);
  AtomS3.dis.drawpix(0x0000ff);
  Serial.println(">>ATOM DTU NB MQTT TEST");
  SerialAT.begin(SIM7028_BAUDRATE, SERIAL_8N1, ATOM_DTU_SIM7028_RX,
                 ATOM_DTU_SIM7028_TX);

  modemConnect();
}

void loop() {
   AtomS3.update();
   SerialMon.print(F("Performing HTTP GET request... "));
  int err = http.get(resource);
  if (err != 0) {
    SerialMon.println(F("failed to connect"));
    delay(10000);
    return;
  }

  int status = http.responseStatusCode();
  SerialMon.print(F("Response status code: "));
  SerialMon.println(status);
  if (!status) {
    delay(10000);
    return;
  }

  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());

  // Shutdown

  http.stop();
  SerialMon.println(F("Server disconnected"));
}


void modemConnect(void) {
  // Get card number
  String ccid = modem.getSimCCID();
  Serial.println("CCID: " + ccid);
  // Acquire signal strength
  int csq = modem.getSignalQuality();
  Serial.println("Signal quality: " + String(csq));
  unsigned long start = millis();
  log("Initializing modem...");
  while (!modem.init()) {
    log("waiting...." + String((millis() - start) / 1000) + "s");
  };

  start = millis();
  log("Waiting for network...");
  while (!modem.waitForNetwork()) {
    log("waiting...." + String((millis() - start) / 1000) + "s");
  }
  log("success");
#ifdef MODE_NB_IOT
#else
  SerialMon.println("Waiting for GPRS connect...");
  if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
    SerialMon.println("waiting...." + String((millis() - start) / 1000) + "s");
  }
  SerialMon.println("success");
#endif

  // Example Query the IP address of a device
  String ip = modem.getLocalIP();

  log("Device IP address: " + ip);

  log("success");
}

HTTP リクエストが成功すると、サーバーからの一連の情報が返され、シリアルポートを通じて出力されます。

4. MQTT サービス

本モジュールは MQTT プロトコル通信もサポートしています。サンプルでは、Baidu Cloud 、 OneNET 、 ThingsCloud の 3 つの MQTT サービスプラットフォームに対応しています。このチュートリアルは Baidu Cloud IoT Platform を基にしています。他のプラットフォームを使用する場合は、 example フォルダ内の他のサンプルを参照してください。

SIM カードとデバッグモードの選択は HTTP と同じです。

MQTT_BROKERmqtt_devidmqtt_pubidmqtt_password を個人の MQTT アカウント情報に置き換えてください。質問がある場合は、このチュートリアルを参照してください。

cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
#include <M5AtomS3.h>
#include "ATOM_DTU_NB.h"
#include <PubSubClient.h>
#include <TinyGsmClient.h>
#include <time.h>
#include <sys/time.h>
#define MQTT_BROKER   "*********"  //Baidu Cloud address
#define MQTT_PORT     1883        //Port number

#define UPLOAD_INTERVAL   2000
#define mqtt_devid        "*******"                      //Device ID
#define mqtt_pubid        "*************"        //username
#define mqtt_password     "*************"          //password
int postMsgId = 0;  //Keep track of how many posts have been made
// This is the template used by post to upload data
#define ONENET_POST_BODY_FORMAT "{\"id\":%d,\"dp\":%s}"
// Receiving and sending properties set the subject
// Receive device properties to get the command topic
#define ONENET_TOPIC_GET "$iot/" mqtt_devid "/msg"
// Send data subject on the device
#define ONENET_TOPIC_POST  "$iot/" mqtt_devid "/events"
int num=0;
uint32_t lastReconnectAttempt = 0;

#define DUMP_AT_COMMANDS    //If you need to debug, you can open this macro definition and TinyGsmClientSIM7028.h line 13 //#define TINY_GSM_DEBUG Serial
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
    StreamDebugger debugger(SerialAT, SerialMon);
    TinyGsm modem(debugger, ATOM_DTU_SIM7028_RESET);
#else
    TinyGsm modem(SerialAT, ATOM_DTU_SIM7028_RESET);
#endif

TinyGsmClient tcpClient(modem);
PubSubClient mqttClient(MQTT_BROKER, MQTT_PORT, tcpClient);

void mqttCallback(char *topic, byte *payload, unsigned int len);
bool mqttConnect(void);
void nbConnect(void);

void log(String info) {
    SerialMon.println(info);
}

void setup() {
    AtomS3.begin(true);
    Serial.println(">>ATOM DTU NB MQTT TEST");
    SerialAT.begin(SIM7028_BAUDRATE, SERIAL_8N1, ATOM_DTU_SIM7028_RX,
                   ATOM_DTU_SIM7028_TX);
    AtomS3.dis.drawpix(0x0000ff);
    nbConnect();
    mqttClient.setServer(MQTT_BROKER, MQTT_PORT);
    mqttClient.setCallback(mqttCallback);
}

void loop() {
    static unsigned long timer = 0;

    if (!mqttClient.connected()) {
        log(">>MQTT NOT CONNECTED");
        log(mqttClient.state());
        AtomS3.dis.drawpix(0xff0000);
        uint32_t t = millis();
        if (t - lastReconnectAttempt > 10000L) {
            lastReconnectAttempt = t;
            if (mqttConnect()) {
                lastReconnectAttempt = 0;
            }
        }
        delay(100);
    }
    if (millis() >= timer) {
        timer = millis() + UPLOAD_INTERVAL;
        if (mqttClient.connected())
        {
          // First concatenate the json string
          char param[120];
          char jsonBuf[178];
          sprintf(param, "{\"num\":[{\"v\":%d}]}",num); // We write the data to be uploaded in the param

          postMsgId += 1;
          num+=1;
          if(num>256){
            num=0;
          }
          sprintf(jsonBuf, ONENET_POST_BODY_FORMAT, postMsgId, param);

          log("public the data:");
          log(jsonBuf);
          log("\n");

          mqttClient.publish(ONENET_TOPIC_POST, jsonBuf);
          //Send data to the topic
          delay(100);

        }
    }
    AtomS3.dis.drawpix(0x00ff00);
    mqttClient.loop();
}

void mqttCallback(char *topic, byte *payload, unsigned int len) {
    char info[len + 1];
    memcpy(info, payload, len);
    info[len] = '\0';
    log("Message arrived:"+String(info));
    log("Topic received: " + String(topic));
}

bool mqttConnect(void) {
    log("Connecting to ");
    log(MQTT_BROKER);
    bool status =mqttClient.connect(mqtt_devid, mqtt_pubid, mqtt_password);
    if (status == false) {
        int errorCode = mqttClient.state();
        log("MQTT Connection failed with error code: " + String(errorCode));
        return false;
    }
    log("MQTT CONNECTED!");
    mqttClient.subscribe(ONENET_TOPIC_GET);
    return mqttClient.connected();
}

void nbConnect(void) {
    unsigned long start = millis();
    log("Initializing modem...");
    while (!modem.init()) {
        log("waiting...." + String((millis() - start) / 1000) + "s");
    };

    start = millis();
    log("Waiting for network...");
    while (!modem.waitForNetwork()) {
        log("waiting...." + String((millis() - start) / 1000) + "s");
    }
    log("success");
    String ccid = modem.getSimCCID();
    Serial.println("CCID: " + ccid);
    int csq = modem.getSignalQuality();
    Serial.println("Signal quality: " + String(csq));
}

MQTT サービスが正常に接続されると、MQTT Explorer を使用してサブスクリプショントピックを追加し、データを確認できます。(質問がある場合は、このインターフェースを参照してください)

On This Page