一、項目背景
智慧農業是近年來發展迅速的領域,其目的是利用先進的傳感技術、物聯網技術和云計算技術等,實現自動化、智能化的農業生產管理,并提高農業生產效率和質量。本文基于CC2530設計了一種智慧農業控制系統,采用DHT11模塊、BH1750模塊和土壤濕度傳感器等傳感器,通過串口協議將采集的數據上傳給上位機顯示。
二、系統框架
本系統主要包括一下的組成部分:
【1】采集端:由CC2530單片機和各種傳感器構成,負責測量環境溫濕度、環境光照強度和土壤濕度等信息,并通過串口協議將采集的數據上傳給上位機顯示。
【2】上位機:采用Qt進行開發,負責接收串口上傳的數據并進行顯示。
【3】傳輸介質:采用串口協議進行數據傳輸,支持異步通信,具有數據幀結構。
【4】傳感器模塊:包括DHT11模塊、BH1750模塊和土壤濕度傳感器等,通過采集環境溫濕度、環境光照強度和土壤濕度等信息,實現對農業生產環境的監測和控制。
CC2530是德州儀器(Texas Instruments)推出的一款低功耗無線系統芯片,它是基于ZigBee協議的SoC系統,內置了ARM Cortex-M3處理器和IEEE 802.15.4標準無線通信模塊,可以實現低速率的無線數據傳輸和網絡互連。CC2530芯片的主要特點是低功耗、高可靠性、靈活性強、易于集成和開發,被廣泛應用于物聯網、智能家居、智能電表、智能照明等領域的無線數據傳輸和控制系統中。
BH1750是一款數字式環境光傳感器,可用于測量光強度。它具有高分辨率和靈敏度,并且與普通光敏電阻相比,具有更廣泛的動態范圍和線性性。BH1750可以通過I2C接口連接到微控制器或其他電子設備上,如Arduino、樹莓派等。它被廣泛應用于夜間照明系統、自動控制系統、安防監控等領域。
DHT11是一種數字溫濕度傳感器,可以測量環境的溫度和相對濕度。它通常被用于家庭和工業自動化等領域,可以在各種應用中監測環境條件。
DHT11有四個引腳:VCC(電源正極)、GND(地)、DATA(數據信號)和NC(未使用)。它可以通過單一總線接口與微控制器連接,并以數字形式輸出溫度和濕度值。其溫度測量范圍為0℃至50℃,濕度測量范圍為20%RH至90%RH。
在使用DHT11傳感器時,需要注意一些問題。例如,在讀取數據之前,應將傳感器加電并等待1至2秒鐘,以使其穩定。此外,在讀取數據后,還需要進行數據校驗,以確保數據的準確性。
三、系統設計
【1】采集端設計
采集端主要由CC2530單片機和各種傳感器構成。其中,溫濕度采用DHT11模塊,光照強度采用BH1750模塊,土壤濕度采用土壤濕度傳感器。通過采集這些信息,可以了解農田的環境狀態,并根據需要進行相應的調節和控制,保證作物的正常生長。
【2】上位機設計
上位機采用QT進行開發,支持串口通信和數據顯示。在數據傳輸端口的配置上,串口通信采用異步通信方式,支持數據幀結構,即每個數據包由起始位、數據位、校驗碼、停止位等幾部分組成,以確保數據傳輸的穩定性和可靠性。同時,上位機還實現了數據的動態顯示和歷史數據的查詢導出功能,以方便用戶對農田環境數據進行分析和處理。
四、上位機源碼實現
以下是Qt串口讀取數據的實現代碼:
#include
#include
#include
#include
?
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
?
QSerialPort serial;
serial.setPortName("COM1"); // 根據實際情況設置端口號
if (!serial.open(QIODevice::ReadWrite)) { // 打開串口
qDebug() << "Failed to open serial port!";
return 1;
}
?
// 設置串口參數
serial.setBaudRate(QSerialPort::Baud115200);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
serial.setStopBits(QSerialPort::OneStop);
serial.setFlowControl(QSerialPort::NoFlowControl);
?
while (true) {
if (serial.waitForReadyRead(1000)) { // 等待數據
QByteArray data = serial.readAll(); // 讀取所有數據
qDebug() << "Received data:" << data; // 打印所有數據
?
// 解析數據
QStringList dataList = QString(data).split(",");
if (dataList.size() == 4) {
float temperature = dataList[0].toFloat();
float humidity = dataList[1].toFloat();
float illumination = dataList[2].toFloat();
float soilMoisture = dataList[3].toFloat();
?
// 打印解析后的數據
qDebug() << "Temperature:" << temperature << "°C";
qDebug() << "Humidity:" << humidity << "%";
qDebug() << "Illumination:" << illumination << "lux";
qDebug() << "Soil Moisture:" << soilMoisture << "%";
}
}
}
?
return a.exec();
}
讀取數據時,采用了waitForReadyRead函數等待串口數據到達,該函數的參數表示最長等待時間,單位為毫秒。在解析數據時,使用了QString的split函數將數據按逗號分隔為多個字符串,再分別轉換為對應的浮點數。
五、CC2530設備端源碼
【1】BH1750數據讀取
以下是CC2530單片機讀取BH1750光敏傳感器的值并打印到串口的代碼:
#include "hal_board_cfg.h"
#include "hal_types.h"
#include "hal_defs.h"
#include "hal_uart.h"
#include "onboard.h"
#include "hal_i2c.h"
?
#define BH1750_ADDR 0x23 // BH1750默認地址
?
void initUART();
void sendStr(char *str);
void BH1750_init();
uint16 BH1750_read();
?
void main()
{
// 初始化
halBoardInit();
initUART();
BH1750_init();
?
while (TRUE)
{
// 讀取傳感器數據
uint16 illumination = BH1750_read();
char str[16];
sprintf(str, "%d", illumination);
?
// 將數據打印到串口
sendStr(str);
?
// 延時等待1秒
halMcuWaitMs(1000);
}
}
?
void initUART()
{
HAL_UART_CFG_T uartCfg;
?
uartCfg.baudRate = HAL_UART_BR_115200;
uartCfg.flowControl = FALSE;
uartCfg.parity = HAL_UART_PARITY_NONE;
uartCfg.stopBits = HAL_UART_STOP_BITS_1;
uartCfg.startGuardTime = 0;
?
HalUARTInit();
HalUARTOpen(HAL_UART_PORT_0, &uartCfg);
}
?
void sendStr(char *str)
{
while (*str != '\\0')
{
HalUARTWrite(HAL_UART_PORT_0, (uint8*)str, 1);
str++;
}
?
HalUARTWrite(HAL_UART_PORT_0, (uint8*)"\\r\\n", 2);
}
?
void BH1750_init()
{
uint8 pBuf[2];
?
pBuf[0] = 0x01; // 開始測量命令
halI2CWrite(BH1750_ADDR, pBuf, 1);
?
pBuf[0] = 0x10; // 分辨率設置為1lx
halI2CWrite(BH1750_ADDR, pBuf, 1);
}
?
uint16 BH1750_read()
{
uint8 pBuf[2];
?
halI2CRead(BH1750_ADDR, pBuf, 2);
?
uint16 illumination = (pBuf[0] << 8) | pBuf[1];
?
return illumination;
}
上述代碼中,initUART函數用于初始化串口,sendStr函數用于將字符串打印到串口。BH1750_init函數用于初始化BH1750傳感器,包括發送開始測量指令和設置分辨率為1lx等操作。BH1750_read函數用于讀取傳感器數據并計算出光照強度值。在main函數中,使用了一個while循環不斷從傳感器讀取數據,并通過串口打印輸出。代碼中的延時函數halMcuWaitMs是CC2530提供的延時函數,可以使用其他方式實現延時等待功能。
【2】DHT11溫濕度數據讀取
以下是CC2530單片機讀取DHT11傳感器的溫度和濕度并打印到串口的代碼:
#include "hal_types.h"
#include "hal_board.h"
#include "hal_uart.h"
?
#define DHT11_PORT 1 // DHT11連接到P1口
?
// 發送一個DHT11開始信號
void DHT11_Start(void) {
// 設置引腳為輸出模式
P1SEL &= ~(1 << DHT11_PORT);
P1DIR |= (1 << DHT11_PORT);
?
// 拉低引腳
P1_1 = 0;
?
// 等待至少18ms
HalDelayMs(18);
?
// 拉高引腳
P1_1 = 1;
?
// 等待20~40us,并切換到輸入模式
HalDelayUs(30);
P1DIR &= ~(1 << DHT11_PORT);
}
?
// 等待DHT11響應信號
uint8 DHT11_WaitResponse(void) {
uint8 timeOut = 0;
while(P1_1 && timeOut < 200) { // 等待低電平出現,超時返回1
HalDelayUs(1);
timeOut++;
}
if(timeOut >= 200) return 1;
?
timeOut = 0;
while(!P1_1 && timeOut < 200) { // 等待高電平出現,超時返回1
HalDelayUs(1);
timeOut++;
}
if(timeOut >= 200) return 1;
?
return 0;
}
?
// 讀取一個位
uint8 DHT11_ReadBit(void) {
uint8 timeOut = 0;
while(P1_1 && timeOut < 200) { // 等待低電平出現,超時返回1
HalDelayUs(1);
timeOut++;
}
?
timeOut = 0;
while(!P1_1 && timeOut < 200) { // 等待高電平出現,超時返回1
HalDelayUs(1);
timeOut++;
}
?
HalDelayUs(40); // 等待40us
?
if(P1_1) return 1; // 如果在40us內未出現低電平,返回1,表示數據錯誤
?
return 0;
}
?
// 讀取一個字節
uint8 DHT11_ReadByte(void) {
uint8 byte = 0;
uint8 i;
for(i=0;i<8;i++) {
byte <<= 1;
byte |= DHT11_ReadBit();
}
return byte;
}
?
// 從DHT11讀取溫度和濕度數據
void DHT11_ReadData(uint8* temperature, uint8* humidity) {
uint8 data[5];
?
// 發送開始信號
DHT11_Start();
?
// 等待響應信號
if(DHT11_WaitResponse()) {
*temperature = 0;
*humidity = 0;
return;
}
?
// 讀取數據
data[0] = DHT11_ReadByte(); // 濕度整數部分
data[1] = DHT11_ReadByte(); // 濕度小數部分
data[2] = DHT11_ReadByte(); // 溫度整數部分
data[3] = DHT11_ReadByte(); // 溫度小數部分
data[4] = DHT11_ReadByte(); // 校驗和
?
// 計算校驗和
uint8 sum = data[0] + data[1] + data[2] + data[3];
if(sum != data[4]) {
*temperature = 0;
*humidity = 0;
return;
}
?
// 計算溫度和濕度
*humidity = data[0];
*temperature = data[2];
}
?
// 初始化串口
void UART_Init(void) {
HalUARTInit();
HalUARTCfg_t uartConfig;
uartConfig.configured = TRUE;
uartConfig.baudRate = HAL_UART_BR_115200;
uartConfig.flowControl = FALSE;
uartConfig.flowControlThreshold = 64;
// 設置串口傳輸格式
uartConfig.rx.maxBufSize = 128;
uartConfig.tx.maxBufSize = 128;
uartConfig.idleTimeout = 6;
uartConfig.intEnable = TRUE;
uartConfig.callBackFunc = NULL;
HalUARTOpen(HAL_UART_PORT_0, &uartConfig);
}
?
// 打印溫度和濕度到串口
void PrintData(uint8 temperature, uint8 humidity) {
char buf[32];
sprintf(buf, "Temperature: %dC, Humidity: %d%%\\r\\n", temperature, humidity);
HalUARTWrite(HAL_UART_PORT_0, (uint8*)buf, strlen(buf));
}
?
void main(void) {
uint8 temperature, humidity;
?
// 初始化串口
UART_Init();
?
while(1) {
// 從DHT11讀取數據
DHT11_ReadData(&temperature, &humidity);
?
// 打印數據到串口
PrintData(temperature, humidity);
?
// 等待1秒鐘
HalDelayMs(1000);
}
}
這段代碼使用CC2530單片機通過DHT11傳感器讀取環境溫度和濕度,并將其打印到串口。具體實現過程為,首先發送一個開始信號,等待DHT11響應信號后,依次讀取濕度整數、濕度小數、溫度整數、溫度小數和校驗和。判斷校驗和是否正確后,計算得到溫度和濕度,并通過串口輸出。為了保證數據的準確性,每次讀取數據前需要等待1秒鐘。
審核編輯:湯梓紅
-
單片機
+關注
關注
6056文章
44800瀏覽量
643685 -
控制系統
+關注
關注
41文章
6734瀏覽量
111541 -
物聯網
+關注
關注
2921文章
45598瀏覽量
384061 -
CC2530
+關注
關注
19文章
221瀏覽量
58576 -
智慧農業
+關注
關注
4文章
807瀏覽量
20192
發布評論請先 登錄
相關推薦

基于CC2530的滑坡監測系統設計

cc2530的PWM實現

cc2530是什么_cc2530能做什么
cc2530芯片有哪些功能
CC2530的數據手冊和CC2530的應用手冊免費下載

CC2530芯片的基本特性和CC2530無線模塊的設計

評論