16_ThingsBoard
ThingsBoardとデータを送受信する
温湿度をThingsBoardへ送信し、ThingsBoardからLEDを操作します。
準備する
CherryIoTとモジュールを接続する
CherryIoTの指定コネクタに以下のモジュールを接続し、CherryIoTをPCのUSB-A挿入口に接続します。
温湿度センサーモジュール
接続先:A
LEDモジュール
接続先:B
Wi-Fiの情報を確認する
CherryIoTを接続する2.4GHz Wi-FiのSSID(ネットワーク名)とパスワードを確認します。Wi-Fiルーター本体のラベルや設定画面に記載されています。分からない場合は、ネットワークの管理者に確認してください。
ThingsBoardを準備する
ThingsBoard Cloudを開く
ThingsBoardのWebサイトを開き、「Try it now」をクリックします。すでにThingsBoard Cloudのアカウントを持っている場合は、「新しいデバイスを追加する」へ進んでください。

ThingsBoard Cloudのリージョンを選ぶ
「Cloud」を選び、「North America」をクリックします。このサンプルではNorth Americaを使用します。

アカウントを作成する
ここでは、メールアドレスを使って登録する方法を説明します。サインアップ画面で必要な情報を入力して、ThingsBoard Cloudのアカウントを作成します。

確認メールを送信する
登録したメールアドレスに確認メールが送信されます。メールが届かない場合は「再送信」から再送できます。

メールからアカウントを有効にする
ThingsBoard Cloudから届いたメールを開き、アカウントを有効にするボタンをクリックします。

ThingsBoard Cloudへログインする
アカウントが有効になったことを確認し、「ログイン」をクリックします。

初期案内を閉じる
初回ログイン時に案内画面が表示された場合は、内容を確認して閉じます。

サインアップ完了
サインアップできました。ThingsBoard Cloudのホーム画面が表示されます。

新しいデバイスを追加する
左メニューの「Entities」→「Devices」を開き、「Add device」→「Add new device」を選びます。

デバイス名を設定する
Nameにデバイス名を入力します。名前は任意です。ここでは「CherryIoT」としています。Device profileは「default」、Is gatewayはOFFのまま「Next: Credentials」をクリックします。

アクセストークンを確認する
CredentialsでAccess tokenを確認して控えます。このアクセストークンは、あとでサンプルコードのtokenへ設定します。確認したら「Add」をクリックします。

デバイスの作成を完了する
デバイスを作成すると接続確認画面が表示されます。このサンプルではCherryIoTから接続するため、ここでコマンドを実行する必要はありません。「Close」で閉じます。

作成したデバイスを確認する
Devicesの一覧に「CherryIoT」が追加されます。まだCherryIoTを接続していないため、この時点では「Inactive」と表示されます。

アクセストークンを再確認する
作成したデバイスを開くと、「Copy access token」からアクセストークンを確認できます。作成時に控え忘れた場合は、ここからも確認できます。

ダッシュボードを作成する
左側の「Dashboards」を開き、「Add dashboard」→「Create new dashboard」を選びます。

ダッシュボード名を設定する
Titleにダッシュボード名を入力します。名前は任意です。ここでは「CherryIoT」としています。入力したら「Add」をクリックします。

ウィジェットを追加する
作成したダッシュボードを開き、「Add widget」をクリックします。

IoT Hubのウィジェットを開く
ウィジェット一覧で「IoT Hub」を選び、「Cards & Info」を開きます。

温度表示用のカードを選ぶ
温度と湿度を表示するカードをそれぞれ作成します。まずは「Indoor temperature card」を選び、Temperatureから設定します。

Indoor temperature cardを追加する
Indoor temperature cardの内容を確認して「Add」をクリックします。

温度カードをCherryIoTへ関連付ける
Deviceに「CherryIoT」を選び、そのまま「Add」をクリックします。HumidityもTemperatureと同様の手順で作成します。

LED操作用のウィジェットを追加する
温度と湿度のカードを追加したら、もう一度「Add widget」を開きます。

Power buttonを検索する
ウィジェット一覧の「Installed」を開き、検索欄に「button」と入力して「Buttons」を選びます。

Power buttonを選ぶ
Buttonsの一覧から、LEDのON・OFFに使用する「Power button」を選びます。

