04.ATOM Liteで降水確率のLED表示
04.ATOM Liteで降水確率のLED表示
降水確率をLEDの色表示します。Wi-Fi接続をして、気象庁の降水確率を06-12時 → 12-18時 → 18-24時で今日 → 明日 → 明後日の順にLEDで色表示します。10%ごとの降水確率の表示色は、抵抗のカラーコード表示色とし、100%は90%同じとしました。
0%→黒(消灯), 10%→茶, 20%→赤, 30%→橙, 40%→黄,
50%→緑, 60%→青, 70%→紫, 80%→灰, 90%→白, 100%→白
赤は降水確率20%
必要ハード
・ATOM Liteライブラリのインストール
Arduino-IDE > スケッチ > ライブラリをインクルード > ライブラリを管理... > "json" で検索ArduinoJson by Benoit Blanchon 6.19.4 をインストール > 閉じる
(Arduino_JSON by Arduino 0.1.0ではありません)
ArduinoJsonの解説
https://arduinojson.org/v6/doc/
XMLファイル
降水確率は一定時間内(ここでは6H)に1mm以上の雨or雪の降る確率で、四捨五入して10%単位で表現しています。気象庁の天気予報
https://www.jma.go.jp/bosai/forecast/
の内容をXMLとJSONP形式で配信してくれているJapan Weather Forecast xml(日本お天気予報)
https://www.drk7.jp/weather/
のサービスを利用します。
神奈川県の実際に使用するのはjsonファイル
https://www.drk7.jp/weather/json/14.js
ですが、ここでは見やすいXMLファイル
https://www.drk7.jp/weather/xml/14.xml
を参考にします。
・東部(横浜地方気象台)
今日から6日先までの7日間の天気・天気マーク(gif)・9-18時の日中の最高気温(℃)・0-9時の朝の最低気温(℃)・降水確率。今日と明日はさらに、詳細天気・波の高さ(m)も。
・西部(小田原観測所)
東部と同じ項目。ただし、明後日~6日先は横浜と同じデータです。
ある日の14.xmlを、一部見やすいように字下げ・改行・省略・注釈をつけると以下になります。
<weatherforecast>
<title>weather forecast xml</title>
<link>http://www.drk7.jp/weather/xml/14.xml</link>
<description>気象庁の天気予報情報を XML で配信。1日1回 AM 6:00 ごろ更新。</description>
<pubDate>Sat, 20 Aug 2022 06:00:01 +0900</pubDate>
<author>気象庁</author>
<managingEditor>drk7.jp</managingEditor>
<pref id="神奈川県">
<area id="東部"> ← 横浜
<geo><long/><lat/></geo>
<info date="2022/08/20"> ← 今日
<weather>曇</weather> ← 天気
<img>http://www.drk7.jp/MT/images/MTWeather/200.gif</img> ← 天気マーク
<weather_detail>くもり 所により 夕方 から 雨</weather_detail> ← 詳細天気
<wave>1メートル</wave> ← 波高
<temperature unit="摂氏">
<range centigrade="max">31</range> ← 最高温度
<range centigrade="min">23</range> ← 最低温度
</temperature>
<rainfallchance unit="%">
<period hour="00-06">10</period> ← 0-6時の降水確率
<period hour="06-12">10</period>
<period hour="12-18">20</period>
<period hour="18-24">30</period>
</rainfallchance>
</info>
<info date="2022/08/21"> ← 明日
<weather>曇一時雨</weather>
<img>http://www.drk7.jp/MT/images/MTWeather/202.gif</img>
<weather_detail>くもり 明け方 から 朝 雨</weather_detail>
<wave>1メートル</wave>
<temperature unit="摂氏">
<range centigrade="max">29</range>
<range centigrade="min">24</range>
</temperature>
<rainfallchance unit="%">
<period hour="00-06">60</period>
<period hour="06-12">60</period>
<period hour="12-18">20</period>
<period hour="18-24">20</period>
</rainfallchance>
</info>
<info date="2022/08/22"> ← 明後日
<weather>曇時々晴</weather>
<img>http://www.drk7.jp/MT/images/MTWeather/201.gif</img>
<temperature unit="摂氏">
<range centigrade="max">30</range>
<range centigrade="min">24</range>
</temperature>
<rainfallchance unit="%">
<period hour="00-06">30</period>
<period hour="06-12">30</period>
<period hour="12-18">30</period>
<period hour="18-24">30</period>
</rainfallchance>
</info>
<info date="2022/08/23"> ← 3日先
<weather>晴時々曇</weather>
・・・ 略 ・・・
</info>
<info date="2022/08/24"> ← 4日先
<weather>曇時々晴</weather>
・・・ 略 ・・・
</info>
<info date="2022/08/25"> ← 5日先
<weather>曇一時雨</weather>
・・・ 略 ・・・
</info>
<info date="2022/08/26"> ← 6日先
<weather>曇一時雨</weather>
・・・ 略 ・・・
</info>
</area>
<area id="西部"> ← 小田原
・・・ 略 ・・・
</area>
</pref>
</weatherforecast>
その時の気象庁の表示* 1時間に1mm以上の雨が降ると、普通に傘が必要です。降水確率30%以上は外出時傘を持った方が良いらしいです。
解説
気象庁 神奈川県の天気予報https://www.jma.go.jp/bosai/forecast/#area_type=offices&area_code=140000
表示内容
色表示は、0-6時の降水確率表示は省略し、1.今日の06-12時の降水確率
2.今日の12-18時
3.今日の18-24時
4.明日の06-12時
5.明日の12-18時
6.明日の18-24時
7.明後日(7-9は同じ値です)
8.明後日
9.明後日
の順です。
日付
今日は1回、明日は2回、明後日は3回、確率表示の前に短く白色が点灯します。色表示
降水確率と変更した表示色00%→黒 0x000000 or 消灯
10%→茶 0x100000 暗い赤800000では赤いので
20%→赤 0xFF0000
30%→橙 0xFF610F 橙EF810Fでは黄色っぽいので
40%→黄 0xFFFF00
50%→緑 0x008000
60%→青 0x0000FF
70%→紫 0x400080 紫800080では赤っぽいので
80%→灰 0x0F0F0F 暗い白808080では明るいので
90%&100%→白 0xFFFFFF
注意
drk7.jpでは、朝6時頃にデータを更新しているので、深夜1時に見ると今日の降水確率は、明日の降水確率表示の部分です。また、気象庁は毎日5時、11時、17時、天気が急変したときには随時修正して発表しているので、朝6時以降に更新された場合は、気象庁のデータと異なる場合があります。
スケッチ
**********の2件は、接続Wi-FiのSSIDとパスワードです。
// ATOM Liteで今日と明日と明後日の06-12,12-18,18-24時の降水確率9件を色表示
// 気象庁の天気予報をJson型式に変換してくれるdrk7.jpを利用 (drk7.jpの更新は毎朝6時頃)
// 変換サイト https://www.drk7.jp/weather/
// 気象庁の天気予報(横浜市) https://www.jma.go.jp/bosai/forecast/#area_type=class20s&area_code=1410000
#include <WiFi.h> // wifi使用
#include <HTTPClient.h> // HTTPClientを使用
#include <ArduinoJson.h> // json使用
#include <M5Atom.h> // Atom使用
const char* ssid = "**********"; // wifiのSSID
const char* password = "**********"; // そのパスワード
const char* endpoint = "https://www.drk7.jp/weather/json/14.js";//神奈川県
const char* region = "東部"; // 横浜地方気象台
// 関東1都6県は
// 東京都→"・・・/13.js", 東京地方(東京), 伊豆諸島北部, 伊豆諸島南部, 小笠原諸島
//神奈川県→"・・・/14.js",東部(横浜), 西部(小田原)
// 埼玉県→"・・・/11.js", 北部(熊谷), 南部(さいたま), 秩父地方
// 千葉県→"・・・/12.js", 北東部(銚子), 北西部(千葉), 南部(館山)
// 茨城県→"・・・/08.js", 北部(水戸), 南部(土浦)
// 栃木県→"・・・/09.js", 北部(大田原), 南部(宇都宮)
// 群馬県→"・・・/10.js", 北部(みなかみ), 南部(前橋)
DynamicJsonDocument weatherInfo(20000); //
String createJson(String jsonString) { // JSONPをJSONにする関数
jsonString.replace("drk7jpweather.callback(", ""); //
return jsonString.substring(0, jsonString.length() - 2); //
}
DynamicJsonDocument getJson() { //
DynamicJsonDocument doc(20000); //
if ((WiFi.status() == WL_CONNECTED)) { // wifiが接続されていたら
HTTPClient http; // 定義
http.begin(endpoint); //
int httpCode = http.GET(); // 登録URLに、GETリクエスト送信
if (httpCode > 0) { // HTTPのリターンコードにエラーがなければ
String jsonString = createJson(http.getString());//jsonオブジェクト作成関数
deserializeJson(doc, jsonString); //JSON文字列をCFML(構造体や配列など)に変換
} else {
Serial.println("HTTP要求エラー"); // シリアルモニタに表示
}
http.end(); // リソースを解放
}
return doc; //
}
void lighting(String rain) { // LED1回点灯関数
int intrain = rain.toInt(); // 文字を数値に変換
switch (intrain) {
case 0:
M5.dis.drawpix(0, 0x000000); break; // 黒
case 10:
M5.dis.drawpix(0, 0x100000); break; // 茶(暗い赤)800000では赤い
case 20:
M5.dis.drawpix(0, 0xFF0000); break; // 赤
case 30:
M5.dis.drawpix(0, 0xFF610F); break; // 橙EF810Fでは黄色っぽい
case 40:
M5.dis.drawpix(0, 0xFFFF00); break; // 黄
case 50:
M5.dis.drawpix(0, 0x008000); break; // 緑
case 60:
M5.dis.drawpix(0, 0x0000FF); break; // 青
case 70:
M5.dis.drawpix(0, 0x400080); break; // 紫800080では赤紫っぽい
case 80:
M5.dis.drawpix(0, 0x0F0F0F); break; // 灰(暗い白)808080では明るい
default:
M5.dis.drawpix(0, 0xFFFFFF); break; // 白
}
delay(1000); // 1秒点灯
M5.dis.drawpix(0, 0x000000); // 黒
delay(200); // 0.2秒消灯
}
void drawWeather(String infoWeather) { // 1日分のデータ表示関数
DynamicJsonDocument doc(20000); //
deserializeJson(doc, infoWeather); //
String docdate = doc["date"]; // 予報年月日
Serial.print("("); Serial.print(docdate); //シリアルモニタに表示
Serial.print("):"); // シリアルモニタに表示
String weather = doc["weather"]; // 天気予報
Serial.println(weather); // シリアルモニタに表示
String weatherdetail = doc["weather_detail"]; // 詳しい天気予報
if (weatherdetail != "null") { // 明後日以外の時
Serial.println(weatherdetail); // シリアルモニタに表示
}
String docwave = doc["wave"]; // 波の高さ
if (docwave != "null") { // 明後日以外の時
Serial.print("波:");
Serial.println(docwave); // シリアルモニタに表示
}
String maxTmp = doc["temperature"]["range"][0]["content"];
// 温度 範囲 最高 値
String minTmp = doc["temperature"]["range"][1]["content"];
// 温度 範囲 最低 値
String rain0006 = doc["rainfallchance"]["period"][0]["content"];
// 降水確率 期間 00-06 値
String rain0612 = doc["rainfallchance"]["period"][1]["content"]; // 06-12
String rain1218 = doc["rainfallchance"]["period"][2]["content"]; // 12-18
String rain1824 = doc["rainfallchance"]["period"][3]["content"]; // 18-24
Serial.print(maxTmp); Serial.print("℃max, "); // 最高気温を表示
Serial.print(minTmp); Serial.println("℃min"); // 最低気温を表示
Serial.printf("降水確率(0-6:%3s%%,)6-12:%3s%%, 12-18:%3s%%, 18-24:%3s%%\n",
rain0006, rain0612, rain1218, rain1824); // 降水確率
lighting(rain0612); // 06-12時の降水確率を色で点灯
lighting(rain1218); // 12-18時の降水確率を色で点灯
lighting(rain1824); // 18-24時の降水確率を色で点灯
Serial.println(); // 改行
}
void setup() {
M5.begin(true, false, true); //(LCD,PowerEnable=true,Serial)
delay(50); // 50mS待つ
Serial.begin(115200); // Upload Speed=15200にする
WiFi.begin(ssid, password); // Wi-Fi設定を初期化
Serial.println(""); // 改行
Serial.println("Wi-Fiに接続中です。"); // シリアルモニタに表示
while (WiFi.status() != WL_CONNECTED) { // 接続状態が接続完でない時
delay(500); // 0.5S待つ
Serial.print("."); // シリアルモニタに表示
Serial.print(WiFi.status()); // Wi-Fiの状態数表示
// 0:WL_IDLE_STATUS WiFi.begin()が呼び出され
// 下記3か4になるまでの一時的状態
// 1:WL_NO_SSID_AVAIL 使用可能なSSIDがない
// 2:WL_SCAN_COMPLETED スキャンネットワークが完了
// 3:WL_CONNECTED WiFiに接続が確立
// 4:WL_CONNECT_FAILED すべての試行で接続失敗
// 5:WL_CONNECTION_LOST 接続が失われた
// 6:WL_DISCONNECTED ネットワークから切断
// 255:WL_NO_SHIELD WiFiシールドが存在しない
} // 接続完の時
Serial.println(""); // シリアルモニタで改行
Serial.println("Wi-Fiに接続しました。"); // シリアルモニタに表示
Serial.print("IPアドレス:"); // シリアルモニタに表示
Serial.println(WiFi.localIP()); // WiFiのIPアドレスを表示
weatherInfo = getJson(); // 関数実行
WiFi.disconnect(true); // Wi-Fi機能のみがoff
}
void loop() {
String day0 = weatherInfo["pref"]["area"][region]["info"][0];
// 県 東部 領域 情報 今日
String day1 = weatherInfo["pref"]["area"][region]["info"][1]; // 明日
String day2 = weatherInfo["pref"]["area"][region]["info"][2]; // 明後日
M5.dis.drawpix(0, 0xFFFFFF); delay(100); // 白0.1秒点灯
M5.dis.drawpix(0, 0x000000); delay(200); // 黒0.2秒消灯
delay(700); // 0.7秒待つ
Serial.print("今日"); drawWeather(day0); // データ表示関数 今日
delay(500); // 0.7秒待つ
for (int i = 0; i <= 2; i++) { // 2回
M5.dis.drawpix(0, 0xFFFFFF); delay(100); // 白0.1秒点灯
M5.dis.drawpix(0, 0x000000); delay(200); // 黒0.2秒消灯
}
delay(700); // 0.7秒待つ
Serial.print("明日"); drawWeather(day1); // データ表示関数 明日
delay(500); // 0.5秒待つ
for (int i = 0; i <= 3; i++) { // 3回
M5.dis.drawpix(0, 0xFFFFFF); delay(100); // 0.1秒点灯
M5.dis.drawpix(0, 0x000000); delay(200); // 黒0.2秒消灯
}
delay(700); // 0.7秒待つ
Serial.print("明後日"); drawWeather(day2); // データ表示関数 明後日
delay(3000); // 3秒待つ
/*LED 色test
M5.dis.drawpix(0, 0x000000); // 黒
delay(2000);
M5.dis.drawpix(0, 0x100000); // 茶(暗い赤)800000では赤い
delay(2000);
M5.dis.drawpix(0, 0xFF0000); // 赤
delay(2000);
M5.dis.drawpix(0, 0xFF610F); // 橙EF810Fでは黄色っぽい
delay(2000);
M5.dis.drawpix(0, 0xFFFF00); // 黄
delay(2000);
M5.dis.drawpix(0, 0x008000); // 緑
delay(2000);
M5.dis.drawpix(0, 0x0000FF); // 青
delay(2000);
M5.dis.drawpix(0, 0x400080); // 紫800080では赤紫っぽい
delay(2000);
M5.dis.drawpix(0, 0x0F0F0F); // 灰(暗い白)808080では明るい
delay(2000);
M5.dis.drawpix(0, 0xFFFFFF); // 白
delay(2000);
*/
}
* フラッシュメモリ(1.3Mbyte)を、スケッチが65%使用。RAM(327kbyte)は、グローバル変数が12%使用、ローカル変数で286kbyte使用可能。(1000byte=1kbyteで計算)