Maixduino で AWS IoT に接続する


はじめに

MaixduinoはK210 CPUを載せたMaixシリーズの中でもそのままWiFiに接続できるボードです。AWS IoTにも簡単に接続できます。今回は一番簡単なArduino PubSubClientを使用します。

ESP32向けに書かれたこちらの記事を参考にさせて頂きました。

ESP32でAWS IoTに繋いでThing Shadowを弄る

AWS IoT

AWS IoTについては解説ページ等も多いので省略しますが、以下の作業を行います。

  • AWS IoTの登録
  • モノの登録
  • X.509証明書の生成
  • 証明書へのポリシーとモノのアタッチ

証明書は作成後にダウンロードしておく必要があります。失くしてしまうと再作成になります。

使用ライブラリー

Maixduino_WiFiEsp32でTLS接続できるようにしました。

コード

main.cpp
#include <Arduino.h>
#include <Sipeed_ST7789.h>
#include <WiFiEsp32.h>
#include <PubSubClient.h>

SPIClass spi_(SPI0);
Sipeed_ST7789 lcd(320, 240, spi_);

char SSID[] = "<YOUR_SSID>";
char PASS[] = "<YOUR_WIFI_PASSWORD>";
int status = WL_IDLE_STATUS;

const char *endpoint = "<AWS_IOT_ENDPOINT>";
// Example: xxxxxxxxxxxxxx.iot.ap-northeast-1.amazonaws.com
const int port = 8883;
char *pubTopic = "/sample123";
char *subTopic = "/sample123";

const char* certificate = "-----BEGIN CERTIFICATE-----\n" \
"......\n" \
"-----END CERTIFICATE-----\n";

const char* privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" \
"......\n" \
"-----END RSA PRIVATE KEY-----\n";

WiFiEspSSLClient httpsClient;
PubSubClient mqttClient(httpsClient);

long messageSentAt = 0;
int dummyValue = 0;
char pubMessage[128];

void mqttCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i=0;i<length;i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
}

void connectAWSIoT() {
  while (!mqttClient.connected()) {
    if (mqttClient.connect("maixamigo")) {
      Serial.println("Connected.");
      int qos = 0;
      mqttClient.subscribe(subTopic, qos);
      Serial.println("Subscribed.");
    } else {
      Serial.print("Failed. Error state=");
      Serial.print(mqttClient.state());
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  lcd.begin(15000000, COLOR_BLACK);
  Serial.begin(115200);   // initialize serial for debugging
  WiFi.init();    // initialize ESP32 module

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  status = WiFi.begin(SSID, PASS);
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(SSID);
    // Connect to WPA/WPA2 network
    sleep(1);
    status = WiFi.status();
  }

  Serial.println("Connected.");

  // Configure MQTT Client
  httpsClient.setCertificate(certificate);
  httpsClient.setPrivateKey(privateKey);
  mqttClient.setServer(endpoint, port);
  mqttClient.setCallback(mqttCallback);

  connectAWSIoT();
}


void loop() {
  if (!mqttClient.connected()) {
    connectAWSIoT();
  }
  mqttClient.loop();

  long now = millis();
  if (now - messageSentAt > 5000) {
    messageSentAt = now;
    sprintf(pubMessage, "{\"message\": \"%d\"}", dummyValue++);
    Serial.print("Publishing message to topic ");
    Serial.println(pubTopic);
    Serial.println(pubMessage);
    mqttClient.publish(pubTopic, pubMessage);
    Serial.println("Published.");
  }
}

さいごに

TLSで接続できれば、MaixduinoでもESP32と同様に簡単にAWS IoTに接続することができました。今後はM5StickV+M5Stackなどでも試したいと思っています。

メモ

Maixduinoの ESP32ファームウェア が2020年5月に1.4.0→1.4.1にアップデートされていたので、更新方法のメモ

  • esptool

PlatformIOでM5Stackを使っていれば、~/.platform/packages/tool-esptoolpy にも入っています。なければダウンロードします。

  • ファームウェアをダウンロード

GitHubのReleaseページ から maixduino_esp32_firmware_v1.4.1_0x0.bin をダウンロードします

  • 書き込み

Macであればこんな感じで書き込み

./esptool.py --chip esp32 --port /dev/cu.usbserial-xel_sipeed1 -b 115200 write_flash -z 0x0000 ~/Downloads/maixduino_esp32_firmware_v1.4.1_0x0.bin

参考