Power buttonをCherryIoTへ関連付ける
Target deviceに「CherryIoT」を選びます。Initial stateのgetState、Power OnのsetState(true)、Power OffのsetState(false)はそのまま使用し、「Add」をクリックします。

ダッシュボードを保存する
Temperature、Humidity、Powerが表示されたら、右上の「Save」をクリックしてダッシュボードを保存します。現在はCherryIoTをThingsBoardへ接続していないため、温度・湿度はN/A、PowerにはRequest timeoutのエラーが表示されていますが問題ありません。

Arduino IDEに必要なライブラリをインストールする
このサンプルでは、次のライブラリを追加する必要があります。
- DHT20
- PubSubClient
初めて使用する場合のみインストールしてください。
ライブラリをインストールするサンプルコード
GitHubで公開しているサンプルコードです。コードをコピーして Arduino IDEで使用します。
GitHubからコードを読み込んでいます...プログラムを書き込む
上のサンプルコードをコピーし、Arduino IDEに貼りつけます。
設定情報を書き換える
コード内の以下の箇所を、「1 準備する」で確認・取得した情報に 書き換えます。
| コード内の項目 | 入力する情報 |
|---|---|
ssid | 接続するWi-FiのSSID |
password | Wi-Fiのパスワード |
token | ThingsBoardで取得したデバイスのアクセストークン |
const char* ssid = "ここにSSIDを入力";const char* password = "ここにパスワードを入力";const char* token = "ここにアクセストークンを入力";コードの左側にある項目名や記号は残し、例を参考に値の部分だけを 書き換えます。値を囲む"、行末の;、 証明書の開始・終了行などは削除しません。書き換えたあと、xxxxxなどの仮の文字が残っていないことを確認してください。
Wi-Fiのパスワード、APIキー、トークン、証明書などを入力したコードは、 Webサイト、SNS、GitHubなどへ公開しないでください。
ボードとポートの設定を確認し、左上の 「→(書き込みボタン)」を押してCherryIoTに書き込みます。
初めて書き込む方は「はじめてのCherryIoT」で詳しい手順を確認してください。
動作確認
ThingsBoardで確認する
1温度と湿度が表示されることを確認する
プログラムを書き込んでCherryIoTがThingsBoardへ接続すると、TemperatureとHumidityに温湿度センサーで測定した値が表示されます。

2PowerからLEDを操作する
ThingsBoardのPowerをON・OFFして、コネクタBのLEDが点灯・消灯することを確認します。
次の2つを確認できれば成功です。
- ThingsBoardに温度と湿度が表示される
- ThingsBoardの画面からLEDを点灯・消灯できる
動作中、シリアルモニターには温湿度センサーで測定した温度と湿度、ThingsBoardとの通信状況が表示されます。Powerを操作したときは、受信したRPCメッセージとLEDの状態も表示されます。
Arduino IDEの画面右上にあるアイコンをクリックすると、 画面下にシリアルモニターが表示されます。

