IoTシステムの概要を知り、実際にデバイスを動かしてみよう

2020年2月28日(金)
岡嵜 雄平

プログラムのコンパイル

今回、M5Stackに書き込むプログラム(M5Stack-PIR Motion Sensor読み取りプログラム)をこちらにアップロードしましたので、ダウンロードしてください。

ダウンロードが完了したらZipファイルを解凍し、M5StackCheckPoint.inoをArduino IDEで起動してください。

ダウンロードしたファイルを解凍

Arduino IDEが起動したら、一度プログラムを検証してみましょう。画面左上の「検証」をクリックします。

プログラムを検証

M5Stackにプログラムを書き込む

M5Stackにプログラムを書き込むため、M5StackとPCをUSBケーブルで接続します。次に「マイコンボードに書き込む」をクリックして、プログラムをM5Stackに書き込みます。

プログラムをM5Stackに書き込む

もし、書き込み時にエラーが表示される場合は、以下をご確認ください。

  • USBケーブルはしっかり接続できているか
  • 「ツール」→「シリアルポート」で選択されているシリアルポートはM5Stackと接続しているポートか
  • 「ツール」→「ボード」で「M5Stack-Core-ESP32」を選択しているか
  • 「ツール」→「Upload Speed」で「921600」を選択しているか

書き込みに失敗する場合の確認

動作確認

書き込みが完了したら、M5Stackの電源をONします。USB type-cケーブルを接続すると自動的に電源がONになります。電源がONにならない場合は電源ボタンを1回押してみてください。人感センサーの目の前で人が動くと、LCDディスプレイに「Hello!」と表示されるはずです。

人を検知する前

人を検知した後

プログラムの解説

今回準備したプログラムは2つのソースコードから構成されています。言語はArduino言語と呼ばれる、C/C++と類似した言語を使用します。C/C++と聞くと身構える人が多いかも知れませんが、Arduinoの各種ライブラリを活用することで、そこまで難しいコーディングをする必要がないことがわかると思います。

M5StackCheckPoint.ino

Arduino言語で書かれたソースコードのうち、setup()loop()は特殊な関数です。setup()は電源ON後に1度だけ呼ばれる、その名の通りセットアップ用の関数です。この関数でLCD初期化(setupLcd())を呼び出しています。

loop()setup()完了後に電源ONしている間繰り返し呼ばれる関数です。人感センサーの値を読み出し、前回から値が変化した場合のみLCDの表示を切り替えています。

現時点では、Wi-Fi接続(setupWifi())やMQTT接続(setupMqtt())、人感センサーの値送信(sendDetected())はコメントアウトしています。クラウドアプリケーションの構築が完了したら有効化します(次回で解説します)。

#include <M5Stack.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include "Free_Fonts.h"
#include "secret.h"

#define PIR_MOTION_SENSOR 36
#define CLIENT_ID "1"

static WiFiClientSecure httpsClient;
static PubSubClient mqttClient(httpsClient);
static int detected = 0;

// Wi-Fi接続する
void setupWifi() {
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    M5.Lcd.print(".");
    delay(1000);
  }
}

// MQTT接続する
void setupMqtt() {
  httpsClient.setCACert(ROOT_CA);
  httpsClient.setCertificate(CERTIFICATE);
  httpsClient.setPrivateKey(PRIVATE_KEY);
  mqttClient.setServer(CLOUD_ENDPOINT, CLOUD_PORT);
  while (!mqttClient.connected()) {
    if (!(mqttClient.connect(CLIENT_ID))) {
      delay(1000);
    }
  }
}

// LCDを初期化する
void setupLcd() {
  M5.Lcd.fillScreen(TFT_BLACK);
  M5.Lcd.setTextDatum(MC_DATUM);
  M5.Lcd.setFreeFont(FF44);
}

// 検知状態を送信する
void sendDetected(int detected) {
  // 検知状態をJSON化する
  char message[64] = {0};
  sprintf(message, "{\"detected\": %d}", detected);

  // JSONを送信する
  while(!(mqttClient.publish(CLOUD_TOPIC, message))) {
    // 送信失敗した場合は再接続してリトライする
    mqttClient.disconnect();
    while (!mqttClient.connected()) {
      if (!(mqttClient.connect(CLIENT_ID))) {
        M5.Lcd.print("#");
        delay(1000);
      }
    }
  }
}

void setup() {
  M5.begin();
  M5.Power.begin();
  // setupWifi(); TODO: Secret.hを編集する必要がある
  // setupMqtt(); TODO: Secret.hを編集する必要がある
  setupLcd();
  pinMode(PIR_MOTION_SENSOR, INPUT);
}

void loop() {
  // 検知状態を読み出し
  int ret = digitalRead(PIR_MOTION_SENSOR);
  if (ret != detected) {
    // 検知状態が変化した場合
    detected = ret;
    if (detected) {
      // 検知したとき: Hello!と表示しクラウドへ送信
      M5.Lcd.fillScreen(TFT_BLUE);
      M5.Lcd.setTextColor(TFT_WHITE, TFT_BLUE);
      M5.Lcd.drawString("Hello!", 160, 120, GFXFF);
    } else {
      // 検知していないとき
      M5.Lcd.fillScreen(TFT_BLACK);
      M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
      M5.Lcd.drawString("....", 160, 120, GFXFF);
    }
    // sendDetected(detected); TODO: Secret.hを編集する必要がある
    delay(1000);
  }
}

Secret.h

Wi-Fi、MQTT接続に関連する秘匿情報をまとめたヘッダファイルです。次回のクラウドアプリケーションを構築後にデータ送信を有効化するタイミングで、各項目を記載ください。

// WiFiのSSID, PASSWORDを入力
#define WIFI_SSID "xxxxxxxx"
#define WIFI_PASSWORD "xxxxxxxx"

// AWS IoT Coreのエンドポイントを確認し入力
#define CLOUD_ENDPOINT "xxxxxxxxxxxxxxxxx.iot.ap-northeast-1.amazonaws.com"
#define CLOUD_PORT 8883
#define CLOUD_TOPIC "/check_point"

// AWS IoT Coreで発行した証明書の内容を入力
#define ROOT_CA "-----BEGIN CERTIFICATE-----\n"\
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"\
"-----END CERTIFICATE-----\n"

#define CERTIFICATE "-----BEGIN CERTIFICATE-----\n"\
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"\
"-----END CERTIFICATE-----\n"

#define PRIVATE_KEY "-----BEGIN RSA PRIVATE KEY-----\n"\
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n"\
"-----END RSA PRIVATE KEY-----\n"\

おわりに

今回は、IoTシステムの概要および、M5Stackとセンサーの接続、M5Stackへのプログラムの書き込み手順を解説しました。無事にデバイスが動作すると、開発へのモチベーションも高まったのではないでしょうか。

しかし、これだけではまだ「IoT」とは呼べません。モノ(M5Stack)がインターネットに繋がっていないためです。次回はクラウド上にアプリケーションを構築した上で、M5Stackからデータを送信できるようプログラムを修正していきます。

次回もお楽しみに!

株式会社Fusic
mockmockの運用・開発を担当するエンジニア、AWS Certified Solutions Architect – Professional。山口県出身。高専卒業後、関西にて組込みソフトウェアの開発を数年間経験。その後、福岡へJターン転職。同時にWeb/IoTエンジニアにスキルチェンジした。プライベートでは2児の父。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています