• 方案介紹
    • 一、項(xiàng)目介紹
    • 二、設(shè)計(jì)需求
    • 三、華為云產(chǎn)品設(shè)備創(chuàng)建
    • 四、硬件選型
    • 五、代碼設(shè)計(jì)
    • 六、上位機(jī)開發(fā)
  • 附件下載
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

基于物聯(lián)網(wǎng)設(shè)計(jì)的水稻田智能灌溉系統(tǒng)(STM32+華為云IOT)

05/28 10:04
362
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

更多詳細(xì)資料請(qǐng)聯(lián)系.docx

共1個(gè)文件

一、項(xiàng)目介紹

隨著科技的不斷發(fā)展和人們生活水平的提高,農(nóng)業(yè)生產(chǎn)也逐漸向智能化、高效化的方向發(fā)展。水稻作為我國主要的糧食作物之一,其生長(zhǎng)過程中的灌溉管理尤為重要。傳統(tǒng)的灌溉方式往往依賴于人工觀察和控制,不僅效率低下,而且容易出現(xiàn)誤差,無法滿足現(xiàn)代農(nóng)業(yè)生產(chǎn)的需求。

當(dāng)前設(shè)計(jì)了一款基于STM32的水稻田智能灌溉系統(tǒng)。該系統(tǒng)能夠通過水位傳感器溫度傳感器實(shí)時(shí)監(jiān)測(cè)稻田的水位和水溫,并根據(jù)設(shè)定的閾值自動(dòng)控制水泵的開關(guān),實(shí)現(xiàn)自動(dòng)灌溉。同時(shí),通過NBIOT模塊將實(shí)時(shí)數(shù)據(jù)上傳到華為云物聯(lián)網(wǎng)云平臺(tái),用戶可以通過手機(jī)APP遠(yuǎn)程監(jiān)控和控制設(shè)備的運(yùn)行,實(shí)現(xiàn)遠(yuǎn)程管理。相當(dāng)于直接將水稻田搬到了云端,后期還會(huì)加入攝像頭監(jiān)控,加入圖像處理,在家就可以了解到每一塊稻田的生長(zhǎng)情況。

整個(gè)系統(tǒng)的電源采用太陽能板供電。

整個(gè)系統(tǒng)的應(yīng)用可以大大提高水稻灌溉的效率和準(zhǔn)確性,減少人力資源的浪費(fèi),降低生產(chǎn)成本,并為農(nóng)業(yè)生產(chǎn)提供更有力的技術(shù)保障。此外,系統(tǒng)還可以推廣到其他領(lǐng)域的智能灌溉和控制中,具有廣闊的市場(chǎng)應(yīng)用前景。

二、設(shè)計(jì)需求

該系統(tǒng)通過水位傳感器檢測(cè)稻田的水位,根據(jù)預(yù)先設(shè)置的水位閾值,自動(dòng)控制繼電器開啟水泵進(jìn)行抽水灌溉,從而實(shí)現(xiàn)自動(dòng)補(bǔ)充灌溉水。同時(shí),溫度傳感器可以監(jiān)測(cè)水溫的變化,確保水溫適宜。利用NBIOT模塊實(shí)現(xiàn)與華為云物聯(lián)網(wǎng)云平臺(tái)的連接,將實(shí)時(shí)的水位和水溫?cái)?shù)據(jù)上傳到云平臺(tái)。

為了方便用戶遠(yuǎn)程操作和監(jiān)控,開發(fā)了手機(jī)APP。用戶可以通過APP遠(yuǎn)程手動(dòng)控制水泵的開關(guān),實(shí)現(xiàn)遠(yuǎn)程操作。同時(shí),手機(jī)APP可以實(shí)時(shí)顯示設(shè)備上傳的水溫和水位數(shù)據(jù),提供可視化的界面,方便用戶監(jiān)控農(nóng)田狀況。