コードの解説
MQTTでテレメトリを送信し、RPCメッセージを受信してLEDの状態を切り替えます。
GitHubからコードを読み込んでいます...#include <DHT20.h>温湿度センサーDHT20を使うためのライブラリを読み込みます。
#include <Wire.h>I2C通信を使うためのWireライブラリを読み込みます。I2Cは、少ない信号線でセンサーなどとデータをやり取りする通信方式です。
#include <WiFi.h>CherryIoTをWi-Fiへ接続するためのライブラリを読み込みます。
#include <WiFiClientSecure.h>暗号化された通信を行うためのWiFiClientSecureライブラリを読み込みます。
#include <PubSubClient.h>MQTT通信を行うためのPubSubClientライブラリを読み込みます。MQTTは、機器とクラウドの間で軽量にデータを送受信する通信方式です。
const char* ssid = "xxxxx";CherryIoTを接続するWi-FiのSSIDを、ssidへ保存します。
const char* password = "xxxxx";Wi-Fiのパスワードを、passwordへ保存します。
const char* mqtt_server = "thingsboard.cloud";MQTTの接続先をThingsBoard Cloudに設定します。
const int mqtt_port = 8883;暗号化されたMQTT通信に使用する8883番ポートを、mqtt_portへ保存します。
const char* token = "xxxxx";ThingsBoardで作成したデバイスのアクセストークンを、tokenへ保存します。
const char* temperature_key = "temperature";ThingsBoardへ送る温度データの項目名を、temperature_keyへ保存します。
const char* humidity_key = "humidity";ThingsBoardへ送る湿度データの項目名を、humidity_keyへ保存します。
DHT20 DHT;DHT20を操作するためのDHTオブジェクトを作ります。
WiFiClientSecure espClient;ThingsBoardと暗号化通信を行うためのespClientオブジェクトを作ります。
PubSubClient client(espClient);espClientを使ってMQTT通信するためのclientオブジェクトを作ります。
const int ledPin = 4;コネクタBのLEDに対応するGPIO4を、定数ledPinへ保存します。
void callback(char* topic, byte* payload, unsigned int length) {ThingsBoardからMQTTメッセージを受信したときに実行する処理を、callback関数にまとめます。topicには受信先のトピック名、payloadには受信データ、lengthにはデータの長さが渡されます。
String topicStr = String(topic);受信したトピック名を扱いやすいString型へ変換し、topicStrへ保存します。
String message;受信したメッセージを組み立てるためのmessageを用意します。
for (unsigned int i = 0; i < length; i++) {受信したデータの長さだけ繰り返し処理します。
message += (char)payload[i];受信したデータを1文字ずつmessageへ追加します。
Serial.println("[MQTT] Topic: " + topicStr);受信したMQTTトピックをシリアルモニターへ表示します。
Serial.println("[MQTT] Payload: " + message);受信したメッセージの内容をシリアルモニターへ表示します。
if (topicStr.startsWith("v1/devices/me/rpc/request/")) {受信したトピックがThingsBoardからのRPC操作かを確認します。RPCは、ネットワーク経由で機器側の処理を呼び出す仕組みです。
String requestId = topicStr.substring(strlen("v1/devices/me/rpc/request/"));RPCのトピックからリクエスト番号を取り出し、requestIdへ保存します。getStateへの返信先を作るときに使用します。
if (message.indexOf(""method":"setState"") >= 0) {受信したメッセージが、LEDの状態を変更するsetState命令かを確認します。
bool ledState = message.indexOf("true") >= 0;受信内容にtrueが含まれているかを確認し、LEDをONにするかOFFにするかをledStateへ保存します。
digitalWrite(ledPin, ledState ? HIGH : LOW);ledStateがtrueならLEDを点灯し、falseなら消灯します。
Serial.println(ledState ? "LED ON" : "LED OFF");LEDの状態に合わせて「LED ON」または「LED OFF」をシリアルモニターへ表示します。
else if (message.indexOf(""method":"getState"") >= 0) {受信したメッセージが、現在のLED状態を取得するgetState命令かを確認します。
bool currentState = digitalRead(ledPin) == HIGH;現在のLED出力を読み取り、点灯しているかどうかをcurrentStateへ保存します。
String responseTopic = "v1/devices/me/rpc/response/" + requestId;getStateの結果を返すための返信先トピックを、requestIdを使って作ります。
String responsePayload = currentState ? "true" : "false";現在のLED状態を、ThingsBoardへ返すtrueまたはfalseの文字列へ変換します。
client.publish(responseTopic.c_str(), responsePayload.c_str());現在のLED状態をThingsBoardへ返信します。
Serial.println("Reported LED state: " + responsePayload);ThingsBoardへ返信したLED状態をシリアルモニターへ表示します。
void InitWiFi() {Wi-Fiへ接続する処理を、InitWiFi関数にまとめます。
Serial.print("Connecting to WiFi");Wi-Fiへの接続を開始することをシリアルモニターへ表示します。
WiFi.begin(ssid, password);設定したSSIDとパスワードを使ってWi-Fiへの接続を開始します。
while (WiFi.status() != WL_CONNECTED) {Wi-Fiへ接続されるまで処理を繰り返します。
Serial.print(".");接続待ちであることを「.」で表示します。
Serial.println("
WiFi connected");Wi-Fiへ接続できたことをシリアルモニターへ表示します。
void reconnect() {ThingsBoardとのMQTT接続が切れたときに再接続する処理を、reconnect関数にまとめます。
while (!client.connected()) {ThingsBoardへ接続できるまで処理を繰り返します。
Serial.println("[TB] Connecting to ThingsBoard...");ThingsBoardへの接続を開始することをシリアルモニターへ表示します。
if (client.connect("ESP32C3Client", token, NULL)) {「ESP32C3Client」というクライアント名とアクセストークンを使ってThingsBoardへMQTT接続します。NULLはパスワードを指定しないことを表します。
Serial.println("[TB] Connected to ThingsBoard!");ThingsBoardへ接続できたことをシリアルモニターへ表示します。
client.subscribe("v1/devices/me/rpc/request/+");ThingsBoardから送られるRPC操作を受信できるよう、RPC用のMQTTトピックを購読します。+は任意のリクエスト番号を受け取るための記号です。
} else {client.setCallback(callback);ThingsBoardへ接続できなかった場合は、受信時に使うcallback関数を設定してから接続エラーの情報を表示します。
Serial.print("[TB] Failed, rc=");ThingsBoardへの接続に失敗したことをシリアルモニターへ表示します。
Serial.print(client.state());MQTT接続に失敗したときの状態コードをシリアルモニターへ表示します。
Serial.println(" try again in 5 seconds");5秒後に再接続することをシリアルモニターへ表示します。
void setup() {setup関数は、CherryIoTの電源を入れたときやリセットしたときに1回だけ実行されます。ここで通信や端子の初期設定を行います。
Serial.begin(115200);ThingsBoardとの接続状況や測定値をPCへ表示するため、115200bpsでシリアル通信を開始します。
Wire.begin(1, 3);温湿度センサーとI2C通信するため、SDAをGPIO1、SCLをGPIO3として通信を開始します。
pinMode(ledPin, OUTPUT);LEDへ信号を出力できるように、ledPinをOUTPUT(出力)に設定します。
digitalWrite(ledPin, LOW);起動時のLEDを消灯状態にします。
espClient.setInsecure();ThingsBoardとの暗号化通信でサーバー証明書の検証を省略する設定にします。
InitWiFi();InitWiFi関数を呼び出し、Wi-Fiへ接続します。
client.setServer(mqtt_server, mqtt_port);MQTTの接続先として、ThingsBoard Cloudのサーバーと8883番ポートを設定します。
client.setCallback(callback);MQTTメッセージを受信したときにcallback関数を実行するよう設定します。
void loop() {loop関数はsetup関数のあとに繰り返し実行されます。ThingsBoardとの接続を維持しながら、温度と湿度の測定・送信を繰り返します。
if (!client.connected()) {ThingsBoardとのMQTT接続が切れていないか確認します。
reconnect();接続されていない場合はreconnect関数を呼び出して再接続します。
client.loop();MQTT接続を維持し、ThingsBoardから届くメッセージを処理します。
DHT.read();DHT20へ測定を指示し、現在の温度と湿度のデータを読み取ります。
float humidity = DHT.getHumidity();読み取った湿度をhumidityへ保存します。
float temperature = DHT.getTemperature();読み取った温度をtemperatureへ保存します。
if (!isnan(humidity) && !isnan(temperature)) {温度と湿度の両方を正常に取得できたときだけ、表示と送信を行います。
Serial.print("Temperature: ");シリアルモニターへ「Temperature: 」と表示します。
Serial.println(temperature);測定した温度をシリアルモニターへ表示します。
Serial.print("Humidity: ");シリアルモニターへ「Humidity: 」と表示します。
Serial.println(humidity);測定した湿度をシリアルモニターへ表示します。
String payload = "{";ThingsBoardへ送る温度と湿度をJSON形式にまとめるため、payloadの作成を始めます。JSONは項目名と値を組み合わせてデータを表す形式です。
payload += """ + String(temperature_key) + "":" + String(temperature, 2) + ",";temperatureという項目名と、小数点以下2桁にした温度をpayloadへ追加します。
payload += """ + String(humidity_key) + "":" + String(humidity, 2);humidityという項目名と、小数点以下2桁にした湿度をpayloadへ追加します。
payload += "}";JSONの最後に「}」を追加して、送信データを完成させます。
client.publish("v1/devices/me/telemetry", payload.c_str());完成した温度と湿度のJSONを、ThingsBoardのテレメトリとして送信します。テレメトリは機器からクラウドへ送る測定値などのデータです。