Board logo

標題: LCD display library [打印本頁]

作者: C_Law    時間: 2021-2-18 18:11     標題: LCD display library

本帖最後由 C_Law 於 2021-2-18 18:13 編輯

這塊 Display 是朋友好耐之前淘返來不識用就放埋一邊,最近執屋搵返出來,他不要就送給我玩。

我想試下用 Arduino UNO 或 ESP8266 去玩,應該用什麼 Library?

背面幾粒 Chip 的字又細又矇,老花眼的我用埋放大鏡都睇不到。

Uploaded_via_HKEPC_IR_Pro_Android(9d4f0).jpg

Uploaded_via_HKEPC_IR_Pro_Android(91aa1).jpg

圖片附件: Uploaded_via_HKEPC_IR_Pro_Android(9d4f0).jpg (2021-2-18 18:12, 136.38 KB) / 下載次數 82
https://h0.hkepc.com/forum/attachment.php?aid=2249661&k=6025079730cc7e89613508d038e8452e&t=1781592527&sid=38c58EYhg6



圖片附件: Uploaded_via_HKEPC_IR_Pro_Android(91aa1).jpg (2021-2-18 18:12, 141.26 KB) / 下載次數 102
https://h0.hkepc.com/forum/attachment.php?aid=2249663&k=48956bd6583d07d18c3d42aff44094dc&t=1781592527&sid=38c58EYhg6


作者: hon829    時間: 2021-2-18 18:25

行UART通訊, 似無lib.
https://www.aliexpress.com/i/32891203005.html
作者: xiao    時間: 2021-2-18 18:38

http://www.sun-lcm.com/a/guanyuwomen/ziliaoxiazai/kafagongju/
作者: Charcoal99    時間: 2021-2-18 18:56

模塊資料在樓上連結, 按 「集成串口屏模块」, 選 JC024 下載.
作者: C_Law    時間: 2021-2-18 19:21

Thanks all~~~~

研究下先。
作者: C_Law    時間: 2021-5-23 16:54

本帖最後由 C_Law 於 2021-5-23 22:23 編輯

唔該各位師兄!!

[attach]2264657[/attach]
Ooops~~~~今日上不到圖

Uploaded_via_HKEPC_IR_Pro_Android(0091d).jpg


相隔好耐, 今日先到得閒拎出來玩, 搵塊 D1 mini 上網拎時間做個鐘玩下。再有時間玩就去埋天文台搵溫度,濕度之類。

via HKEPC IR Pro 3.6.1 - Android(3.3.1)

圖片附件: Uploaded_via_HKEPC_IR_Pro_Android(0091d).jpg (2021-5-23 22:20, 144.09 KB) / 下載次數 89
https://h0.hkepc.com/forum/attachment.php?aid=2264727&k=a46655a3232087122584da5f4caec870&t=1781592527&sid=38c58EYhg6


作者: xiao    時間: 2021-5-25 22:29

這厲害 請問哪裡買 多少銀兩
作者: C_Law    時間: 2021-5-26 05:40

這厲害 請問哪裡買 多少銀兩
xiao 發表於 2021/5/25 22:29


這塊 LCD 係朋友給我,我都不知本來從哪裡買。不過上淘佬用 JC024 QVGA 做 Keywords 搵下,似係這個:
标准JC024串口屏集成字库图片功能UART指令驱动 HMI人机交互
https://item.taobao.com/item.htm?id=605375019156
https://detail.tmall.com/item.htm?id=620656642888

價錢好飄忽,同樣係塊 Display + 4 pin 線,一間賣 30 人仔,一間要 60!以上兩間都要另加大陸段運費。
作者: xiao    時間: 2021-5-26 07:59

這塊 LCD 係朋友給我,我都不知本來從哪裡買。不過上淘佬用 JC024 QVGA 做 Keywords 搵下,似係這個:
标 ...
C_Law 發表於 2021-5-26 05:40



    謝謝你的資訊 看來不值這價位
作者: C_Law    時間: 2021-6-5 17:30

本帖最後由 C_Law 於 2021-6-5 17:42 編輯

20210605a.jpg
今日得閒繼續玩,上天文台搵埋濕度/溫度放入個 Display。本來還想搵埋酷熱/寒冷/火災/暴雨/風球之類的警告,但今日什麼警告都無,無得睇個 json 檔的真正內容,只能憑天文台的說明檔去估。

暫時打算平時濕度/溫度用綠色字,有黃/紅火災警告時將濕度改用黃/紅色字,有酷熱/寒冷警告就將溫度改用紅/藍色字。目前濕度值左邊還有位剩,打算預留作風球、黑/紅/黃雨。

另外,之前玩開 irplusLAN(一個本來用來經 WiFi/BT 發射紅外線遙控訊號的 Android App),順手將以前做 IR 發射器的 Code 改一改加埋入個鐘,目前可以用手機經  irplusLAN 以 WiFi 控制個鐘改顏色、背光的光暗、手動即時上網更新時間/天氣。