主控芯片采用STM32F103C8T6,具有豐富的外設(shè)資源和良好的性能,能夠滿足系統(tǒng)的需求。水溫檢測(cè)方面采用DS18B20防水溫度傳感器,具有高精度和穩(wěn)定性,可以準(zhǔn)確地監(jiān)測(cè)水溫。NBIOT聯(lián)網(wǎng)模塊采用BC26,支持NB-IoT通信技術(shù),能夠?qū)崿F(xiàn)與云平臺(tái)的連接。云服務(wù)器采用華為云物聯(lián)網(wǎng)服務(wù)器,提供穩(wěn)定可靠的云端服務(wù)。手機(jī)APP采用Qt進(jìn)行開發(fā),可以在不同的平臺(tái)上運(yùn)行,并提供友好的用戶界面和交互體驗(yàn)。

系統(tǒng)的功能主要包括以下幾個(gè)方面:

(1)水位檢測(cè):系統(tǒng)需要通過水位傳感器實(shí)時(shí)監(jiān)測(cè)稻田的水位,并能夠根據(jù)設(shè)定的閾值自動(dòng)控制水泵的開關(guān),實(shí)現(xiàn)自動(dòng)灌溉。

(2)水溫檢測(cè):系統(tǒng)需要通過溫度傳感器實(shí)時(shí)監(jiān)測(cè)稻田的水溫,并將數(shù)據(jù)傳輸到云平臺(tái)進(jìn)行遠(yuǎn)程監(jiān)控。

(3)數(shù)據(jù)傳輸:系統(tǒng)需要通過NBIOT模塊將實(shí)時(shí)水溫和水位數(shù)據(jù)上傳到華為云物聯(lián)網(wǎng)云平臺(tái),實(shí)現(xiàn)遠(yuǎn)程監(jiān)控和控制。

(4)遠(yuǎn)程控制:用戶可以通過手機(jī)APP遠(yuǎn)程監(jiān)控和控制設(shè)備的運(yùn)行,包括水泵的開關(guān)和閾值的設(shè)置等。

(5)人機(jī)界面:手機(jī)APP需要提供友好的人機(jī)界面,能夠?qū)崟r(shí)顯示設(shè)備上傳的水溫和水位數(shù)據(jù),并提供相應(yīng)的操作按鈕。

在硬件選型方面,主要考慮了以下幾個(gè)方面:

(1)主控芯片:選擇了STM32F103C8T6作為主控芯片。STM32F103C8T6是一款基于ARM Cortex-M3內(nèi)核的32位微控制器,具有高性能、低功耗、易于開發(fā)等優(yōu)點(diǎn)。該芯片具有豐富的外設(shè)接口,能夠滿足本系統(tǒng)的需求。

(2)水位傳感器:選擇了防水型的水位傳感器,以確保在潮濕環(huán)境下能夠正常工作。該傳感器具有高精度、高可靠性、低功耗等優(yōu)點(diǎn),能夠滿足本系統(tǒng)的需求。

(3)溫度傳感器:選擇了DS18B20防水溫度傳感器,該傳感器具有高精度、高可靠性、低功耗等優(yōu)點(diǎn),能夠?qū)崟r(shí)檢測(cè)稻田的水溫,并將數(shù)據(jù)傳輸?shù)街骺匦酒?/p>

(4)NBIOT模塊:選擇了BC26模塊作為NBIOT通信模塊。該模塊具有低功耗、高穩(wěn)定性、易于開發(fā)等優(yōu)點(diǎn),能夠?qū)?shí)時(shí)數(shù)據(jù)上傳到華為云物聯(lián)網(wǎng)云平臺(tái)。

(5)水泵:選擇具有自動(dòng)控制功能的水泵,能夠根據(jù)主控芯片的控制信號(hào)自動(dòng)開關(guān)。

三、華為云產(chǎn)品設(shè)備創(chuàng)建

這一章節(jié)主要是介紹華為云物聯(lián)網(wǎng)云端產(chǎn)品與設(shè)備的創(chuàng)建流程。

3.1 開通物聯(lián)網(wǎng)服務(wù)

地址: https://www.huaweicloud.com/product/iothub.html

image-20230801151136153

點(diǎn)擊總覽,查看接入信息。 我們當(dāng)前設(shè)備準(zhǔn)備采用MQTT協(xié)議接入華為云平臺(tái),這里可以看到MQTT協(xié)議的地址和端口號(hào)等信息。

image-20230925155200396

image-20230925155233810

總結(jié):

端口號(hào):   MQTT (1883)  
接入地址: e244e6efb9.st1.iotda-device.cn-north-4.myhuaweicloud.com

