LoRa モジュール LRA1 のデータを 「IoT データ可視化サービス Ambient」 へ送信
2022/12/27 : hexToInt() を改良, binToInt() を追加
■概要
LRA1 評価ボードの温湿度、気圧センサ BME280 のデータをデータ可視化サービス Ambient に送信します。
送信側 LRA1 では温度、湿度、気圧データを送信。
受信側 LRA1 でそれを受け取り、温度-湿度から露点温度を計算。WiFi 経由で各データを Ambient に送信します。
WiFi 接続、露点計算に Seeed Studio XIAO ESP32C3 を使っています。
■データ可視化サービス Ambient
Ambient については、こちらです。

■LRA1 送信側
'' BME280Send.bas 277 Bytes
'' 参照:LRA1 UART/BASIC チュートリアル
Do
'' BME280 値取得
Bme T, H, P
' Print "T=";T
' Print "H=";H
' Print "P=";P
'' LCD に表示
LClr
LPrint Form("2",T/10);".";Abs(T)%10;" ";H/10;"%"
LPos = 64
LPrint P/10;".";P%10;"hP"
'' 送信
Txd = wChr(T);wChr(H);wChr(P)
Send
Delay 500
Loop
End
'' BME280Recv.bas 315 Bytes
'' 参照:LRA1 UART/BASIC チュートリアル
UBaud = 19200
LClr
Do
'' 受信
Recv 1000
If Stat = 10 Then
'' 温度、湿度、気圧の値を取得
T = Int16(Rxdw(8))
H = Rxdw(10)
P = Rxdw(12)
' Print "T=";T
' Print "H=";H
' Print "P=";P
While UInkey >= 0: Loop ''UART2 受信バッファをクリア
'' UART2 送信(16進4桁 x 3 + CrLf) XAIO ESP32C3 へ送信
UPrint Form("04X", T); Form("04X", H); Form("04X", P)
' Print "send:";Form("04X", T); Form("04X", H); Form("04X", P)
'' UART2 露点計算値を受信(16進4桁 + CrLf)
^ = UGets(100) '' XAIO ESP32C3 から受信
' Print "len=";^[] '' 受信文字列の長さ(CrLfを含まない)
' Print ^
'' LCD に表示
LClr
LPrint Form("2",T/10);".";Abs(T)%10;" ";H/10;"%"
LPos = 64
''LPrint P/10;".";P%10;"hP" '' 気圧(未使用)
If ^[] = 4 Then ''制御文字を含まない文字数
D = "$";Chr(^[0]);Chr(^[1]);Chr(^[2]);Chr(^[3])
'' AQM0802A-RN-GBW データシート
'' https://akizukidenshi.com/download/ds/xiamen/AQM0802.pdf
LPrint D/10;".";Abs(D)%10;Chr($F2);"CDP" ''="℃DP"
' Print "DP ";D/10;".";Abs(D)%10
EndIf
EndIf
Loop
End
/*
* 温度、湿度から露点温度を計算し、IoT データ可視化サービス Ambient へ送信する
*/
#include "Ambient.h"
WiFiClient client;
Ambient ambient;
const char* ssid = "TP-LINK_****"; //"your ssid";
const char* password = "3641****"; //"your password";
unsigned int channelId = 59***; //100; // AmbientのチャネルID
const char* writeKey = "9ea686d2********"; //"writeKey"; // ライトキー
String recvStr = "";
unsigned long ticks;
void setup() {
// LRA1 との通信
Serial.begin(19200);
delay(100);
WiFi.begin(ssid, password); // Wi-Fi APに接続
while (WiFi.status() != WL_CONNECTED) { // Wi-Fi AP接続待ち
delay(100);
}
//Serial.print("WiFi connected\r\nIP address: ");
//Serial.println(WiFi.localIP());
ambient.begin(channelId, writeKey, &client); // チャネルIDとライトキーを指定してAmbientの初期化
ticks = millis();
}
void loop() {
float temp, humi, dewp;
int index = 0;
// UART0 受信 (LRA1から温度、湿度、気圧を受信)
if (Serial.available()){
recvStr = Serial.readStringUntil(0x0A);
recvStr.trim();
index = recvStr.length();
}
if (index >= 12) {
temp = hexToInt(recvStr.substring(0, 4)) / 10.0; // 温度
humi = hexToInt(recvStr.substring(4, 8)) / 10.0; // 湿度
String hpas = recvStr.substring(8, 12); // 気圧(未使用)
// 露点温度計算
dewp = dewPointC(temp, humi);
String DP = String((int)(dewp * 10.0), HEX);
strDigits(DP, 4); // 桁合わせ
Serial.println(DP); // UART0 送信(LRA1へ露点温度を送信)
// Ambientへのデータ送信(約30秒ごと)
if ((millis() - ticks) >= 30000) { // 30秒
ticks = millis();
// 温度、湿度、露点温度を Ambient に送信する
ambient.set(1, String(temp).c_str());
ambient.set(2, String(humi).c_str());
ambient.set(3, String(dewp).c_str());
ambient.send();
}
}
}
// 桁そろえ(文字列の前に"0"を追加)
void strDigits(String& str, int digits) {
int len = str.length();
if (len < digits) {
for (int i = len; i < digits; i++) {
str = "0" + str;
}
}
}
// hex ="0D0A" or "0x0D0A"
long hexToInt(String hex) {
int l = hex.length();
unsigned char buf[l + 1];
hex.getBytes(buf, l + 1); // char[] に
return strtol((const char*)buf, NULL, 16); // HexToInt
}
// bin = "1111" or "0b1111"
long binToInt(String bin) {
int l = bin.length();
if (l > 2){
String c = bin.substring(1, 2);
c.toUpperCase();
if (c == "B"){
bin = bin.substring(2);
l = bin.length();
}
}
unsigned char buf[l + 1];
bin.getBytes(buf, l + 1); // char[] に
return strtol((const char*)buf, NULL, 2); // BinToInt
}
// BME280:dewPointC()を流用(かなり誤差がある)
double dewPointC(double celsius, double humidity) {
//double celsius = readTempC();
//double humidity = readFloatHumidity();
// (1) Saturation Vapor Pressure = ESGG(T)
double RATIO = 373.15 / (273.15 + celsius);
double RHS = -7.90298 * (RATIO - 1);
RHS += 5.02808 * log10(RATIO);
RHS += -1.3816e-7 * (pow(10, (11.344 * (1 - 1 / RATIO))) - 1);
RHS += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1);
RHS += log10(1013.246);
// factor -3 is to adjust units - Vapor Pressure SVP * humidity
double VP = pow(10, RHS - 3) * humidity;
// (2) DEWPOINT = F(Vapor Pressure)
double T = log(VP / 0.61078); // temp var
return (241.88 * T) / (17.558 - T);
}