分區溫度及天文台濕度:(後面的 &lang=xx,xx 可改為 en/tc/sc=英/繁/簡)
https://data.weather.gov.hk/weatherAPI/opendata/weather.php?dataType=rhrread&lang=en
天氣警告:
https://data.weather.gov.hk/weatherAPI/opendata/weather.php?dataType=warnsum&lang=tc

英文使用說明:
https://data.weather.gov.hk/weatherAPI/doc/HKO_Open_Data_API_Documentation.pdf
繁中使用說明:
https://data.weather.gov.hk/weatherAPI/doc/HKO_Open_Data_API_Documentation_tc.pdf

圖片附件: 20210605a.jpg (2021-6-5 16:59, 149.76 KB) / 下載次數 89
https://h0.hkepc.com/forum/attachment.php?aid=2266689&k=bac5f2dc88a34644ad3cd225392eaca6&t=1781592527&sid=38c58EYhg6


作者: royc    時間: 2021-6-10 11:10

今日得閒繼續玩,上天文台搵埋濕度/溫度放入個 Display。本來還想搵埋酷熱/寒冷/火災/暴雨/風球之類的警告 ...
C_Law 發表於 2021-6-5 17:30

師兄請教一下,小弟正想試下整個香港地區溫度,用你上面個天文台api。
請問有冇參考連結例程可以用到香港地區data,改小小就用得。我用D1mini的

謝謝

via HKEPC IR Pro 3.6.1 - iOS(3.0.0)
作者: C_Law    時間: 2021-6-13 01:57

本帖最後由 C_Law 於 2021-6-13 02:35 編輯
師兄請教一下,小弟正想試下整個香港地區溫度,用你上面個天文台api。
請問有冇參考連結例程可以用到香港 ...
royc 發表於 2021/6/10 11:10


以下係我玩緊個鐘的部份 Code,可以用 rhrread 搵到:
閃電
分區氣溫
天文台濕度

以及用 warnsum 搵到
風球
紅黑黃雨
雷暴警告
寒冷/酷熱警告
紅/黃火災警告