根據(jù)域名地址得到IP地址信息:

Microsoft Windows [版本 10.0.19045.3448]
(c) Microsoft Corporation。保留所有權(quán)利。

C:Users11266>ping e244e6efb9.st1.iotda-device.cn-north-4.myhuaweicloud.com

正在 Ping e244e6efb9.st1.iotda-device.cn-north-4.myhuaweicloud.com [117.78.5.125] 具有 32 字節(jié)的數(shù)據(jù):
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=41ms TTL=94
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=44ms TTL=94
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=43ms TTL=94
來自 117.78.5.125 的回復(fù): 字節(jié)=32 時(shí)間=42ms TTL=94

117.78.5.125 的 Ping 統(tǒng)計(jì)信息:
    數(shù)據(jù)包: 已發(fā)送 = 4,已接收 = 4,丟失 = 0 (0% 丟失),
往返行程的估計(jì)時(shí)間(以毫秒為單位):
    最短 = 41ms,最長(zhǎng) = 44ms,平均 = 42ms

C:Users11266>

image-20230925155314730

MQTT協(xié)議接入端口號(hào)有兩個(gè),1883是非加密端口,8883是證書加密端口,單片機(jī)無法加載證書,所以使用1883端口比較合適。 接下來的ESP8266就采用1883端口連接華為云物聯(lián)網(wǎng)平臺(tái)。

3.2 創(chuàng)建產(chǎn)品

(1)創(chuàng)建產(chǎn)品

點(diǎn)擊產(chǎn)品頁,再點(diǎn)擊創(chuàng)建產(chǎn)品。

image-20230925155450476

(2)填寫產(chǎn)品信息

根據(jù)自己產(chǎn)品名字填寫。

(3)品創(chuàng)建成功

(4)添加自定義模型

產(chǎn)品創(chuàng)建完成之后,點(diǎn)擊進(jìn)入產(chǎn)品詳情頁面,翻到最下面可以看到模型定義。

這個(gè)模型就是定義自己設(shè)備接下來需要向服務(wù)器上傳那些數(shù)據(jù)類型。根據(jù)自己的數(shù)據(jù)類型進(jìn)行編寫。

3.3 添加設(shè)備

產(chǎn)品是屬于上層的抽象模型,接下來在產(chǎn)品模型下添加實(shí)際的設(shè)備。添加的設(shè)備最終需要與真實(shí)的設(shè)備關(guān)聯(lián)在一起,完成數(shù)據(jù)交互。

(1)注冊(cè)設(shè)備

image-20230925160050686

(2)根據(jù)自己的設(shè)備填寫

設(shè)備標(biāo)識(shí)碼、密碼這些根據(jù)自己情況認(rèn)真填寫。

(3)保存設(shè)備信息

創(chuàng)建完畢之后,點(diǎn)擊保存并關(guān)閉,得到創(chuàng)建的設(shè)備密匙信息。該信息在后續(xù)生成MQTT三元組的時(shí)候需要使用。

創(chuàng)建之后,得到的設(shè)備信息如下:

{
    "device_id": "65113d05a559fd7cd41435f8_lock1",
    "secret": "12345678"
}

(4)設(shè)備創(chuàng)建完成

可以點(diǎn)擊設(shè)備進(jìn)入到設(shè)備詳情頁面。

3.4 MQTT協(xié)議主題訂閱與發(fā)布

(1)主題訂閱格式

幫助文檔地址:https://support.huaweicloud.com/devg-iothub/iot_02_2200.html

image-20230801151350067

image-20230801151355027

對(duì)于設(shè)備而言,一般會(huì)訂閱平臺(tái)下發(fā)消息給設(shè)備 這個(gè)主題。

設(shè)備想接收平臺(tái)下發(fā)的消息,就需要訂閱平臺(tái)下發(fā)消息給設(shè)備 的主題,訂閱后,平臺(tái)下發(fā)消息給設(shè)備,設(shè)備就會(huì)收到消息。

如果設(shè)備想要知道平臺(tái)下發(fā)的消息,需要訂閱上面圖片里標(biāo)注的主題。

以當(dāng)前設(shè)備為例,最終訂閱主題的格式如下:
$oc/devices/{device_id}/sys/messages/down

