16_ThingsBoard

ThingsBoardとデータを送受信する

温湿度をThingsBoardへ送信し、ThingsBoardからLEDを操作します。

温湿度センサーモジュールLEDモジュールWi-Fi通信
1

準備する

CherryIoTとモジュールを接続する

CherryIoTの指定コネクタに以下のモジュールを接続し、CherryIoTをPCのUSB-A挿入口に接続します。

温湿度センサーモジュール

温湿度センサーモジュール

接続先:A

LEDモジュール

LEDモジュール

接続先:B

Wi-Fiの情報を確認する

CherryIoTを接続する2.4GHz Wi-FiのSSID(ネットワーク名)とパスワードを確認します。Wi-Fiルーター本体のラベルや設定画面に記載されています。分からない場合は、ネットワークの管理者に確認してください。

ThingsBoardを準備する

ThingsBoard Cloudを開く

ThingsBoardのWebサイトを開き、「Try it now」をクリックします。すでにThingsBoard Cloudのアカウントを持っている場合は、「新しいデバイスを追加する」へ進んでください。

ThingsBoardのWebサイトでTry it nowを選ぶ画面

ThingsBoard Cloudのリージョンを選ぶ

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

ThingsBoard CloudでNorth Americaを選ぶ画面

アカウントを作成する

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

ThingsBoard Cloudのサインアップ画面

確認メールを送信する

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

ThingsBoard Cloudのメール確認画面

メールからアカウントを有効にする

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

ThingsBoard Cloudから届いたアカウント確認メール

ThingsBoard Cloudへログインする

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

ThingsBoard Cloudのアカウント有効化完了画面

初期案内を閉じる

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

ThingsBoard Cloudの初回案内画面

サインアップ完了

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

ThingsBoard Cloudのホーム画面でAdd deviceを選ぶ画面

新しいデバイスを追加する

左メニューの「Entities」→「Devices」を開き、「Add device」→「Add new device」を選びます。

ThingsBoard CloudでAdd new deviceを選ぶ画面

デバイス名を設定する

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

ThingsBoard CloudでCherryIoTデバイスを作成する画面

アクセストークンを確認する

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

ThingsBoard Cloudでデバイスのアクセストークンを確認する画面

デバイスの作成を完了する

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

ThingsBoard Cloudのデバイス作成完了と接続確認画面

作成したデバイスを確認する

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

ThingsBoard CloudのDevices一覧にCherryIoTが表示された画面

アクセストークンを再確認する

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

ThingsBoard Cloudのデバイス詳細画面にあるCopy access token

ダッシュボードを作成する

左側の「Dashboards」を開き、「Add dashboard」→「Create new dashboard」を選びます。

ThingsBoard CloudでCreate new dashboardを選ぶ画面

ダッシュボード名を設定する

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

ThingsBoard CloudでCherryIoTダッシュボードを作成する画面

ウィジェットを追加する

作成したダッシュボードを開き、「Add widget」をクリックします。

ThingsBoard CloudのCherryIoTダッシュボードでAdd widgetを選ぶ画面

IoT Hubのウィジェットを開く

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

ThingsBoard Cloudのウィジェット一覧でIoT Hubを選ぶ画面

温度表示用のカードを選ぶ

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

ThingsBoard IoT HubのCards and Infoから温度カードを選ぶ画面

Indoor temperature cardを追加する

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

ThingsBoardのIndoor temperature cardを追加する画面

温度カードをCherryIoTへ関連付ける

Deviceに「CherryIoT」を選び、そのまま「Add」をクリックします。HumidityもTemperatureと同様の手順で作成します。

ThingsBoardの温度カードにCherryIoTデバイスを設定する画面

LED操作用のウィジェットを追加する

温度と湿度のカードを追加したら、もう一度「Add widget」を開きます。

ThingsBoardのダッシュボードに温度と湿度のカードを追加した画面

Power buttonを検索する

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

ThingsBoardのInstalledウィジェットでbuttonを検索する画面

Power buttonを選ぶ

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

ThingsBoardのButtons一覧からPower buttonを選ぶ画面

Power buttonをCherryIoTへ関連付ける

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

ThingsBoardのPower ButtonにCherryIoTとRPCメソッドを設定する画面

ダッシュボードを保存する

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

ThingsBoardのCherryIoTダッシュボードに温度、湿度、Powerが表示された画面

Arduino IDEに必要なライブラリをインストールする

このサンプルでは、次のライブラリを追加する必要があります。

  • DHT20 by Rob Tillaart
  • PubSubClient by Nick O'Leary

初めて使用する場合のみインストールしてください。

ライブラリをインストールする
2

サンプルコード

GitHubで公開しているサンプルコードです。コードをコピーして Arduino IDEで使用します。

16_ThingsBoard.ino
GitHubで開く
GitHubからコードを読み込んでいます...
3

プログラムを書き込む

上のサンプルコードをコピーし、Arduino IDEに貼りつけます。

設定情報を書き換える

コード内の以下の箇所を、「1 準備する」で確認・取得した情報に 書き換えます。

コード内の項目入力する情報
ssid接続するWi-FiのSSID
passwordWi-Fiのパスワード
tokenThingsBoardで取得したデバイスのアクセストークン
const char* ssid = "ここにSSIDを入力";const char* password = "ここにパスワードを入力";const char* token = "ここにアクセストークンを入力";

コードの左側にある項目名や記号は残し、例を参考に値の部分だけを 書き換えます。値を囲む"、行末の;、 証明書の開始・終了行などは削除しません。書き換えたあと、xxxxxなどの仮の文字が残っていないことを確認してください。

Wi-Fiのパスワード、APIキー、トークン、証明書などを入力したコードは、 Webサイト、SNS、GitHubなどへ公開しないでください。

ボードとポートの設定を確認し、左上の 「→(書き込みボタン)」を押してCherryIoTに書き込みます。

初めて書き込む方は「はじめてのCherryIoT」で詳しい手順を確認してください。

4

動作確認

ThingsBoardで確認する

1温度と湿度が表示されることを確認する

プログラムを書き込んでCherryIoTがThingsBoardへ接続すると、TemperatureとHumidityに温湿度センサーで測定した値が表示されます。

ThingsBoardのCherryIoTダッシュボードに温度と湿度が表示された画面

2PowerからLEDを操作する

ThingsBoardのPowerをON・OFFして、コネクタBのLEDが点灯・消灯することを確認します。

次の2つを確認できれば成功です。

  • ThingsBoardに温度と湿度が表示される
  • ThingsBoardの画面からLEDを点灯・消灯できる

動作中、シリアルモニターには温湿度センサーで測定した温度と湿度、ThingsBoardとの通信状況が表示されます。Powerを操作したときは、受信したRPCメッセージとLEDの状態も表示されます。

Arduino IDEの画面右上にあるアイコンをクリックすると、 画面下にシリアルモニターが表示されます。

Arduino IDEでシリアルモニターを表示する場所
5

コードの解説

MQTTでテレメトリを送信し、RPCメッセージを受信してLEDの状態を切り替えます。

16_ThingsBoard.ino
GitHubで開く
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のテレメトリとして送信します。テレメトリは機器からクラウドへ送る測定値などのデータです。