上載到 ESP8266 前要先修改 PortNo, WiFi 的 SSID/PASSWORD。
Oooops~~~~這裡貼 Code 自動幫我刪除了一部份斜楝!照抄以下出來用係會錯,等我諗諗再 Post 過。
(好似改返正)
  1. #ifndef UNIT_TEST
  2. #include <Arduino.h>
  3. #endif
  4. #include <ESP8266WiFi.h>
  5. #include <ESP8266WiFiMulti.h>
  6. #include <ESP8266WebServer.h>
  7. #include <ESP8266mDNS.h>
  8. #include <WiFiClient.h>
  9. #include <ESP8266HTTPClient.h>

  10. // some parameters used for WiFi
  11. const unsigned int PortNo = 80;
  12. const char* SSID1 = "yourSSID1";               // SSID and Password for WiFi connection
  13. const char* PW1 = "yourPASSWORD1";
  14. const char* SSID2 = "yourSSID2";
  15. const char* PW2 = "yourPASSWORD2";
  16. const char* SSID3 = "yourSSID3";
  17. const char* PW3 = "yourPASSWORD3";

  18. const uint16_t LED = 2;       // OnChipLED(Pull_Up)=D4 for D1 mini
  19. const bool LEDon = false;     // false for Pull_Up, otherwise true

  20. // some variables for weather
  21. String weatherJSON;
  22. String TempC;
  23. String MaxMinTempC;
  24. String HumPercent;
  25. String WTCSGNL;  // Tropical Cyclone Warning Signal: None, TC1, TC3, TC8xx, TC9, TC10
  26. bool Lightning;
  27. bool WTS = false; //Thunderstorm warning
  28. int wFire;  // Fire warning: 0,1,2=Normal, Yellow, Red
  29. int wCH;    // Cold/Hot warning: 0,1,2,=Normal,Cold,Hot
  30. int wRAIN;  // Rain warning: 0,1,2,3=None,Amber,Red,Black

  31. ESP8266WiFiMulti wifiMulti;
  32. ESP8266WebServer server(PortNo);

  33. void setup() {
  34.   pinMode(LED, OUTPUT);
  35.   digitalWrite(LED, LEDon);
  36.   
  37.   Serial.begin(115200);
  38.   Serial.println("");
  39.   
  40.   WiFi.mode(WIFI_STA);
  41.   wifiMulti.addAP(SSID1, PW1);
  42.   wifiMulti.addAP(SSID2, PW2);
  43.   wifiMulti.addAP(SSID3, PW3);
  44.   
  45.   // waiting for WiFi connection
  46.   while (wifiMulti.run() != WL_CONNECTED) {
  47.     delay(500);
  48.   }
  49.   
  50.   Serial.println("");
  51.   Serial.print("Connected to: ");
  52.   Serial.println(WiFi.SSID());
  53.   Serial.print("IP address: ");
  54.   Serial.println(WiFi.localIP().toString());
  55.   Serial.print("Port no.: ");
  56.   Serial.println(PortNo);
  57.   digitalWrite(LED, !LEDon);
  58.   
  59.   server.on("/", handleRoot);
  60.   server.on("/rhrread", handleRhrread);
  61.   server.on("/warnsum", handleWarnSum);
  62.   server.on("/rhrread2", handleRhrread2);
  63.   server.on("/warnsum2", handleWarnSum2);
  64.   server.onNotFound(handleNotFound);
  65.   server.begin();
  66. }

  67. void loop() {
  68.   server.handleClient();
  69. }

  70. void handleRoot() {
  71.   String message = "";
  72.   message = "<HTML>\n" \
  73.             "  <HEAD>\n" \
  74.             "    <TITLE>Get weather information by ESP8266</TITLE>\n" \
  75.             "  </HEAD>\n" \
  76.             "  <body>\n" \
  77.             "    Get weather information by ESP8266<p>\n";
  78.   message += "  </body>\n" \
  79.              "</HTLM>";
  80.   server.send(200, "text/html", message);
  81. }

  82. void handleRhrread() {
  83.   String message = "";
  84.   if (GetJson("rhrread")){
  85.     int StartPos = 0;
  86.     int EndPos = weatherJSON.length() - 1;
  87.     int ResultStart = 0;
  88.     int ResultEnd = EndPos;
  89.     String sTemp;
  90.     String Location;
  91.     message = weatherJSON;
  92.         
  93.     // Get Lightning warning for "Hong Kong and Kowloon"
  94.     Location = "Hong Kong and Kowloon";
  95.     StartPos = 0;
  96.     EndPos = weatherJSON.length() - 1;
  97.     ResultStart = StartPos;
  98.     ResultEnd = EndPos;
  99.     Lightning = false;
  100.     if (GetJsonRange("\"lightning\":{", "]", StartPos, EndPos, &ResultStart, &ResultEnd)){
  101.       StartPos = ResultStart;
  102.       EndPos = ResultEnd;
  103.       if (GetJsonRange("\"" + Location + "\",\"occur\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  104.         Lightning = (weatherJSON.substring(ResultStart, ResultEnd) == "true");
  105.       }
  106.     }
  107.     message += "\n\rLightning=";
  108.     if (Lightning) message += "true";
  109.     else message += "false";
  110.    
  111.     // Get "Kowloon City" temperture
  112.     Location = "Kowloon City";
  113.     StartPos = 0;
  114.     EndPos = weatherJSON.length() - 1;
  115.     TempC = "";
  116.     if (GetJsonRange("\"temperature\":{\"data\":[", "]", StartPos, EndPos, &ResultStart, &ResultEnd)){
  117.       StartPos = ResultStart;
  118.       EndPos = ResultEnd;
  119.       if (GetJsonRange("\"" + Location + "\",\"value\":", ",", StartPos, EndPos, &ResultStart, &ResultEnd)){
  120.         TempC = weatherJSON.substring(ResultStart, ResultEnd) + "C";
  121.       }
  122.     }
  123.     message += "\n\rTempC=" + TempC;
  124.    
  125.     // Get Humidity
  126.     StartPos = 0;
  127.     EndPos = weatherJSON.length() - 1;
  128.     ResultStart = StartPos;
  129.     ResultEnd = EndPos;
  130.     if (GetJsonRange("\"humidity\":{", "]", StartPos, EndPos, &ResultStart, &ResultEnd)){
  131.       StartPos = ResultStart;
  132.       EndPos = ResultEnd;
  133.       if (GetJsonRange("\"value\":", ",", StartPos, EndPos, &ResultStart, &ResultEnd)){
  134.         HumPercent = weatherJSON.substring(ResultStart, ResultEnd) + "%";
  135.       }
  136.     }
  137.     message += "\n\rHumidity=" +HumPercent;
  138.   }
  139.   
  140.   server.send(200, "text/plain", message);
  141. }

  142. void handleRhrread2() {
  143.   String message = "";
  144.   if (true){
  145.     weatherJSON = "{\"lightning\":{\"data\":[{\"place\":\"Lantau\",\"occur\":\"true\"},{\"place\":\"Hong Kong and Kowloon\",\"occur\":\"true\"}],\"startTime\":\"2021-06-11T18:45:00+08:00\",\"endTime\":\"2021-06-11T19:45:00+08:00\"},\"rainfall\":{\"data\":[{\"unit\":\"mm\",\"place\":\"Central &amp; Western District\",\"max\":9,\"min\":1,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Eastern District\",\"max\":8,\"min\":1,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Kwai Tsing\",\"max\":2,\"min\":0,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Islands District\",\"max\":12,\"min\":0,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"North District\",\"max\":0,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Sai Kung\",\"max\":0,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Sha Tin\",\"max\":1,\"min\":0,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Southern District\",\"max\":15,\"min\":7,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Tai Po\",\"max\":1,\"min\":0,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Tsuen Wan\",\"max\":2,\"min\":0,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Tuen Mun\",\"max\":3,\"min\":0,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Wan Chai\",\"max\":10,\"min\":5,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Yuen Long\",\"max\":2,\"min\":0,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Yau Tsim Mong\",\"max\":4,\"min\":0,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Sham Shui Po\",\"max\":2,\"min\":1,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Kowloon City\",\"max\":1,\"min\":0,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Wong Tai Sin\",\"max\":0,\"main\":\"FALSE\"},{\"unit\":\"mm\",\"place\":\"Kwun Tong\",\"max\":1,\"min\":0,\"main\":\"FALSE\"}],\"startTime\":\"2021-06-11T18:45:00+08:00\",\"endTime\":\"2021-06-11T19:45:00+08:00\"},\"icon\":[64],\"iconUpdateTime\":\"2021-06-11T20:25:00+08:00\",\"uvindex\":\"\",\"updateTime\":\"2021-06-11T20:26:00+08:00\",\"temperature\":{\"data\":[{\"place\":\"King's Park\",\"value\":27,\"unit\":\"C\"},{\"place\":\"Hong Kong Observatory\",\"value\":28,\"unit\":\"C\"},{\"place\":\"Wong Chuk Hang\",\"value\":28,\"unit\":\"C\"},{\"place\":\"Ta Kwu Ling\",\"value\":29,\"unit\":\"C\"},{\"place\":\"Lau Fau Shan\",\"value\":28,\"unit\":\"C\"},{\"place\":\"Tai Po\",\"value\":29,\"unit\":\"C\"},{\"place\":\"Sha Tin\",\"value\":29,\"unit\":\"C\"},{\"place\":\"Tuen Mun\",\"value\":27,\"unit\":\"C\"},{\"place\":\"Tseung Kwan O\",\"value\":27,\"unit\":\"C\"},{\"place\":\"Sai Kung\",\"value\":29,\"unit\":\"C\"},{\"place\":\"Cheung Chau\",\"value\":26,\"unit\":\"C\"},{\"place\":\"Chek Lap Kok\",\"value\":27,\"unit\":\"C\"},{\"place\":\"Tsing Yi\",\"value\":29,\"unit\":\"C\"},{\"place\":\"Shek Kong\",\"value\":28,\"unit\":\"C\"},{\"place\":\"Tsuen Wan Ho Koon\",\"value\":26,\"unit\":\"C\"},{\"place\":\"Tsuen Wan Shing Mun Valley\",\"value\":28,\"unit\":\"C\"},{\"place\":\"Hong Kong Park\",\"value\":27,\"unit\":\"C\"},{\"place\":\"Shau Kei Wan\",\"value\":27,\"unit\":\"C\"},{\"place\":\"Kowloon City\",\"value\":28,\"unit\":\"C\"},{\"place\":\"Happy Valley\",\"value\":28,\"unit\":\"C\"},{\"place\":\"Wong Tai Sin\",\"value\":28,\"unit\":\"C\"},{\"place\":\"Stanley\",\"value\":27,\"unit\":\"C\"},{\"place\":\"Kwun Tong\",\"value\":27,\"unit\":\"C\"},{\"place\":\"Sham Shui Po\",\"value\":28,\"unit\":\"C\"},{\"place\":\"Kai Tak Runway Park\",\"value\":28,\"unit\":\"C\"},{\"place\":\"Yuen Long Park\",\"value\":29,\"unit\":\"C\"},{\"place\":\"Tai Mei Tuk\",\"value\":29,\"unit\":\"C\"}],\"recordTime\":\"2021-06-11T20:00:00+08:00\"},\"warningMessage\":[\"The Tropical Cyclone Signal No. 1 has been issued.\",\"The Amber Rainstorm Warning Signal was issued at 8:25 p.m.\",\"The Thunderstorm Warning has been issued. It will remain effective until 11:00 p.m. today. Occasional thunderstorms are expected to occur over Hong Kong.\"],\"mintempFrom00To09\":\"\",\"rainfallFrom00To12\":\"\",\"rainfallLastMonth\":\"\",\"rainfallJanuaryToLastMonth\":\"\",\"tcmessage\":[\"Here is the information on Tropical Depression:\nLocation: 18.3 degrees north, 112.3 degrees east; Maximum sustained wind near its centre: 45 km\/h.\"],\"humidity\":{\"recordTime\":\"2021-06-11T20:00:00+08:00\",\"data\":[{\"unit\":\"percent\",\"value\":88,\"place\":\"Hong Kong Observatory\"}]}}";
  146.     int StartPos = 0;
  147.     int EndPos = weatherJSON.length() - 1;
  148.     int ResultStart = 0;
  149.     int ResultEnd = EndPos;
  150.     String sTemp;
  151.     String Location;
  152.     message = weatherJSON;
  153.         
  154.     // Get Lightning warning for "Hong Kong and Kowloon"
  155.     Location = "Hong Kong and Kowloon";
  156.     StartPos = 0;
  157.     EndPos = weatherJSON.length() - 1;
  158.     ResultStart = StartPos;
  159.     ResultEnd = EndPos;
  160.     Lightning = false;
  161.     if (GetJsonRange("\"lightning\":{", "]", StartPos, EndPos, &ResultStart, &ResultEnd)){
  162.       StartPos = ResultStart;
  163.       EndPos = ResultEnd;
  164.       if (GetJsonRange("\"" + Location + "\",\"occur\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  165.         Lightning = (weatherJSON.substring(ResultStart, ResultEnd) == "true");
  166.       }
  167.     }
  168.     message += "\n\rLightning=";
  169.     if (Lightning) message += "true";
  170.     else message += "false";
  171.    
  172.     // Get "Kowloon City" temperture
  173.     Location = "Kowloon City";
  174.     StartPos = 0;
  175.     EndPos = weatherJSON.length() - 1;
  176.     TempC = "";
  177.     if (GetJsonRange("\"temperature\":{\"data\":[", "]", StartPos, EndPos, &ResultStart, &ResultEnd)){
  178.       StartPos = ResultStart;
  179.       EndPos = ResultEnd;
  180.       if (GetJsonRange("\"" + Location + "\",\"value\":", ",", StartPos, EndPos, &ResultStart, &ResultEnd)){
  181.         TempC = weatherJSON.substring(ResultStart, ResultEnd) + "C";
  182.       }
  183.     }
  184.     message += "\n\rTempC=" + TempC;
  185.    
  186.     // Get Humidity
  187.     StartPos = 0;
  188.     EndPos = weatherJSON.length() - 1;
  189.     ResultStart = StartPos;
  190.     ResultEnd = EndPos;
  191.     if (GetJsonRange("\"humidity\":{", "]", StartPos, EndPos, &ResultStart, &ResultEnd)){
  192.       StartPos = ResultStart;
  193.       EndPos = ResultEnd;
  194.       if (GetJsonRange("\"value\":", ",", StartPos, EndPos, &ResultStart, &ResultEnd)){
  195.         HumPercent = weatherJSON.substring(ResultStart, ResultEnd) + "%";
  196.       }
  197.     }
  198.     message += "\n\rHumidity=" +HumPercent;
  199.   }
  200.   
  201.   server.send(200, "text/plain", message);
  202. }

  203. void handleWarnSum() {
  204.   String message ="";
  205.   if (GetJson("warnsum")) {
  206.     int StartPos = 0;
  207.     int EndPos = weatherJSON.length() - 1;
  208.     int ResultStart = 0;
  209.     int ResultEnd = EndPos;
  210.     String sTemp;
  211.    
  212.     // Check WRAIN
  213.     wRAIN = 0;
  214.     if (GetJsonRange("\"WRAIN\":{", "}", StartPos, EndPos, &ResultStart, &ResultEnd)){
  215.       StartPos = ResultStart;
  216.       EndPos = ResultEnd;
  217.       if (GetJsonRange("\"actionCode\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  218.         sTemp = weatherJSON.substring(ResultStart, ResultEnd);
  219.         if ((sTemp != "CANCEL") && (GetJsonRange("\"code\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd))){
  220.           sTemp = weatherJSON.substring(ResultStart, ResultEnd);
  221.           if (sTemp == "WRAINA") wRAIN = 1;
  222.           else if (sTemp == "WRAINR") wRAIN = 2;
  223.           else if (sTemp == "WRAINB") wRAIN = 3;
  224.         }
  225.       }
  226.     }
  227.     message = "\n\r\n\rwRAIN=";
  228.     message += wRAIN;
  229.    
  230.     // Check Thunderstorm warning WTS
  231.     StartPos = 0;
  232.     EndPos = weatherJSON.length() - 1;
  233.     WTS = false;
  234.     if (GetJsonRange("\"WTS\":{", "}", StartPos, EndPos, &ResultStart, &ResultEnd)){
  235.       StartPos = ResultStart;
  236.       EndPos = ResultEnd;
  237.       
  238.       if (GetJsonRange("\"actionCode\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  239.         sTemp = weatherJSON.substring(ResultStart, ResultEnd);
  240.         if (sTemp != "CANCEL") WTS = true;
  241.       }
  242.     }
  243.     message += "\n\rWTS=";
  244.     if (WTS) message += "true";
  245.     else message += "false";
  246.    
  247.     // Check Tropical Cyclone Warning Signal WTCSGNL
  248.     StartPos = 0;
  249.     EndPos = weatherJSON.length() - 1;
  250.     WTCSGNL = "None";
  251.     if (GetJsonRange("\"WTCSGNL\":{\"", "}", StartPos, EndPos, &ResultStart, &ResultEnd)){
  252.       StartPos = ResultStart;
  253.       EndPos = ResultEnd;
  254.       if (GetJsonRange("\"actionCode\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  255.         if (weatherJSON.substring(ResultStart, ResultEnd) != "CANCEL") {
  256.           if (GetJsonRange("\"code\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  257.             WTCSGNL = weatherJSON.substring(ResultStart, ResultEnd);
  258.           }
  259.         }
  260.       }
  261.     }
  262.     message += "\n\rWTCSGNL=" + WTCSGNL;
  263.    
  264.     // Check WHOT
  265.     wCH = 0;
  266.     StartPos = 0;
  267.     EndPos = weatherJSON.length() - 1;
  268.     if (GetJsonRange("\"WHOT\":{\"", "}", StartPos, EndPos, &ResultStart, &ResultEnd)){
  269.       StartPos = ResultStart;
  270.       EndPos = ResultEnd;
  271.       if (GetJsonRange("\"actionCode\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  272.         if (weatherJSON.substring(ResultStart, ResultEnd) != "CANCEL") wCH = 2;
  273.       }
  274.     }
  275.    
  276.     // Check WCOLD
  277.     StartPos = 0;
  278.     EndPos = weatherJSON.length() - 1;
  279.     // wCH already reset before WHOT check, no need to reset in here
  280.     if (GetJsonRange("\"COLD\":{\"", "}", StartPos, EndPos, &ResultStart, &ResultEnd)){
  281.       StartPos = ResultStart;
  282.       EndPos = ResultEnd;
  283.       if (GetJsonRange("\"actionCode\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  284.         if (weatherJSON.substring(ResultStart, ResultEnd) != "CANCEL") wCH = 1;
  285.       }
  286.     }
  287.     message += "\n\rwCH=";
  288.     message += wCH;
  289.    
  290.     // Get WFIRE
  291.     StartPos = 0;
  292.     EndPos = weatherJSON.length() - 1;
  293.     wFire = 0;
  294.     if (GetJsonRange("\"WFIRE\":{\"", "}", StartPos, EndPos, &ResultStart, &ResultEnd)){
  295.       StartPos = ResultStart;
  296.       EndPos = ResultEnd;
  297.       if (GetJsonRange("\"actionCode\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  298.         if (weatherJSON.substring(ResultStart, ResultEnd) != "CANCEL") {
  299.           if (GetJsonRange("\"code\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  300.             sTemp = weatherJSON.substring(ResultStart, ResultEnd);
  301.             if (sTemp == "WFIREY") wFire = 1;      // yellow
  302.             else if (sTemp == "WFIRER") wFire = 2; // red
  303.           }
  304.         }
  305.       }
  306.     }
  307.     message += "\n\rwFire=";
  308.     message += wFire;
  309.   }
  310.   
  311.   message = weatherJSON + message;
  312.   server.send(200, "text/plain", message);
  313. }

  314. void handleWarnSum2() {
  315.   String message ="";
  316.   if (true) {
  317.     weatherJSON = "{\"WRAIN\":{\"name\":\"Rainstorm Warning Signal\",\"code\":\"WRAINA\",\"type\":\"Amber\",\"actionCode\":\"ISSUE\",\"issueTime\":\"2021-06-11T20:25:00+08:00\",\"updateTime\":\"2021-06-11T20:25:00+08:00\"},\"WTS\":{\"name\":\"Thunderstorm Warning\",\"code\":\"WTS\",\"actionCode\":\"UPDATE\",\"issueTime\":\"2021-06-11T18:35:00+08:00\",\"expireTime\":\"2021-06-11T23:00:00+08:00\",\"updateTime\":\"2021-06-11T21:10:00+08:00\"},\"WTCSGNL\":{\"name\":\"Tropical Cyclone Warning Signal\",\"code\":\"TC1\",\"actionCode\":\"ISSUE\",\"type\":\"Standby Signal No. 1\",\"issueTime\":\"2021-06-11T16:15:00+08:00\",\"updateTime\":\"2021-06-11T16:15:00+08:00\"}}";
  318.     int StartPos = 0;
  319.     int EndPos = weatherJSON.length() - 1;
  320.     int ResultStart = 0;
  321.     int ResultEnd = EndPos;
  322.     String sTemp;
  323.    
  324.     // Check WRAIN
  325.     wRAIN = 0;
  326.     if (GetJsonRange("\"WRAIN\":{", "}", StartPos, EndPos, &ResultStart, &ResultEnd)){
  327.       StartPos = ResultStart;
  328.       EndPos = ResultEnd;
  329.       if (GetJsonRange("\"actionCode\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  330.         sTemp = weatherJSON.substring(ResultStart, ResultEnd);
  331.         if ((sTemp != "CANCEL") && (GetJsonRange("\"code\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd))){
  332.           sTemp = weatherJSON.substring(ResultStart, ResultEnd);
  333.           if (sTemp == "WRAINA") wRAIN = 1;
  334.           else if (sTemp == "WRAINR") wRAIN = 2;
  335.           else if (sTemp == "WRAINB") wRAIN = 3;
  336.         }
  337.       }
  338.     }
  339.     message = "\n\r\n\rwRAIN=";
  340.     message += wRAIN;
  341.    
  342.     // Check Thunderstorm warning WTS
  343.     StartPos = 0;
  344.     EndPos = weatherJSON.length() - 1;
  345.     WTS = false;
  346.     if (GetJsonRange("\"WTS\":{", "}", StartPos, EndPos, &ResultStart, &ResultEnd)){
  347.       StartPos = ResultStart;
  348.       EndPos = ResultEnd;
  349.       
  350.       if (GetJsonRange("\"actionCode\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  351.         sTemp = weatherJSON.substring(ResultStart, ResultEnd);
  352.         if (sTemp != "CANCEL") WTS = true;
  353.       }
  354.     }
  355.     message += "\n\rWTS=";
  356.     if (WTS) message += "true";
  357.     else message += "false";
  358.    
  359.     // Check Tropical Cyclone Warning Signal WTCSGNL
  360.     StartPos = 0;
  361.     EndPos = weatherJSON.length() - 1;
  362.     WTCSGNL = "None";
  363.     if (GetJsonRange("\"WTCSGNL\":{\"", "}", StartPos, EndPos, &ResultStart, &ResultEnd)){
  364.       StartPos = ResultStart;
  365.       EndPos = ResultEnd;
  366.       if (GetJsonRange("\"actionCode\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  367.         if (weatherJSON.substring(ResultStart, ResultEnd) != "CANCEL") {
  368.           if (GetJsonRange("\"code\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  369.             WTCSGNL = weatherJSON.substring(ResultStart, ResultEnd);
  370.           }
  371.         }
  372.       }
  373.     }
  374.     message += "\n\rWTCSGNL=" + WTCSGNL;
  375.    
  376.     // Check WHOT
  377.     wCH = 0;
  378.     StartPos = 0;
  379.     EndPos = weatherJSON.length() - 1;
  380.     if (GetJsonRange("\"WHOT\":{\"", "}", StartPos, EndPos, &ResultStart, &ResultEnd)){
  381.       StartPos = ResultStart;
  382.       EndPos = ResultEnd;
  383.       if (GetJsonRange("\"actionCode\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  384.         if (weatherJSON.substring(ResultStart, ResultEnd) != "CANCEL") wCH = 2;
  385.       }
  386.     }
  387.    
  388.     // Check WCOLD
  389.     StartPos = 0;
  390.     EndPos = weatherJSON.length() - 1;
  391.     // wCH already reset before WHOT check, no need to reset in here
  392.     if (GetJsonRange("\"COLD\":{\"", "}", StartPos, EndPos, &ResultStart, &ResultEnd)){
  393.       StartPos = ResultStart;
  394.       EndPos = ResultEnd;
  395.       if (GetJsonRange("\"actionCode\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  396.         if (weatherJSON.substring(ResultStart, ResultEnd) != "CANCEL") wCH = 1;
  397.       }
  398.     }
  399.     message += "\n\rwCH=";
  400.     message += wCH;
  401.    
  402.     // Get WFIRE
  403.     StartPos = 0;
  404.     EndPos = weatherJSON.length() - 1;
  405.     wFire = 0;
  406.     if (GetJsonRange("\"WFIRE\":{\"", "}", StartPos, EndPos, &ResultStart, &ResultEnd)){
  407.       StartPos = ResultStart;
  408.       EndPos = ResultEnd;
  409.       if (GetJsonRange("\"actionCode\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  410.         if (weatherJSON.substring(ResultStart, ResultEnd) != "CANCEL") {
  411.           if (GetJsonRange("\"code\":\"", "\"", StartPos, EndPos, &ResultStart, &ResultEnd)){
  412.             sTemp = weatherJSON.substring(ResultStart, ResultEnd);
  413.             if (sTemp == "WFIREY") wFire = 1;      // yellow
  414.             else if (sTemp == "WFIRER") wFire = 2; // red
  415.           }
  416.         }
  417.       }
  418.     }
  419.     message += "\n\rwFire=";
  420.     message += wFire;
  421.   }
  422.   
  423.   message = weatherJSON + message;
  424.   server.send(200, "text/plain", message);
  425. }

  426. void handleNotFound() {
  427.   String message = "File Not Found\n\n";
  428.   message += "URI: ";
  429.   message += server.uri();
  430.   message += "\nMethod: ";
  431.   message += (server.method() == HTTP_GET)?"GET":"POST";
  432.   message += "\nArguments: ";
  433.   message += server.args();
  434.   message += "\n";
  435.   for (uint8_t i = 0; i < server.args(); i++)
  436.     message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
  437.   server.send(404, "text/plain", message);
  438. }

  439. bool GetJson(String dataType){
  440.   /*
  441.     dataType can be: rhrread, warnsum, fnd...etc
  442.   */
  443.   bool Result = false;
  444.   HTTPClient http;
  445.   WiFiClientSecure client;
  446.   client.setInsecure(); // use with caution
  447.   weatherJSON = "";     // clear previous JSON
  448.   
  449.   http.begin(client, "https://data.weather.gov.hk/weatherAPI/opendata/weather.php?dataType=" + dataType + "&lang=en");
  450.   if (http.GET() == HTTP_CODE_OK) {
  451.     weatherJSON = http.getString();
  452.     Result = true;
  453.   }
  454.   return Result;
  455. }

  456. bool GetJsonRange(String StartString, String EndString, int StartPos, int EndPos, int *SectionStart, int *SectionEnd) {
  457.   bool Good = true;
  458.   int ResultStart = StartPos;
  459.   int ResultEnd = EndPos;
  460.   String message = "";
  461.   // initial check
  462.   if ((StartString == "") || (EndString =="")) Good = false;
  463.   if (!Good || (StartPos < 0) || (StartPos > weatherJSON.length() - 1)) Good = false;
  464.   if (!Good || (EndPos <= StartPos) || (EndPos > weatherJSON.length() -1)) Good = false;
  465.   
  466.   if (Good) {
  467.     ResultStart = weatherJSON.indexOf(StartString, StartPos);
  468.     if (ResultStart < 0) Good =false;
  469.     else {
  470.       ResultStart += StartString.length();
  471.       if (ResultStart > EndPos) Good =false;
  472.       else {
  473.         ResultEnd = weatherJSON.indexOf(EndString, ResultStart);
  474.         if (ResultEnd > EndPos) Good = false;
  475.       }
  476.     }
  477.   }
  478.   if (Good) {
  479.     *SectionStart = ResultStart;
  480.     *SectionEnd = ResultEnd;
  481.   }
  482.   return Good;
  483. }
複製代碼
.

好似寫了好多行,實際有百幾行係重複 ,handleRhrread 和 handleWarnsum 以及 handleRhrread2 和 handleWarnsum2 基本上係一樣,分別只係前者會即時上天文台下載資料,而後者是我用來做測試,用了昨晚又一號風球、又黃雨、又雷暴……etc 的時候下載資料。

上載及連到 WiFi 後(LED 會熄),可以用以用 Web browser 經以下網址讀取資料:
http://ip-address:PortNo/xxxx

ip-address 係 Router 派給 ESP8266 的 ip
PortNo 係程式開頭由你自定的 Port number
xxxx 可以係 rhrread 或 warnsum。(以及 rhrread2 或 warnsum2)

主要係經 GetJson() 去下載天文台的 JSON 檔。

至於由 JSON 搵出想要的資料,應該係有 Library 去解讀內容,但我懶得睇 Library 的說明,寧願自己寫,我用 GetJsonRange() 去搵我想要的數值。

例如搵九龍城氣溫,氣溫必定係以下一段之內:
"temperature":{"data":[{...},{...},...{九龍城資料},...{...}]}
我先用 GetJsonRange() 去搵 "temperature":{"data":[ 以及 ] 的位置(ResultStart, ResultEnd)。

然後係上次搵到的範圍內再搵九龍城資料,這資料會類似係:
{"place":"Kowloon City","value":28,"unit":"C"}
而溫度就夾係 "place":"Kowloon City","value": 同後面的逗號之間,可以再用 GetJsonRange() 去搵這兩個位置,最後就可以用substring 從 weatherJSON 之中抽出溫度數值(String)。

不過有些資料,例如暴雨警告,除了搵 WRAIN 同個 code 之外,還是睇埋 actionCode 是否 CANCEL。
作者: marlin12    時間: 2021-6-13 12:22

本帖最後由 marlin12 於 2021-6-13 15:38 編輯

有時間的話,可以試用ArduinoJson v6。
這個程式庫是雙向的,可以把陣列(array)轉為JSON,或者JSON轉為陣列。

ArduinoJson

Deserialize with ArduinoJson (JSON轉array)

還有ArduinoJson Assistant,教埋你點用。
只需要揀啱Processor(ESP8266)、Mode(Deserialize)、Input Type(String),然後放你個JSON字串入去,相關的程式便會自動產生出來。
作者: C_Law    時間: 2021-6-13 16:16

有時間的話,可以試用ArduinoJson v6。
這個程式庫是雙向的,可以把陣列(array)轉為JSON,或者JSON轉為陣列 ...
marlin12 發表於 2021/6/13 12:22


Thx~~~

其實我都有裝 ArduinoJson,不過無心機睇 Tutorial,我見天文台幾個 JSON 的結構不是太複雜,就嘗試寫 GetJsonRange() 玩下先。
作者: royc    時間: 2021-6-13 21:23

多謝各位師兄資料,都要時間消代一下。
Thanks

via HKEPC IR Pro 3.6.1 - iOS(3.0.0)
作者: xiao    時間: 2021-6-16 09:16

厲害, 結果看似簡單, 原來寫碼要這麼長
作者: C_Law    時間: 2021-6-18 21:33

厲害, 結果看似簡單, 原來寫碼要這麼長
xiao 發表於 2021/6/16 09:16


其實我無學過 C++,亂寫一通 ,識寫應該可以寫得簡潔好多!

大致上完成我心目中想做的事。係差在不知怎去整黑雨警告,事關不想睇電視時被個鐘的光度吸引了視線,所以個鐘用黑色做底色,但黑底加個黑色雨字就即係無字!不想雨字改其他顏色,唯有係個雨字加底色,但試了好組合,還未試到個效果好的底色可以配到黃/紅黑。暫時用個「雨」字頂檔,遲下得閒會畫公仔。
LCD_Clock20210618a.jpg

ps.個 LCD 內置字庫同畫圖指令,話就話有 64 色可揀,但好多色重複,實際可用顏色其實好小。

圖片附件: LCD_Clock20210618a.jpg (2021-6-18 21:33, 148.59 KB) / 下載次數 87
https://h0.hkepc.com/forum/attachment.php?aid=2268755&k=54a980f010b8366ebcce72fe6b285755&t=1781592527&sid=38c58EYhg6






歡迎光臨 電腦領域 HKEPC Hardware (https://h0.hkepc.com/forum/) Powered by Discuz! 7.2