最終的格式:
$oc/devices/65113d05a559fd7cd41435f8_lock1/sys/messages/down

?

(2)主題發(fā)布格式

對(duì)于設(shè)備來說,主題發(fā)布表示向云平臺(tái)上傳數(shù)據(jù),將最新的傳感器數(shù)據(jù),設(shè)備狀態(tài)上傳到云平臺(tái)。

這個(gè)操作稱為:屬性上報(bào)。

幫助文檔地址:https://support.huaweicloud.com/api-iothub/iot_06_v5_3010.html

image-20230925160939978

根據(jù)幫助文檔的介紹, 當(dāng)前設(shè)備發(fā)布主題,上報(bào)屬性的格式總結(jié)如下:

發(fā)布的主題格式:
$oc/devices/{device_id}/sys/properties/report
 
最終的格式:
$oc/devices/65113d05a559fd7cd41435f8_lock1/sys/properties/report
發(fā)布主題時(shí),需要上傳數(shù)據(jù),這個(gè)數(shù)據(jù)格式是JSON格式。

上傳的JSON數(shù)據(jù)格式如下:

{
  "services": [
    {
      "service_id": <填服務(wù)ID>,
      "properties": {
        "<填屬性名稱1>": <填屬性值>,
        "<填屬性名稱2>": <填屬性值>,
        ..........
      }
    }
  ]
}
根據(jù)JSON格式,一次可以上傳多個(gè)屬性字段。 這個(gè)JSON格式里的,服務(wù)ID,屬性字段名稱,屬性值類型,在前面創(chuàng)建產(chǎn)品的時(shí)候就已經(jīng)介紹了,不記得可以翻到前面去查看。

根據(jù)這個(gè)格式,組合一次上傳的屬性數(shù)據(jù):
{"services": [{"service_id": "lock","properties":{"lock":1}}]}

3.5 MQTT三元組

MQTT協(xié)議登錄需要填用戶ID,設(shè)備ID,設(shè)備密碼等信息,就像我們平時(shí)登錄QQ,微信一樣要輸入賬號(hào)密碼才能登錄。MQTT協(xié)議登錄的這3個(gè)參數(shù),一般稱為MQTT三元組。

接下來介紹,華為云平臺(tái)的MQTT三元組參數(shù)如何得到。

(1)MQTT服務(wù)器地址

要登錄MQTT服務(wù)器,首先記得先知道服務(wù)器的地址是多少,端口是多少。

幫助文檔地址:https://console.huaweicloud.com/iotdm/?region=cn-north-4#/dm-portal/home

MQTT協(xié)議的端口支持1883和8883,它們的區(qū)別是:8883 是加密端口更加安全。但是單片機(jī)上使用比較困難,所以當(dāng)前的設(shè)備是采用1883端口進(jìn)連接的。

根據(jù)上面的域名和端口號(hào),得到下面的IP地址和端口號(hào)信息: 如果設(shè)備支持填寫域名可以直接填域名,不支持就直接填寫IP地址。 (IP地址就是域名解析得到的)

華為云的MQTT服務(wù)器地址:117.78.5.125
域名:e244e6efb9.st1.iotda-device.cn-north-4.myhuaweicloud.com
華為云的MQTT端口號(hào):1883

注意! 具體要看這里:

image-20230925161111346

(2)生成MQTT三元組

華為云提供了一個(gè)在線工具,用來生成MQTT鑒權(quán)三元組: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/

打開這個(gè)工具,填入設(shè)備的信息(也就是剛才創(chuàng)建完設(shè)備之后保存的信息),點(diǎn)擊生成,就可以得到MQTT的登錄信息了。

下面是打開的頁面:

image-20230801151418248

填入設(shè)備的信息: (上面兩行就是設(shè)備創(chuàng)建完成之后保存得到的)

image-20230925161154059

得到三元組之后,設(shè)備端通過MQTT協(xié)議登錄鑒權(quán)的時(shí)候,填入?yún)?shù)即可。

ClientId 65113d05a559fd7cd41435f8_lock1_0_0_2023092508
Username 65113d05a559fd7cd41435f8_lock1
Password 1a3e7f486aa551bca7b6ff5c19c29d2006e940ec1f98ab416e10be1288106953

