在這個(gè)項(xiàng)目中,我們將使用物聯(lián)網(wǎng)構(gòu)建一個(gè)智能農(nóng)業(yè)系統(tǒng)。該項(xiàng)目的目的是幫助農(nóng)民獲取實(shí)時(shí)數(shù)據(jù)(溫度、濕度、土壤水分、土壤溫度),以進(jìn)行有效的環(huán)境監(jiān)測(cè),從而使他們能夠提高產(chǎn)品的整體產(chǎn)量和質(zhì)量。這種使用由 NodeMCU 驅(qū)動(dòng)的物聯(lián)網(wǎng)系統(tǒng)的智能農(nóng)業(yè)由 DHT11 傳感器、濕度傳感器、DS18B20 傳感器探頭、LDR、水泵和 12V LED 燈條組成。當(dāng)基于物聯(lián)網(wǎng)的農(nóng)業(yè)監(jiān)測(cè)系統(tǒng)啟動(dòng)時(shí),它會(huì)檢查土壤濕度、溫度、濕度和土壤溫度。然后它將這些數(shù)據(jù)發(fā)送到物聯(lián)網(wǎng)云進(jìn)行實(shí)時(shí)監(jiān)控。如果土壤濕度低于一定水平,它會(huì)自動(dòng)啟動(dòng)水泵。我們之前建自動(dòng)植物灌溉系統(tǒng) 在移動(dòng)設(shè)備上發(fā)送警報(bào)但不監(jiān)控其他參數(shù)。除此之外, 雨水報(bào)警 和 土壤濕度檢測(cè)電路 也有助于構(gòu)建智能農(nóng)業(yè)監(jiān)測(cè)系統(tǒng)。
智慧農(nóng)業(yè)系統(tǒng)所需組件
NodeMCU ESP8266
土壤濕度傳感器
DHT11 傳感器
DS18B20 防水溫度傳感器探頭
LDR
潛水迷你水泵
12V LED燈條
7805穩(wěn)壓器
電阻器(4.7K、10K)
電容器(0.1μF、10μF)
在線服務(wù)
Adafruit IO
智慧農(nóng)業(yè)系統(tǒng)電路圖
智能農(nóng)業(yè)系統(tǒng)的完整示意圖如下:
這個(gè)電路并不難。這里我們使用了4個(gè)傳感器,即DHT11,DS18B20傳感器探頭,LDR和土壤濕度傳感器,一個(gè)12V LED燈條,12V水泵,7805穩(wěn)壓器,以及兩個(gè)TP122晶體管來(lái)控制LED燈條和水泵。7805 用于從 12V 適配器獲得穩(wěn)壓 5V,DHT11 傳感器用于獲取溫度和濕度讀數(shù)。DS18B20傳感器探頭用于獲取土壤溫度,土壤濕度傳感器用于讀取土壤濕度,以便自動(dòng)打開(kāi)/關(guān)閉水泵。
Adafruit IO 設(shè)置
Adafruit IO 是一個(gè)開(kāi)放數(shù)據(jù)平臺(tái),可讓您聚合、可視化和分析云上的實(shí)時(shí)數(shù)據(jù)。使用 Adafruit IO,您可以通過(guò) Internet 上傳、顯示和監(jiān)控您的數(shù)據(jù),并使您的項(xiàng)目支持物聯(lián)網(wǎng)。您可以使用 Adafruit IO 在互聯(lián)網(wǎng)上控制電機(jī)、讀取傳感器數(shù)據(jù)并制作酷炫的 IoT 應(yīng)用程序。
要使用 Adafruit IO,首先,您必須在 Adafruit IO 上創(chuàng)建一個(gè)帳戶。為此,請(qǐng)?jiān)L問(wèn) Adafruit IO 網(wǎng)站并單擊屏幕右上角的“免費(fèi)入門(mén)”。
完成帳戶創(chuàng)建過(guò)程后,登錄您的帳戶并單擊右上角的“查看 AIO Key”以獲取您的帳戶用戶名和 AIO 密鑰。
當(dāng)您“AIO 密鑰”時(shí),將彈出一個(gè)窗口,其中包含您的 Adafruit IO AIO 密鑰和用戶名。復(fù)制此密鑰和用戶名。您稍后將在代碼中使用它。
現(xiàn)在,在此之后,您需要?jiǎng)?chuàng)建一個(gè)提要。要?jiǎng)?chuàng)建提要,請(qǐng)單擊“提要”。然后單擊“操作”,您將看到一些選項(xiàng),從中單擊“創(chuàng)建新提要”。
之后,將打開(kāi)一個(gè)新窗口,您需要在其中輸入提要的名稱和描述。書(shū)寫(xiě)描述是可選的。
點(diǎn)擊“創(chuàng)建”;在此之后,您將被重定向到新創(chuàng)建的提要。
對(duì)于這個(gè)項(xiàng)目,我們總共為水泵、LED 燈條、濕度數(shù)據(jù)、溫度、濕度、天氣數(shù)據(jù)和土壤溫度創(chuàng)建了 8 個(gè)源。按照與上述相同的過(guò)程創(chuàng)建其余的提要。
創(chuàng)建提要后,現(xiàn)在我們將創(chuàng)建一個(gè) Adafruit IO 儀表板,以在單個(gè)頁(yè)面上顯示所有這些提要。為此,首先創(chuàng)建一個(gè)儀表板,然后在該儀表板中添加所有這些提要。
要?jiǎng)?chuàng)建儀表板,請(qǐng)單擊儀表板選項(xiàng),然后單擊“操作”,然后單擊“創(chuàng)建新儀表板”。
在下一個(gè)窗口中,輸入儀表板的名稱,然后單擊“創(chuàng)建”。
創(chuàng)建儀表板后,現(xiàn)在我們將塊添加到儀表板。要添加塊,請(qǐng)單擊右上角的“齒輪”,然后單擊“創(chuàng)建新塊”。
首先,我們將添加兩個(gè)切換按鈕塊來(lái)手動(dòng)打開(kāi)/關(guān)閉 LED 燈條和水泵,然后添加四個(gè)滑塊來(lái)顯示溫度、濕度、土壤溫度和水分值,最后,兩個(gè)圖表塊來(lái)顯示最近 30 天的水分和土壤溫度數(shù)據(jù)。要在儀表板上添加按鈕,請(qǐng)單擊 Toggle 塊。
在下一個(gè)窗口中,它將要求您選擇提要,因此單擊 LED 提要。
在此之后,按照相同的過(guò)程添加其余的塊。添加所有塊后,我的儀表板如下所示:
您可以通過(guò)單擊設(shè)置按鈕來(lái)編輯儀表板。
獲取 OpenWeatherMap API
如前所述,我們還將在 Adafruit IO 儀表板上顯示天氣預(yù)報(bào),為此,我們將使用OpenWeatherMap API 請(qǐng)求所選位置的當(dāng)天天氣預(yù)報(bào)。OpenWeatherMap 提供了高度可識(shí)別的天氣產(chǎn)品,使處理天氣數(shù)據(jù)變得更加容易。可以通過(guò)遵循行業(yè)標(biāo)準(zhǔn)并與不同類型的企業(yè)系統(tǒng)兼容的快速、可靠的 API 訪問(wèn)這些數(shù)據(jù)。OpenWeatherMap 提供付費(fèi)和免費(fèi)計(jì)劃,在這個(gè)項(xiàng)目中,我們將使用它的免費(fèi)計(jì)劃來(lái)獲取天氣預(yù)報(bào)數(shù)據(jù)。
現(xiàn)在要獲取 API 密鑰,必須在他們的平臺(tái)上注冊(cè),所以首先創(chuàng)建一個(gè)帳戶,一旦您的帳戶被創(chuàng)建,您將被重定向到儀表板,如下所示。從那里單擊您的姓名,然后單擊“我的 API 密鑰”,您將看到一個(gè)唯一的 API 密鑰以從站點(diǎn)中提取信息。
現(xiàn)在我們將使用 5 天/3 小時(shí)的預(yù)測(cè)數(shù)據(jù) API。此 API 包含間隔 3 小時(shí)的天氣預(yù)報(bào)數(shù)據(jù),并且預(yù)報(bào)數(shù)據(jù)以 JSON 或 XML 格式提供。要獲取您選擇的位置的天氣數(shù)據(jù),請(qǐng)輸入以下 URL,將大括號(hào)中的部分替換為城市和您的唯一 API 密鑰:
api.openweathermap.org/data/2.5/forecast?q={城市名稱}&appid={API 密鑰}
例如,我們的 API URL 將是:
api.openweathermap.org/data/2.5/forecast?q=齋浦爾&appid=e8b22b36da932dce8f31ec9be9cb68a3
將此 URL 粘貼到瀏覽器的搜索欄中,它應(yīng)該會(huì)為您提供一堆與您當(dāng)?shù)氐奶鞖忸A(yù)報(bào)信息相對(duì)應(yīng)的信息。
現(xiàn)在我們有了 JSON 數(shù)據(jù),下一步將生成代碼,通過(guò)它我們可以讀取 JSON 數(shù)據(jù)并根據(jù)需要對(duì)其進(jìn)行表述。為此,請(qǐng)轉(zhuǎn)到ArduinoJson 助手并在第一步中選擇處理器類型、模式和輸入類型。
然后在下一部分中,粘貼 JSON 數(shù)據(jù)。
然后在最后一步,您將獲得讀取天氣預(yù)報(bào)數(shù)據(jù)的代碼。我們不會(huì)使用助手生成的完整代碼。
智能農(nóng)業(yè)系統(tǒng)編程NodeMCU
基于物聯(lián)網(wǎng)的農(nóng)業(yè)監(jiān)測(cè)系統(tǒng)的完整代碼在文檔末尾給出。在這里,我們將解釋代碼的一些重要部分。該代碼使用DallasTemperature、OneWire、?Adafruit_MQTT、?ArduinoJson和DHT.h庫(kù)。Adafruit_MQTT.h和DHT11.h可以從給定的鏈接下載,其余的庫(kù)可以直接從 Arduino IDE 庫(kù)管理器下載。
將庫(kù)安裝到 Arduino IDE 后,通過(guò)包含所需的庫(kù)文件來(lái)啟動(dòng)代碼。
?
#include#include <達(dá)拉斯溫度.h> #include #include "DHT.h" #include "Adafruit_MQTT.h" #include "Adafruit_MQTT_Client.h" #include
?
然后輸入您從 Adafruit IO 服務(wù)器復(fù)制的 Wi-Fi 和 Adafruit IO 憑據(jù)。這些將包括 MQTT 服務(wù)器、端口號(hào)、用戶名和 AIO 密鑰。
?
const char *ssid = "Wi-Fi 名稱"; const char *pass = "Wi-Fi 密碼"; #define MQTT_SERV "io.adafruit.com" #define MQTT_PORT 1883 #define MQTT_NAME "Adafruit IO 用戶名" #define MQTT_PASS "AIO 密鑰"
?
然后設(shè)置用于存儲(chǔ)傳感器數(shù)據(jù)和控制 LED 和水泵的 Adafruit IO 饋送。在我的例子中,我定義了四個(gè)饋送來(lái)存儲(chǔ)不同的傳感器數(shù)據(jù),即:土壤溫度、溫度、濕度和濕度,一個(gè)用于顯示天氣數(shù)據(jù)的饋送和兩個(gè)用于控制 LED 燈條和水泵的饋送。
?
Adafruit_MQTT_Client mqtt(&client, MQTT_SERV, MQTT_PORT, MQTT_NAME, MQTT_PASS); Adafruit_MQTT_Publish Moisture = Adafruit_MQTT_Publish(&mqtt,MQTT_NAME "/f/Moisture"); Adafruit_MQTT_Publish 溫度 = Adafruit_MQTT_Publish(&mqtt,MQTT_NAME "/f/Temperature"); Adafruit_MQTT_Publish Humidity = Adafruit_MQTT_Publish(&mqtt,MQTT_NAME "/f/Humidity"); Adafruit_MQTT_Publish SoilTemp = Adafruit_MQTT_Publish(&mqtt,MQTT_NAME "/f/SoilTemp"); Adafruit_MQTT_Subscribe LED = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/LED"); Adafruit_MQTT_Subscribe Pump = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/Pump");
?
現(xiàn)在在setup()函數(shù)中,以 9600 的波特率初始化串行監(jiān)視器以進(jìn)行調(diào)試。同時(shí)使用begin()函數(shù)初始化 DHT 傳感器和 DS18B20 傳感器。
?
無(wú)效設(shè)置() { 序列號(hào).開(kāi)始(9600); 延遲(10); dht.begin(); 傳感器.開(kāi)始(); ……………….. }
?
現(xiàn)在是void loop()。這是執(zhí)行所有任務(wù)的地方。因此,在這個(gè)循環(huán)中,首先我們將從 OpenWeatherMap API 獲取天氣預(yù)報(bào)數(shù)據(jù),然后我們將讀取傳感器數(shù)據(jù),最后一步,我們將在 Adafruit IO 儀表板上發(fā)布所有這些數(shù)據(jù)。
閱讀天氣預(yù)報(bào):
要從 OpenWeatherMap API 讀取天氣預(yù)報(bào)數(shù)據(jù),我們將使用我們使用 ArduinoJson 助手生成的代碼片段。在 void 循環(huán)中,我們只會(huì)在特定時(shí)間間隔后調(diào)用 API,以免超出每日限制。
?
if (millis() - lastConnectionTime > postInterval) { // 注意建立連接的時(shí)間: 最后連接時(shí)間 = 毫秒(); makehttpRequest(); }
?
讀取傳感器數(shù)據(jù):?
現(xiàn)在獲取天氣數(shù)據(jù)后,接下來(lái)我們將讀取所有傳感器數(shù)據(jù)。這里我們使用 DHT11、DS18B20、LDR 和土壤濕度傳感器。LDR 和土壤濕度傳感器數(shù)據(jù)將用于自動(dòng)化 LED 燈條和水泵。所以首先我們將讀取 LDR 狀態(tài),如果 LDR 讀數(shù)小于 200,則 LED 將自動(dòng)打開(kāi)。同樣,如果土壤水分百分比小于 35,則水泵將打開(kāi)。
?
int ldrStatus = 模擬讀?。╨drPin); 如果(ldrStatus <= 200){ 數(shù)字寫(xiě)入(ledPin,高); } 別的 { 數(shù)字寫(xiě)入(ledPin,低);} 濕度百分比 = ( 100.00 - ( (analogRead(moisturePin) / 1023.00) * 100.00 ) ); 如果(水分百分比 < 35){ 數(shù)字寫(xiě)入(motorPin,高); } 溫度 = dht.readTemperature(); 濕度 = dht.readHumidity(); 傳感器.requestTemperatures(); 土壤溫度 = 傳感器.getTempCByIndex(0);
?
在 Adafruit IO 上發(fā)布數(shù)據(jù):?
現(xiàn)在我們已經(jīng)收集了所有數(shù)據(jù),是時(shí)候在 Adafruit IO 儀表板上發(fā)布這些數(shù)據(jù)了,以便我們可以從任何地方對(duì)其進(jìn)行監(jiān)控。在這里,我們會(huì)將不同的傳感器數(shù)據(jù)發(fā)布到各自的提要中。
?
if (currentTime - previousTime >= 間隔) { if (! Moisture.publish(moisturePercentage)) 如果(!溫度。發(fā)布(溫度)) 如果(!濕度。發(fā)布(濕度)) if (!SoilTemp.publish(soiltemp)) 如果(!WeatherData.publish(圖標(biāo))) }
?
用于智能農(nóng)業(yè)系統(tǒng)的 3D 打印外殼
由于這個(gè)項(xiàng)目將用于農(nóng)業(yè)應(yīng)用,我決定 3D 打印一個(gè)外殼。我用游標(biāo)測(cè)量了裝置的尺寸來(lái)設(shè)計(jì)外殼。完成后,我的設(shè)計(jì)看起來(lái)像這樣:
對(duì)設(shè)計(jì)滿意后,我將其導(dǎo)出為 STL 文件,根據(jù)打印機(jī)設(shè)置對(duì)其進(jìn)行切片,最后打印出來(lái)。STL 文件也可以從 Thingiverse 下載,您可以使用它打印自己的外殼。
打印完成后,我繼續(xù)將項(xiàng)目設(shè)置組裝在一個(gè)永久外殼中以備將來(lái)使用。完成連接后,我將電路組裝到我的外殼中,一切都非常合適,如下所示:
測(cè)試智能農(nóng)業(yè)系統(tǒng)
為了測(cè)試這個(gè)項(xiàng)目,我在塑料托盤(pán)中發(fā)了一些種子,如下圖所示:
我將硬件盒安裝在托盤(pán)旁邊,將水泵連接到水瓶,并連接電源。完成后,它開(kāi)始監(jiān)測(cè)不同的參數(shù),如土壤濕度、土壤溫度等。所有這些讀數(shù)都將發(fā)布在 Adafruit IO 儀表板上。
#include
#include
#include
#include "DHT.h"??
#include "Adafruit_MQTT.h"?
#include "Adafruit_MQTT_Client.h"?
#include
const char *ssid = "銀河-M20"; // 輸入您的 WiFi 名稱
const char *pass = "ac312124"; // 輸入您的 WiFi 密碼
WiFiClient 客戶端;
#define MQTT_SERV "io.adafruit.com"?
#define MQTT_PORT 1883?
#define MQTT_NAME "aschoudhary" // 你的 Adafruit IO 用戶
名 #define MQTT_PASS "1ac95cb8580b4271bbb6d9f75d0668f1" // Adafruit IO AIO key?
const char server[] = "api.openweathermap.org ";
字符串 apiKey = "e8b22b36da932dce8f31ec9be9cb68a3";?
字符串文本;
const char* icon="";?
int jsonend = 0;?
布爾 startJson = 假;
int 狀態(tài) = WL_IDLE_STATUS;
#define JSON_BUFF_DIMENSION 2500?
unsigned long lastConnectionTime = 10 * 60 * 1000; // 上次連接服務(wù)器的時(shí)間,以毫秒為單位
const unsigned long postInterval = 10 * 60 * 1000; // 發(fā)布間隔 10 分鐘(10L * 1000L;測(cè)試延遲 10 秒)
const int ldrPin = D1;?
常量 int ledPin = D0;?
常量int濕氣Pin = A0;// 濕度傳感器引腳
const int motorPin = D8;?
漂浮水分百分比;//濕度讀數(shù)
int溫度,濕度,土壤溫度;
#define ONE_WIRE_BUS 4 //nodemcu 的 D2 引腳
#define DHTTYPE DHT11 //DHT 11?
#define dht_dpin D4?
DHT dht(dht_dpin, DHTTYPE);?
單線單線(ONE_WIRE_BUS);
達(dá)拉斯溫度傳感器(&oneWire);
const unsigned long 間隔 = 50000;?
unsigned long previousTime = 0;?
//設(shè)置您要發(fā)布到
Adafruit_MQTT_Client mqtt(&client, MQTT_SERV, MQTT_PORT, MQTT_NAME, MQTT_PASS);?
Adafruit_MQTT_Publish Moisture = Adafruit_MQTT_Publish(&mqtt,MQTT_NAME "/f/Moisture"); // Moisture 是將發(fā)布數(shù)據(jù)的源名稱
Adafruit_MQTT_Publish Temperature = Adafruit_MQTT_Publish(&mqtt,MQTT_NAME "/f/Temperature");
Adafruit_MQTT_Publish Humidity = Adafruit_MQTT_Publish(&mqtt,MQTT_NAME "/f/Humidity");?
Adafruit_MQTT_Publish SoilTemp = Adafruit_MQTT_Publish(&mqtt,MQTT_NAME "/f/SoilTemp");?
Adafruit_MQTT_Publish WeatherData = Adafruit_MQTT_Publish(&mqtt,MQTT_NAME "/f/WeatherData");?
//設(shè)置您訂閱的訂閱
?源 Adafruit_MQTT_Subscribe LED = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/LED");?
?Adafruit_MQTT_Subscribe Pump = Adafruit_MQTT_Subscribe(&mqtt, MQTT_NAME "/f/Pump");??
無(wú)效設(shè)置()
{
? 序列.開(kāi)始(9600);
? 延遲(10);
? dht.begin();?
? 傳感器.開(kāi)始();
? mqtt.subscribe(&LED);?
? mqtt.subscribe(&Pump);
? pinMode(ledPin,輸出);
? pinMode(ldrPin,輸入);
? 數(shù)字寫(xiě)入(motorPin,低);// 最初保持電機(jī)關(guān)閉 digitalWrite?
? (ledPin, HIGH);?
? text.reserve(JSON_BUFF_DIMENSION);?
? Serial.println("正在連接");?
? 序列號(hào).println(ssid);?
? WiFi.開(kāi)始(ssid,通過(guò));
? 而(WiFi.status()!= WL_CONNECTED)
? {
? ? 延遲(500);
? ? Serial.print("."); // 打印...直到?jīng)]有連接
? }?
? Serial.println("");?
? Serial.println("WiFi 連接");?
}?
void loop()?
{?
?unsigned long currentTime = millis();?
?MQTT_connect();?
?if (millis() - lastConnectionTime >
? ? // 注意建立連接的時(shí)間:
? ? lastConnectionTime = millis();?
? ? makehttpRequest();?
? }?
//}?
?int ldrStatus = analogRead(ldrPin);?
? ? if (ldrStatus <= 200) {?
? ? ? ?digitalWrite(ledPin, HIGH);?
? ? ? ?Serial.print("天黑了,打開(kāi) LED :");?
? ? ? ?Serial.println(ldrStatus);? ??
? ? }??
? ? else {? ? ?
? ? ? digitalWrite(ledPin, LOW);?
? ? ? Serial.print("它很亮,關(guān)閉 LED :");?
? ? ? Serial.println(ldrStatus);?
? ? ?}
? 濕度百分比 = ( 100.00 - ( (analogRead(moisturePin) / 1023.00) * 100.00 ) );?
? Serial.print("土壤水分=");
? 序列號(hào).print(moisturePercentage);?
? 序列號(hào).println("%");? ?
if (moisturePercentage < 35) {?
? digitalWrite(motorPin, HIGH); // 調(diào)整電機(jī)
}?
if (moisturePercentage > 38) {?
? digitalWrite(motorPin, LOW); // 關(guān)閉電機(jī)
}?
?temperature = dht.readTemperature();??
?濕度 = dht.readHumidity();?
?//Serial.print("溫度:");?
?//Serial.print(溫度);?
?//Serial.println();??
?//Serial.print("濕度:");?
?//Serial.print(濕度);?
?//Serial.println();?
?傳感器.requestTemperatures();?
?土壤溫度 = 傳感器.getTempCByIndex(0);?
// Serial.println("土壤溫度:");
// Serial.println(soiltemp);?
if (currentTime - previousTime >= Interval) {??
? ? if (!Moisture.publish(moisturePercentage)) //此條件用于在 adafruit IO 上發(fā)布變量 (moisturePercentage)。根據(jù)你的改變變量。
? ? ? ? ?{? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? }?
? ? if (!Temperature.publish(temperature))??
? ? ? ? ?{? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ?}?
? ? if (!Humidity.publish(humanity))??
? ? ? ? ?{? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ?//delay(30000);? ?
? ? ? ? ? }?
? ? if (!SoilTemp.publish(soiltemp))??
? ? ? ?{? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? }?
? ? if (!WeatherData.publish(icon))?
? ? ? ?{? ? ? ? ? ?
? ? ? ? ?}
? ? ? ? ? 以前的時(shí)間 = 當(dāng)前時(shí)間;
}?
Adafruit_MQTT_Subscribe * 訂閱;
while ((subscription = mqtt.readSubscription(5000))) //在控制某些東西或從 Adafruit IO 獲取數(shù)據(jù)之前不要使用這個(gè)。
? ? ?{?
? ? if (subscription == &LED)?
? ? ?{?
? ? ? //將新值打印到串口監(jiān)視器
? ? ? Serial.println((char*) LED.lastread);?
? ? ? ? if (!strcmp((char*) LED.lastread, "OFF"))?
? ? ? ?{?
? ? ? ? ?digitalWrite(ledPin, LOW);?
? ? ? ? }?
? ? ? ? if (!strcmp((char*) LED.lastread, "ON"))?
? ? ? ? ? {?
? ? ? ? ?digitalWrite(ledPin, HIGH);?
? ? ? ? ?}
? ? ?}? ?
? ? if (subscription == &Pump)?
? ? ? {?
? ? ? //將新值打印到串口監(jiān)視器
? ? ? Serial.println((char*) Pump.lastread);?
? ? ? if (!strcmp((char*) Pump.lastread, "OFF"))?
? ? ? ?{?
? ? ? ? digitalWrite(motorPin, HIGH);?
? ? ? ?}?
? ? ?if (!strcmp((char*) Pump.lastread, "ON"))?
? ? ? ?{?
? ? ? ? digitalWrite(motorPin, LOW);?
? ? ? ?}?
? ? ?}?
? ? }
? 延遲(9000);
?// client.publish(WeatherData, icon)?
}?
void MQTT_connect()??
{?
? int8_t ret;?
? // 如果已經(jīng)連接則停止。
? if (mqtt.connected())??
? {
? ? 返回;
? }?
? uint8_t 重試次數(shù) = 3;?
? while ((ret = mqtt.connect()) != 0) // connect 將返回 0 連接
? {??
? ? ? ?mqtt.disconnect();?
? ? ? ?延遲(5000);// 等待 5 秒
? ? ? ?重試--;?
? ? ? ?if (retries == 0)??
? ? ? ?{?
? ? ? ? ?// 基本上死了,等待 WDT 重置我
? ? ? ? ?while (1);?
? ? ? ?}?
? }?
}?
void makehttpRequest() {?
? // 在發(fā)送新請(qǐng)求之前關(guān)閉任何連接以允許客戶端與服務(wù)器建立連接
? client.stop();?
? // 如果連接成功:
? if (client.connect(server, 80)) {
? ? client.println("GET /data/2.5/forecast?q=" + nameOfCity + "&APPID=" + apiKey + "&mode=json&units=metric&cnt=2 HTTP/1.1");?
? ? client.println("主機(jī):api.openweathermap.org");?
? ? client.println("用戶代理:ArduinoWiFi/1.1");?
? ? client.println("連接:關(guān)閉");?
? ? 客戶端.println();?
? ? 無(wú)符號(hào)長(zhǎng)超時(shí)=毫秒();
? ? while (client.available() == 0) {?
? ? ? if (millis() - timeout > 5000) {?
? ? ? ? Serial.println(">>> Client Timeout !");?
? ? ? ? 客戶端.stop();?
? ? ? ? 返回;?
? ? ? }?
? ? }? ?
? ? 字符 c = 0;?
? ? while (client.available()) {?
? ? ? c = client.
? ? ? // 由于 json 包含相同數(shù)量的打開(kāi)和關(guān)閉大括號(hào),這意味著我們可以通過(guò)計(jì)算
? ? ? 打開(kāi)和關(guān)閉出現(xiàn)次數(shù)來(lái)確定何時(shí)完全接收到 json,//?
? ? ? Serial.print(c);?
? ? ? if (c == '{') {?
? ? ? ? startJson = true; // 設(shè)置 startJson true 表示 json 消息已經(jīng)開(kāi)始
? ? ? ? jsonend++;?
? ? ? }?
? ? ? if (c == '}') {?
? ? ? ? jsonend--;?
? ? ? }?
? ? ? if (startJson == true) {?
? ? ? ? text += c;?
? ? ? }?
? ? ? // 如果 jsonend = 0 那么我們收到了相同數(shù)量的花括號(hào)?
? ? ? if (jsonend == 0 && startJson == true) {
? ? ? ? parseJson(text.c_str()); // 在 parseJson 函數(shù)中解析 c 字符串文本
? ? ? ? text = ""; // 下次清空字符串
? ? ? ? startJson = false; // 將 startJson 設(shè)置為 false,表示新消息尚未開(kāi)始
? ? ? }?
? ? }?
? }?
? else {?
? ? // 如果沒(méi)有建立連接:
? ? Serial.println("connection failed");?
? ? 返回;?
? }?
}?
//解析從OWM接收的json數(shù)據(jù)
void parseJson(const char * jsonString) {?
? //StaticJsonBuffer<4000> jsonBuffer;
? const size_t bufferSize = 2*JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(2) + 4*JSON_OBJECT_SIZE(1) + 3*JSON_OBJECT_SIZE(2) + 3*JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + 2*JSON_OBJECT_SIZE(7) + 2 *JSON_OBJECT_SIZE(8) + 720;
? DynamicJsonBuffer jsonBuffer(bufferSize);?
// DynamicJsonDocument(bufferSize);?
? // 在 JSON 樹(shù)中查找
? 字段 JsonObject& root = jsonBuffer.parseObject(jsonString);?
? if (!root.success()) {?
? ? Serial.println("parseObject() failed");?
? ? 返回;?
? }?
? JsonArray& list = root["list"];?
? JsonObject& nowT = list[0];?
? JsonObject& 稍后 = 列表 [1];?
? JsonObject& tommorow = list[2];?
// 字符串條件 = list.weather.main;
? // 包括溫度和濕度,供那些可能想破解它的人使用?
? String city = root["city"]["name"];?
? 字符串 weatherNow = nowT["天氣"][0]["描述"];?
? String weatherLater = later["weather"][0]["description"];?
? String list12 = later["weather"][0]["list"];?
? 序列號(hào).println(list12);?
? Serial.println(weatherLater);?
? if(weatherLater == "幾朵云"){?
? ? icon = "幾朵云";?
? ? 序列號(hào).print(icon);?
? }?
? else if(weatherLater == "rain"){?
? ? icon = "Rain";?
? ? 序列號(hào).print(icon);?
? }?
? else if(weatherLater == "破云"?
? ? ){ icon = "破云";?
? ? 序列號(hào).print(icon);?
? }
? 否則{
? ? 圖標(biāo)=“晴天”;
? ? }?
}
評(píng)論
查看更多