1.知識百科
智慧灌溉是運用物聯網、云計算、大數據等新一代信息技術,結合農業生產的實際需求,通過傳感器采集土壤溫濕度、光照強度等信息,利用無線傳感網絡傳輸到中央控制系統進行智能控制。智慧灌溉系統由傳感器(水位傳感器)、無線通信模塊(GPRS/CDMA/WLAN/藍牙)和計算機組成;在農業生產中,通過自動感知環境信息(溫度、濕度),實時監控作物生長狀況并做出判斷和決策。
2.開發環境
??本次智慧灌溉平臺包含有硬件和軟件兩部分。其中硬件部分有 基于STM32的主控制器,USB接口水泵、稻田模型、水位監測傳感器,硬件配置如下所所示:
主控制器
稻田模型
??稻田模型中添加了水位監測傳感器設備。
水泵
應用APP
3.硬件設計
4.軟件設計
??本次硬件主控MCU選擇的是ST公司的基于Cortex-M3架構的STM32F103C8T6,供電部分是12V轉5V,采用MP2359實現,5V轉3.3V則采用AMS1117-3.3實現。軟件設計通過HAL庫+KEIL軟件。
主控MCU: STM32F103C8T6
通信設備: ESP8266WIFI
傳感器設備: 水位檢測傳感器
水泵: USB接口3W水泵
其他: RGB工作狀態指示、串口調試接口、ST_Link下載口
4.1 ESP8266WIFI驅動
??ESP8266系列無線模塊是一個經濟高效的WIFI SOC模塊,支持標準IEEE802.11b/g/n協議,內置完整的TCP/IP協議棧。 用戶可以使用此系列模塊向現有設備添加網絡功能,也可以構建獨立的網絡控制器。
支持STA、AP、STA+AP動作模式;
體積非常小的802.11b/g/n WiFi SOC模塊
內置10bit高精度ADC采用低功率32位CPU,兼作應用程序處理器
支持USART、GPIO、IIC、PWM、ADC、SPI等接口時鐘頻率最大為160MHz
支持smart config、AirKiss一鍵網絡支持多個休眠模式,深休眠電流低到20uA
嵌入式LWIP協議棧
支持SDK二次開發
通用AT指令可以快速使用支持串行本地升級和遠程固件升級( FOTA )
本次采用通用AT指令開發,串口通信,波特率為115200,配置模式為AP+TCP服務器。
/*****************ESP8266初始化***************** **形參:u8 *wifi_name -- 熱點名稱 ** u8 *wifi_password -- 密碼 ** u16 port -- 端口號 ** **返回:0--成功,其他值 -- 失敗 const char *AP_TCPSERVER[]= { "ATrn",//測試指令 "ATE0rn",//關閉回顯 "AT+CWMODE=2rn",//--設置為AP(熱點)模式 "AT+RSTrn",//模塊重啟 "ATE0rn",//關閉回顯 "AT+CWSAP="EPS8266_123","01234567",1,4rn", //--設置wifi信息 "AT+CIPMUX=1rn",//設置多連接 "AT+CIPSERVER=1,10rn", //--設置TCP服務器模式,端口號(0~65535) "AT+CIFSRrn"http://查詢IP地址 }; ************************************************/ u8 Esp8266_AP_TcpServer_Init(u8 *wifi_name,u8 *wifi_password,u16 port) { char buff[100]; char *p=NULL; u8 i=0; printf("1.發送測試指令rn"); if(Esp8266_SendCmdCheckStat("ATrn","OKrn"))return 1; printf("2.關回顯rn"); if(Esp8266_SendCmdCheckStat("ATE0rn","OKrn"))return 2; printf("3.設置模式rn"); if(Esp8266_SendCmdCheckStat("AT+CWMODE=2rn","OKrn"))return 3; printf("4.模塊復位rn"); if(Esp8266_SendCmdCheckStat("AT+RSTrn","OKrn"))return 4; Delay_Ms(1000); Delay_Ms(1000); printf("5.關回顯rn"); if(Esp8266_SendCmdCheckStat("ATE0rn","OKrn"))return 5; //字符串拼接 snprintf(buff,sizeof(buff),"AT+CWSAP="%s","%s",1,4rn",wifi_name,wifi_password); printf("buff:%s",buff); printf("6.設置熱點信息rn"); if(Esp8266_SendCmdCheckStat(buff,"OKrn"))return 6; printf("7.設置多連接rn"); if(Esp8266_SendCmdCheckStat("AT+CIPMUX=1rn","OKrn"))return 7; printf("8.設置端口號rn"); snprintf(buff,sizeof(buff),"AT+CIPSERVER=1,%drn",port); if(Esp8266_SendCmdCheckStat(buff,"OKrn"))return 8; printf("9.查詢IP地址rn"); if(Esp8266_SendCmdCheckStat("AT+CIFSRrn","OKrn"))return 9; /*****提取IP地址信息*/ /*usart3:+CIFSR:APIP,"192.168.4.1" +CIFSR:APMAC,"86:f3:eb:a6:be:f9" OK */ p=strstr((char *)usart3_rx_buff,"APIP"); if(p!=NULL) { p+=6; while((*p!='"') && (*p!='')) { buff[i]=*p; p++; i++; } } buff[i]=''; printf("buff:%srn",buff); strcpy((char *)esp8266_info.esp8266_ip,buff);//IP地址 strcpy((char *)esp8266_info.esp8266_name,(char *)wifi_name);//wifi名稱 strcpy((char *)esp8266_info.esp8266_key,(char *)wifi_password);//wifi密碼 esp8266_info.esp8266_prot=port; return 0; }
4.2 水位監測傳感器
??本模塊工作電壓為5V,采用ADC方式采集液位值,原理為印刷電路板侵入水中,阻值會改變,通過測量阻值的變化來測量水位。
獲取水位值示例
u16 Get_Regular_Channelx(u16 ch) { ADC_ChannelConfTypeDef sConfig = {0}; sConfig.Channel=ch;//通道號 sConfig.SamplingTime=ADC_SAMPLETIME_239CYCLES_5;//采樣周期 if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)//ADC通道初始化 { Error_Handler(); } HAL_ADC_Start(&hadc1);//開啟ADC HAL_ADC_PollForConversion(&hadc1,20);//等待規則通道轉換完成 return HAL_ADC_GetValue(&hadc1); } //采集AD值,多次測量求平均值 int Get_WeatherVal() { u16 buffer[10]; u32 count=0; int i=0,j=0; u16 temp; for(i=0;i10;i++) { buffer[i]=Get_Regular_Channelx(ADC_CHANNEL_8);//100ms采集一次水位值 Delay_Ms(2); } for(i=0;i10-1;i++) { for(j=0;j10-1-i;j++) { if(buffer[j]?>buffer[j+1]) { temp=buffer[j]; buffer[j]=buffer[j+1]; buffer[j+1]=temp; } } } for(j=2;j8;j++) { count+=buffer[j]; } return (count/6); }
4.3 水泵驅動
??本次水泵選擇的是3W USB接口抽水電機,通過繼電器控制水泵啟動和關閉,配合上位機軟件和水位傳感器實時監測水位值實現電機自動啟動和停止工作。低電平啟動水泵工作,高電平停止水泵工作。
#define moto_ctl_start() HAL_GPIO_WritePin(moto_clt_GPIO_Port,moto_clt_Pin,GPIO_PIN_RESET) #define moto_ctl_stop() HAL_GPIO_WritePin(moto_clt_GPIO_Port,moto_clt_Pin,GPIO_PIN_SET)
4.4 核心控制功能
設備上電初始化WIFI,等待app連接。水位傳感器實時檢測當前水位狀態,通過APP啟動水泵抽水,當前水位值超過設定是閾值,則水泵自動停止工作。
板載RGB狀態指示燈。硬件電源檢測正常位紅色,WIFI工作工作則紅燈閃爍,APP連接成功則白燈閃爍,電機工作則綠燈閃爍。通過RGB燈光狀態即可得知當前設備工作狀態。
while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if(usart1_flag) { usart1_rx_buff[usart1_cnt]=''; printf("rx1=%s,%drn",usart1_rx_buff,usart1_cnt); usart1_cnt=0; usart1_flag=0; } if(usart3_flag) { usart3_rx_buff[usart3_cnt]=''; printf("rx3=%s,%drn",usart3_rx_buff,usart3_cnt); if(strstr((char *)usart3_rx_buff,"0,CONNECT")) { wifi_stat=1;//連接成功 time=0; stat=0; RGB_Ctl(0,0,0); snprintf(buff,sizeof(buff),"#%d,%d,%d",0,0,threshold_val%101); Esp8266_SendData(0,(u8*)buff);//發松數據到客戶端 } else if(strstr((char *)usart3_rx_buff,"0,CLOSED")) { wifi_stat=0;//斷開連接 time=0; stat=0; RGB_Ctl(0,0,0); moto_ctl_stop(); } else if(strstr((char *)usart3_rx_buff,"motor:1")) { wifi_stat=2;//啟動工作 time=0; stat=0; RGB_Ctl(0,0,0); moto_ctl_start(); motor_stat=1; } else if(strstr((char *)usart3_rx_buff,"motor:0")) { wifi_stat=1;//停止工作 time=0; stat=0; RGB_Ctl(0,0,0); moto_ctl_stop(); motor_stat=0; } else if(strstr((char *)usart3_rx_buff,"max:"))//水位閾值 { //+IPD,0,6:max:97,17 p=strstr((char *)usart3_rx_buff,"max:"); p+=strlen("max:"); threshold_val=atoi(p); //printf("threshold_val=%drn",threshold_val); } usart3_cnt=0; usart3_flag=0; } time++; time2++; time3++; Delay_Ms(1); if(wifi_stat==0 && time>=500)//應用app未連接(紅燈閃爍) { time=0; stat=!stat; if(stat) RGB_Ctl(200,0,0); else RGB_Ctl(0,0,0); } if(wifi_stat==1 && time>=500)//應用app連接成功(白燈閃爍) { time=0; stat=!stat; if(stat) RGB_Ctl(255,253,85); else RGB_Ctl(0,0,0); } else if(wifi_stat==2 && time>=500)//電機工作(綠燈閃爍) { time=0; stat=!stat; if(stat) RGB_Ctl(0,255,0); else RGB_Ctl(0,0,0); } if(time3>=100) { time3=0; data=Get_WeatherVal(); temp=data/3900.00*100; //printf("data=%.2f.%drn",temp,data); if((temp)>=threshold_val)//當前水位值超過設定閾值,則停止電機工作 { if(motor_stat==1) { time=0; stat=0; RGB_Ctl(0,0,0); moto_ctl_stop(); motor_stat=0;//關閉電機 wifi_stat=1; snprintf(buff,sizeof(buff),"#%d,%d,%d",motor_stat,threshold_val,threshold_val); Esp8266_SendData(0,(u8*)buff);//發松數據到客戶端 time2=0; } } } if(time2>=1000 && motor_stat==1 && wifi_stat>=1)//1s上報一次當前水位狀態,且需要再電機工作時進行上報 { time2=0; snprintf(buff,sizeof(buff),"#%d,%d,%d",motor_stat,((int)temp)%101,threshold_val%101); //printf("buff=%srn",buff); Esp8266_SendData(0,(u8*)buff);//發松數據到客戶端 } } /* USER CODE END 3 */ }
審核編輯 黃宇
-
傳感器
+關注
關注
2551文章
51089瀏覽量
753475 -
控制器
+關注
關注
112文章
16356瀏覽量
177999 -
物聯網
+關注
關注
2909文章
44631瀏覽量
373248
發布評論請先 登錄
相關推薦
評論