3.6 模擬設(shè)備登錄測(cè)試

經(jīng)過上面的步驟介紹,已經(jīng)創(chuàng)建了產(chǎn)品,設(shè)備,數(shù)據(jù)模型,得到MQTT登錄信息。 接下來就用MQTT客戶端軟件模擬真實(shí)的設(shè)備來登錄平臺(tái)。測(cè)試與服務(wù)器通信是否正常。

(1)填入登錄信息

打開MQTT客戶端軟件,對(duì)號(hào)填入相關(guān)信息(就是上面的文本介紹)。然后,點(diǎn)擊登錄,訂閱主題,發(fā)布主題。

image-20230925161345360

(2)打開網(wǎng)頁查看

完成上面的操作之后,打開華為云網(wǎng)頁后臺(tái),可以看到設(shè)備已經(jīng)在線了。

點(diǎn)擊詳情頁面,可以看到上傳的數(shù)據(jù)。

到此,云平臺(tái)的部署已經(jīng)完成,設(shè)備已經(jīng)可以正常上傳數(shù)據(jù)了。

四、硬件選型

下面是為了驗(yàn)證設(shè)計(jì)而選型的相關(guān)的硬件模型,能夠?qū)崿F(xiàn)最終的設(shè)計(jì)效果。 模型設(shè)計(jì)最終驗(yàn)證成功之后,重新畫板選型硬件一體化設(shè)計(jì)產(chǎn)品就方便多了。

【1】STM32開發(fā)板

image-20231012155204914

【2】水泵電機(jī)

image-20231012155515636

【3】BC26-NBIOT

image-20231012155624706

【4】水溫檢測(cè)

image-20231012155721909

【5】水位檢測(cè)

鏈接:https://item.taobao.com/item.htm?spm=a21n57.1.0.0.636b523cIyIKxC&id=735112974467&ns=1&abbucket=19#detail

image-20231012155816680

【6】太陽能板

image-20231012161934961

五、代碼設(shè)計(jì)

5.1 主函數(shù)代碼框架

#include "stm32f10x.h"
#include "ds18b20.h"
#include "nbiot.h"

// 定義水位傳感器引腳和繼電器引腳
#define WATER_LEVEL_PIN   GPIO_Pin_0
#define WATER_LEVEL_PORT  GPIOA
#define RELAY_PIN         GPIO_Pin_1
#define RELAY_PORT        GPIOA

// 定義溫度傳感器引腳
#define TEMP_SENSOR_PIN   GPIO_Pin_2
#define TEMP_SENSOR_PORT  GPIOA

// 定義NBIOT模塊和云服務(wù)器相關(guān)參數(shù)
#define NBIOT_RX_PIN      GPIO_Pin_3
#define NBIOT_RX_PORT     GPIOA
#define NBIOT_TX_PIN      GPIO_Pin_4
#define NBIOT_TX_PORT     GPIOA
#define SERVER_ADDRESS    "your_server_address"
#define DEVICE_ID         "your_device_id"
#define DEVICE_KEY        "your_device_key"

// 定義APP開關(guān)水泵控制命令
#define CMD_PUMP_ON       '1'
#define CMD_PUMP_OFF      '0'

// 初始化函數(shù)
void init();
// 獲取水位值
uint8_t getWaterLevel();
// 控制水泵
void controlPump(uint8_t state);
// 獲取溫度值
float getTemperature();
// 更新數(shù)據(jù)到華為云服務(wù)器
void updateDataToCloud(float temperature, uint8_t waterLevel);
// 處理NBIOT模塊接收到的命令
void handleNBIOTCommand(char cmd);

int main(void) {
  // 初始化
  init();

  while (1) {
    // 獲取水位值
    uint8_t waterLevel = getWaterLevel();
    // 控制水泵
    controlPump(waterLevel);
    // 獲取溫度值
    float temperature = getTemperature();
    // 更新數(shù)據(jù)到華為云服務(wù)器
    updateDataToCloud(temperature, waterLevel);
    // 處理NBIOT模塊接收到的命令
    char command = receiveNBIOTCommand();
    handleNBIOTCommand(command);
  }
}

void init() {
  // 初始化GPIO和相關(guān)外設(shè)
  // ...

  // 初始化DS18B20溫度傳感器
  DS18B20_Init(TEMP_SENSOR_PIN);

  // 初始化NBIOT模塊
  NBIOT_Init(NBIOT_RX_PIN, NBIOT_TX_PIN, SERVER_ADDRESS, DEVICE_ID, DEVICE_KEY);
}

uint8_t getWaterLevel() {
  // 讀取水位傳感器的值
  // ...
}

void controlPump(uint8_t state) {
  if (state == 0) {
    // 關(guān)閉繼電器,停止水泵
    GPIO_ResetBits(RELAY_PORT, RELAY_PIN);
  } else {
    // 打開繼電器,啟動(dòng)水泵
    GPIO_SetBits(RELAY_PORT, RELAY_PIN);
  }
}

float getTemperature() {
  // 讀取溫度傳感器的值
  // ...
}

void updateDataToCloud(float temperature, uint8_t waterLevel) {
  // 將溫度和水位值上傳到華為云服務(wù)器
  // ...
}

void handleNBIOTCommand(char cmd) {
  if (cmd == CMD_PUMP_ON) {
    // 手機(jī)APP發(fā)送打開水泵的命令
    controlPump(1);
  } else if (cmd == CMD_PUMP_OFF) {
    // 手機(jī)APP發(fā)送關(guān)閉水泵的命令
    controlPump(0);
  }
}

5.2 BC26模塊代碼

#include <stm32f10x.h>
#include <usart.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <delay.h>

// 定義BC26串口
#define BC26_USART USART1

// 定義MQTT服務(wù)器信息
#define MQTT_SERVER_IP "192.168.1.100"
#define MQTT_SERVER_PORT "1883"
#define MQTT_USERNAME "username"
#define MQTT_PASSWORD "password"
#define MQTT_CLIENT_ID "client_id"

// 串口發(fā)送字符串
void sendString(const char *str) {
    while (*str) {
        USART_SendData(BC26_USART, *str++);
        while (USART_GetFlagStatus(BC26_USART, USART_FLAG_TC) == RESET);
    }
}

// 延時(shí)等待響應(yīng)
bool waitForResponse(const char *response, uint32_t timeout) {
    uint32_t startTime = millis();
    uint32_t elapsedTime = 0;
    uint8_t rxData = 0;
    uint8_t responseIndex = 0;

    while (elapsedTime < timeout) {
        if (USART_GetFlagStatus(BC26_USART, USART_FLAG_RXNE) != RESET) {
            rxData = USART_ReceiveData(BC26_USART);
            if (rxData == response[responseIndex]) {
                responseIndex++;
                if (response[responseIndex] == '?') {
                    return true; // 收到完整響應(yīng)
                }
            } else {
                responseIndex = 0; // 重置響應(yīng)索引
            }
        }

        elapsedTime = millis() - startTime;
    }

    return false; // 超時(shí)未收到完整響應(yīng)
}

// 初始化BC26模塊
bool initBC26Module() {
    sendString("AT+CFUN=1rn"); // 設(shè)置BC26模塊為全功能模式
    if (!waitForResponse("OK", 1000)) {
        return false;
    }

    sendString("AT+CIMIrn"); // 獲取SIM卡的IMSI號(hào)碼
    if (!waitForResponse("OK", 1000)) {
        return false;
    }

    sendString("AT+QCFG="nwscanmode",0,1rn"); // 設(shè)置網(wǎng)絡(luò)掃描模式為自動(dòng)模式
    if (!waitForResponse("OK", 1000)) {
        return false;
    }

    sendString("AT+QCFG="iotopmode",2,1rn"); // 設(shè)置連接模式為Cat M1/NB1優(yōu)先模式
    if (!waitForResponse("OK", 1000)) {
        return false;
    }

    sendString("AT+QICSGP=1,1,"your_apn","","",1rn"); // 配置APN參數(shù),根據(jù)具體網(wǎng)絡(luò)運(yùn)營商設(shè)置
    if (!waitForResponse("OK", 1000)) {
        return false;
    }

    sendString("AT+QIACT=1rn"); // 激活PDP上下文
    if (!waitForResponse("OK", 10000)) {
        return false;
    }

    sendString("AT+QMTOPEN=0,"");
    sendString(MQTT_SERVER_IP); // 連接MQTT服務(wù)器
    sendString("",");
    sendString(MQTT_SERVER_PORT);
    sendString("rn");
    if (!waitForResponse("+QMTOPEN: 0,0", 20000)) {
        return false;
    }

    sendString("AT+QMTCONN=0,"");
    sendString(MQTT_CLIENT_ID); // 使用指定的Client ID連接MQTT服務(wù)器
    sendString("","");
    sendString(MQTT_USERNAME);
    sendString("","");
    sendString(MQTT_PASSWORD);
    sendString(""rn");
    if (!waitForResponse("+QMTCONN: 0,0,0", 10000)) {
        return false;
    }

    return true; // 初始化成功
}

int main(void) {
    // 初始化系統(tǒng)時(shí)鐘等

    USART_InitTypeDef USART_InitStructure;
    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(BC26_USART, &USART_InitStructure);
    USART_Cmd(BC26_USART, ENABLE);

    initBC26Module();

    while (1) {
        // 執(zhí)行其他操作或處理MQTT消息

    }
}

5.3 電機(jī)控制代碼

#include <stm32f10x.h>
#include <stdbool.h>

// 定義電機(jī)引腳
#define MOTOR_PORT GPIOA
#define MOTOR_PIN GPIO_Pin_0

// 初始化電機(jī)引腳
void initMotor() {
    // 使能GPIO時(shí)鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    // 初始化GPIO引腳
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = MOTOR_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽輸出模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(MOTOR_PORT, &GPIO_InitStructure);
}

// 控制電機(jī)狀態(tài)
void setMotorState(bool enabled) {
    if (enabled) {
        GPIO_SetBits(MOTOR_PORT, MOTOR_PIN); // 電機(jī)打開
    } else {
        GPIO_ResetBits(MOTOR_PORT, MOTOR_PIN); // 電機(jī)關(guān)閉
    }
}

int main(void) {
    // 初始化系統(tǒng)時(shí)鐘等

    initMotor();

    while (1) {
        // 控制電機(jī)狀態(tài)
        setMotorState(true); // 打開電機(jī)

        // 延時(shí)一段時(shí)間

        setMotorState(false); // 關(guān)閉電機(jī)

        // 延時(shí)一段時(shí)間
    }
}

5.4 水位檢測(cè)代碼

#include <stm32f10x.h>
#include <stdio.h>
#include <delay.h>

// 定義ADC引腳和通道
#define ADC_PORT GPIOA
#define ADC_PIN GPIO_Pin_0
#define ADC_CHANNEL ADC_Channel_0

// ADC初始化
void initADC() {
    // 使能ADC時(shí)鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

    // 初始化GPIO引腳
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = ADC_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(ADC_PORT, &GPIO_InitStructure);

    // 初始化ADC參數(shù)
    ADC_InitTypeDef ADC_InitStructure;
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; // 獨(dú)立模式
    ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 單通道掃描模式
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // 連續(xù)轉(zhuǎn)換模式
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 不用外部觸發(fā)
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; // 數(shù)據(jù)右對(duì)齊
    ADC_InitStructure.ADC_NbrOfChannel = 1; // 采樣通道數(shù)量
    ADC_Init(ADC1, &ADC_InitStructure);

    // 配置ADC采樣通道
    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL, 1, ADC_SampleTime_55Cycles5);

    // 使能ADC
    ADC_Cmd(ADC1, ENABLE);

    // ADC校準(zhǔn)
    ADC_ResetCalibration(ADC1);
    while (ADC_GetResetCalibrationStatus(ADC1));
    ADC_StartCalibration(ADC1);
    while (ADC_GetCalibrationStatus(ADC1));
}

// 讀取ADC轉(zhuǎn)換值
uint16_t readADC() {
    ADC_RegularChannelConfig(ADC1, ADC_CHANNEL, 1, ADC_SampleTime_55Cycles5);
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));

    return ADC_GetConversionValue(ADC1);
}

int main(void) {
    // 初始化系統(tǒng)時(shí)鐘等

    initADC();

    while (1) {
        uint16_t adcValue = readADC();
        printf("ADC Value: %drn", adcValue);

        // 進(jìn)行水位傳感器的處理和其他操作

        delay_ms(1000); // 延時(shí)1秒
    }
}

5.5 水溫檢測(cè)代碼

#include <stm32f10x.h>
#include <delay.h>

// 定義溫度傳感器引腳
#define TEMPERATURE_PIN GPIO_Pin_1
#define TEMPERATURE_GPIO GPIOA

// 初始化溫度傳感器
void initTemperatureSensor() {
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = TEMPERATURE_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // 使用開漏輸出模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    
    GPIO_Init(TEMPERATURE_GPIO, &GPIO_InitStructure);
}

// 發(fā)送復(fù)位信號(hào)
void resetSensor() {
    GPIO_SetBits(TEMPERATURE_GPIO, TEMPERATURE_PIN);
    delay_us(500);
    GPIO_ResetBits(TEMPERATURE_GPIO, TEMPERATURE_PIN);
    delay_us(500);
    GPIO_SetBits(TEMPERATURE_GPIO, TEMPERATURE_PIN);
    delay_us(500);
}

// 讀取一位數(shù)據(jù)
uint8_t readBit() {
    uint8_t data = 0;
    GPIO_SetBits(TEMPERATURE_GPIO, TEMPERATURE_PIN);
    delay_us(2);
    GPIO_ResetBits(TEMPERATURE_GPIO, TEMPERATURE_PIN);
    delay_us(2);
    GPIO_SetBits(TEMPERATURE_GPIO, TEMPERATURE_PIN);
    delay_us(1);
    if (GPIO_ReadInputDataBit(TEMPERATURE_GPIO, TEMPERATURE_PIN)) {
        data = 1;
    }
    delay_us(60);
    return data;
}

// 讀取一個(gè)字節(jié)數(shù)據(jù)
uint8_t readByte() {
    uint8_t byte = 0;
    for (int i = 0; i < 8; i++) {
        byte |= readBit() << i;
    }
    return byte;
}

// 寫入一位數(shù)據(jù)
void writeBit(uint8_t bit) {
    GPIO_SetBits(TEMPERATURE_GPIO, TEMPERATURE_PIN);
    delay_us(2);
    GPIO_ResetBits(TEMPERATURE_GPIO, TEMPERATURE_PIN);
    delay_us(2);
    if (bit) {
        GPIO_SetBits(TEMPERATURE_GPIO, TEMPERATURE_PIN);
    }
    delay_us(60);
    GPIO_SetBits(TEMPERATURE_GPIO, TEMPERATURE_PIN);
}

// 寫入一個(gè)字節(jié)數(shù)據(jù)
void writeByte(uint8_t byte) {
    for (int i = 0; i < 8; i++) {
        writeBit(byte & 0x01);
        byte >>= 1;
    }
}

// 獲取溫度值
float getTemperature() {
    uint8_t temperature[2];

    resetSensor();
    writeByte(0xCC); // 跳過ROM命令
    writeByte(0x44); // 啟動(dòng)溫度轉(zhuǎn)換命令
    delay_ms(800); // 等待轉(zhuǎn)換完成

    resetSensor();
    writeByte(0xCC); // 跳過ROM命令
    writeByte(0xBE); // 讀取溫度值命令

    temperature[0] = readByte();
    temperature[1] = readByte();

    int16_t rawTemperature = (temperature[1] << 8) | temperature[0];
    float temp = rawTemperature * 0.0625;

    return temp;
}

int main(void) {
    // 初始化系統(tǒng)時(shí)鐘等
    
    initTemperatureSensor();
    
    while (1) {
        float temperature = getTemperature();
        
        // 處理溫度數(shù)據(jù)
        
    }
}

六、上位機(jī)開發(fā)

這篇主要介紹硬件端的設(shè)計(jì)、華為云物聯(lián)網(wǎng)服務(wù)器端的設(shè)計(jì)。下一篇詳細(xì)介紹WEB網(wǎng)頁端、手機(jī)APP和微信小程序的開發(fā)。

  • 更多詳細(xì)資料請(qǐng)聯(lián)系.docx
    下載

相關(guān)推薦

方案定制

去合作
方案開發(fā)定制化,2000+方案商即時(shí)響應(yīng)!