聚豐項(xiàng)目 > 遠(yuǎn)程蜂箱檢測(cè)系統(tǒng)
蜂蜜具有促進(jìn)消化,護(hù)膚美容,抗菌消炎,提高免疫力,入藥等作用,但是傳統(tǒng)蜂蜜的產(chǎn)量卻是有限的,因?yàn)橐爸蟹鋵?duì)生存環(huán)境也比較苛刻,野中蜂比較喜歡生存在干燥,通風(fēng),污染低,蜜源豐富的情況,溫度不宜過(guò)高,噪聲較小,沒(méi)有刺激性氣味的環(huán)境下,并且巢蟲(chóng)對(duì)蜂蜜的危害比較大,一般會(huì)附在蜂箱底部,如果生長(zhǎng)過(guò)多,就會(huì)趴在巢房上,像這種情況下,蜜蜂就會(huì)飛逃,或者出現(xiàn)其他環(huán)境不適合的情況下也會(huì)出現(xiàn)蜂群飛逃的情況,蜂蜜的質(zhì)量跟釀蜜的時(shí)間是成正比的,所以當(dāng)一年中出現(xiàn)蜜蜂飛逃會(huì)嚴(yán)重影響蜂蜜的質(zhì)量和產(chǎn)量。所以蜂農(nóng)一般過(guò)一段時(shí)間就會(huì)對(duì)蜜蜂的情況進(jìn)行檢查,但是由于時(shí)間或者距離等限制不能及時(shí)檢查,接下來(lái)就是我用所學(xué)知識(shí)對(duì)蜜蜂生存環(huán)境的檢測(cè),基于AB32VG1與VWXR2并搭載RT-Thread操作系統(tǒng)的遠(yuǎn)程蜂箱檢測(cè)系統(tǒng),使用DHT11對(duì)蜂箱內(nèi)的溫濕度進(jìn)行檢測(cè),判斷蜂箱是否淋雨,使用光敏電阻對(duì)蜂箱內(nèi)的亮度進(jìn)行檢測(cè),是HC-SR04對(duì)蜂箱底部進(jìn)行巢蟲(chóng)檢測(cè),并通VWXR2進(jìn)行遠(yuǎn)程的數(shù)據(jù)傳輸。然后在客戶(hù)端上查看蜂箱狀況。即使出差也不用擔(dān)心。
jf_15811252

jf_15811252
團(tuán)隊(duì)成員
理想三旬 嵌入式軟件工程師
RT-Thread使用情況概述:
整個(gè)方案涉及的技術(shù)棧有:主控選型、傳感器選型、IO口的分配 、操作系統(tǒng)的選擇與運(yùn)用、API 接口對(duì)接、wifi通信協(xié)議、整個(gè)系統(tǒng)的調(diào)試等等。通過(guò)這個(gè)作品,讓我對(duì)RT-Thread操作系統(tǒng)的框架,內(nèi)核啟動(dòng)流程等有了深刻的認(rèn)識(shí),對(duì)面對(duì)對(duì)象的編程手法有了更深的理解,實(shí)現(xiàn)對(duì)線程、信號(hào)量、互斥量靜態(tài)和動(dòng)態(tài)的創(chuàng)建和刪除與運(yùn)用,實(shí)現(xiàn)ADC、UARTD等設(shè)備的運(yùn)用。
內(nèi)核部分:使用了線程、信號(hào)量、定時(shí)器等
組件部分:Fish
軟件包:DHT11、HC-SR04
設(shè)備驅(qū)動(dòng):GPIO,ADC,UART等
硬件主要使用了AB32VG1開(kāi)發(fā)板,DHT11溫濕度模塊,HC-SR04模塊,MH檢測(cè)裝置,以及VWXR2三明治開(kāi)發(fā)板等(由于在實(shí)驗(yàn)室有些模塊沒(méi)有找到,如4G,聲音等,所以對(duì)項(xiàng)目進(jìn)行簡(jiǎn)化)。
I/O分配情況:

整個(gè)系統(tǒng)接線圖:
各個(gè)模塊簡(jiǎn)介:
AB32VG1:
CPU: AB5301A;( LQFP48 封裝,主頻 120M,片上集成 RAM 192K, flash 8 Mbit, ADCPWM, USB, UART, IIC 等資源).
搭載藍(lán)牙模塊,FM 模塊,一路 TF Card 接口,一路 USB 接口,一路 IIC 接口,一路音頻接口(美標(biāo) CTIA),六路 ADC 輸入引腳端子引出,六路 PWM 輸出引腳端子引出,一個(gè)全彩 LED 燈模塊, 一個(gè)電源指示燈, 三個(gè)燒錄指示燈,一個(gè) IRDA(紅外接收端口),一個(gè) Reset 按鍵, 三個(gè)功能按鍵(通用版為兩個(gè)功能按鍵)。主要功能是作為主控并且搭載RT-Thread操作系統(tǒng)實(shí)現(xiàn)實(shí)時(shí)性控制。
VWXR2:
內(nèi)置低功耗32位cpu,可兼做處理器,主頻最高支持380MHz
工作電壓:2.7-5.5V
外設(shè):9*GPIO,2*Uart,2*ADC
天線支持:板載+可選ipex
采樣率:16K/16bit
語(yǔ)音輸入:內(nèi)置2路音頻ADC,可直接模擬mic
音頻輸出:1路
板載音頻功放:最大支持2.6W
推薦喚醒距離:<=3m
默認(rèn)語(yǔ)音技能:天氣、百科、日歷、計(jì)算器、成語(yǔ)、翻譯、已支持音樂(lè)內(nèi)容點(diǎn)播支持線性雙MIC,間距靈活可調(diào)(>40mm),ID和MD結(jié)構(gòu)設(shè)計(jì)靈活,易集成.
主要功能是實(shí)現(xiàn)MCU與客戶(hù)端的連接,進(jìn)行數(shù)據(jù)交互。
DHT11:
DHT11數(shù)字溫濕度傳感器是一款含有已校準(zhǔn)數(shù)字信號(hào)輸出的溫濕度復(fù)合傳感器。單線通訊方式,測(cè)量精度不怎么樣。供電5v不然會(huì)出現(xiàn)意想不到的BUG.主要功能是實(shí)現(xiàn)蜂箱內(nèi)部的溫濕度采集,讓蜂農(nóng)看到蜂箱內(nèi)部的情況。
HC-SR04:
采用IO口TRIG觸發(fā)測(cè)距,給至少10us的高電平信號(hào);模塊自動(dòng)發(fā)送8個(gè)40khz的方波,自動(dòng)檢測(cè)是否有信號(hào)返回;有信號(hào)返回,通過(guò)IO口ECHO輸出一個(gè)高電平,高電平持續(xù)的時(shí)間就是超聲波從發(fā)射到返回的時(shí)間。測(cè)距范圍是2cm-400cm,值得注意的是,供電為5V,不然會(huì)出現(xiàn)采集數(shù)據(jù)不準(zhǔn)或者不能采集的情況。實(shí)現(xiàn)巢蟲(chóng)檢測(cè)。
MH采集:
即光照強(qiáng)度采集,模擬量輸出,能使數(shù)據(jù)的處理更靈活,實(shí)現(xiàn)蜂箱蓋的檢測(cè),由于蜜蜂是喜歡黑暗的環(huán)境,通過(guò)采集光敏電阻的值,并且有用戶(hù)設(shè)置亮度為多少時(shí)才觸發(fā)。
摘要:RT-Thread 是一個(gè)集實(shí)時(shí)操作系統(tǒng)(RTOS)內(nèi)核、中間件組件和開(kāi)發(fā)者社區(qū)于一體的技術(shù)平臺(tái),RT-Thread 也是一個(gè)組件完整豐富、高度可伸縮、簡(jiǎn)易開(kāi)發(fā)、超低功耗、高安全性的物聯(lián)網(wǎng)操作系統(tǒng)。RT-Thread 具備一個(gè) IoT OS 平臺(tái)所需的所有關(guān)鍵組件,例如GUI、網(wǎng)絡(luò)協(xié)議棧、安全傳輸、低功耗組件等等。經(jīng)過(guò)11年的累積發(fā)展,RT-Thread 已經(jīng)擁有一個(gè)國(guó)內(nèi)最大的嵌入式開(kāi)源社區(qū),同時(shí)被廣泛應(yīng)用于能源、車(chē)載、醫(yī)療、消費(fèi)電子等多個(gè)行業(yè),累積裝機(jī)量超過(guò) 8億 臺(tái),成為國(guó)人自主開(kāi)發(fā)、國(guó)內(nèi)最成熟穩(wěn)定和裝機(jī)量最大的開(kāi)源 RTOS。
RT-Thread 主要采用 C 語(yǔ)言編寫(xiě),淺顯易懂,方便移植。它把面向?qū)ο蟮脑O(shè)計(jì)方法應(yīng)用到實(shí)時(shí)系統(tǒng)設(shè)計(jì)中,使得代碼風(fēng)格優(yōu)雅、架構(gòu)清晰、系統(tǒng)模塊化并且可裁剪性非常好。針對(duì)資源受限的微控制器(MCU)系統(tǒng),可通過(guò)方便易用的工具,裁剪出僅需要 3KB Flash、1.2KB RAM 內(nèi)存資源的 NANO 版本(NANO 是 RT-Thread 官方于 2017 年 7 月份發(fā)布的一個(gè)極簡(jiǎn)版內(nèi)核);而對(duì)于資源豐富的物聯(lián)網(wǎng)設(shè)備,RT-Thread 又能使用在線的軟件包管理工具,配合系統(tǒng)配置工具實(shí)現(xiàn)直觀快速的模塊化裁剪,無(wú)縫地導(dǎo)入豐富的軟件功能包,實(shí)現(xiàn)類(lèi)似 Android 的圖形界面及觸摸滑動(dòng)效果、智能語(yǔ)音交互效果等復(fù)雜功能。其他的不說(shuō),就非常符合國(guó)人習(xí)慣,RT-Thread Studio 也好用,完善化的論壇,里面有個(gè)非常好用的功能就是對(duì)一個(gè)函數(shù)按CTRL鍵就會(huì)跳到相應(yīng)說(shuō)明的位置,還有中文的API參考手冊(cè)等諸多功能,對(duì)新手入門(mén)特友好。
VWXR2與MCU通信協(xié)議
1 串口通信約定
波特率:9600/115200
數(shù)據(jù)位:8
奇偶校驗(yàn):無(wú)
停止位:1
數(shù)據(jù)流控:無(wú)
MCU:用戶(hù)控制板控制芯片,與涂鴉模組通過(guò)串口進(jìn)行通信
2 幀格式說(shuō)明

? 所有大于 1 個(gè)字節(jié)的數(shù)據(jù)均采用大端模式傳輸。
? 一般情況下,采用同命令字一發(fā)一收同步機(jī)制。

? 模組控制命令下發(fā)及 MCU 狀態(tài)上報(bào)則采用異步模式,假設(shè)模組控制命令下發(fā)的命令字為
x,MCU 狀態(tài)上報(bào)的命令字為 y,如下所示:
?模組控制命令下發(fā)

? MCU 狀態(tài)上報(bào)

?數(shù)據(jù)類(lèi)型

在本項(xiàng)目中用到了raw(蜂箱蓋狀態(tài)),value(溫濕度,電源電壓值),bool(巢蟲(chóng)檢測(cè))以及defaut(開(kāi)發(fā)板狀態(tài))上報(bào)數(shù)據(jù)類(lèi)型。
/**
* @brief raw型dp數(shù)據(jù)上傳
* @param[in] {dpid} dpid號(hào)
* @param[in] {value} 當(dāng)前dp值指針
* @param[in] {len} 數(shù)據(jù)長(zhǎng)度
* @return Null
* @note Null
*/
unsigned char mcu_dp_raw_update(unsigned char dpid,const unsigned char value[],unsigned short len)
{
unsigned short send_len = 0;
if(stop_update_flag == ENABLE)
return SUCCESS;
//
send_len = set_wifi_uart_byte(send_len,dpid);
send_len = set_wifi_uart_byte(send_len,DP_TYPE_RAW);
//
send_len = set_wifi_uart_byte(send_len,len / 0x100);
send_len = set_wifi_uart_byte(send_len,len % 0x100);
//
send_len = set_wifi_uart_buffer(send_len,(unsigned char *)value,len);
wifi_uart_write_frame(STATE_UPLOAD_CMD,MCU_TX_VER,send_len);
return SUCCESS;
}
/**
* @brief bool型dp數(shù)據(jù)上傳
* @param[in] {dpid} dpid號(hào)
* @param[in] {value} 當(dāng)前dp值
* @return Null
* @note Null
*/
unsigned char mcu_dp_bool_update(unsigned char dpid,unsigned char value)
{
unsigned short send_len = 0;
if(stop_update_flag == ENABLE)
return SUCCESS;
send_len = set_wifi_uart_byte(send_len,dpid);
send_len = set_wifi_uart_byte(send_len,DP_TYPE_BOOL);
//
send_len = set_wifi_uart_byte(send_len,0);
send_len = set_wifi_uart_byte(send_len,1);
//
if(value == FALSE) {
send_len = set_wifi_uart_byte(send_len,FALSE);
}else {
send_len = set_wifi_uart_byte(send_len,1);
}
wifi_uart_write_frame(STATE_UPLOAD_CMD, MCU_TX_VER, send_len);
return SUCCESS;
}
/**
* @brief value型dp數(shù)據(jù)上傳
* @param[in] {dpid} dpid號(hào)
* @param[in] {value} 當(dāng)前dp值
* @return Null
* @note Null
*/
unsigned char mcu_dp_value_update(unsigned char dpid,unsigned long value)
{
unsigned short send_len = 0;
if(stop_update_flag == ENABLE)
return SUCCESS;
send_len = set_wifi_uart_byte(send_len,dpid);
send_len = set_wifi_uart_byte(send_len,DP_TYPE_VALUE);
//
send_len = set_wifi_uart_byte(send_len,0);
send_len = set_wifi_uart_byte(send_len,4);
//
send_len = set_wifi_uart_byte(send_len,value >> 24);
send_len = set_wifi_uart_byte(send_len,value >> 16);
send_len = set_wifi_uart_byte(send_len,value >> 8);
send_len = set_wifi_uart_byte(send_len,value & 0xff);
wifi_uart_write_frame(STATE_UPLOAD_CMD,MCU_TX_VER,send_len);
return SUCCESS;
}
/**
* @brief fault型dp數(shù)據(jù)上傳
* @param[in] {dpid} dpid號(hào)
* @param[in] {value} 當(dāng)前dp值
* @return Null
* @note Null
*/
unsigned char mcu_dp_fault_update(unsigned char dpid,unsigned long value)
{
unsigned short send_len = 0;
if(stop_update_flag == ENABLE)
return SUCCESS;
send_len = set_wifi_uart_byte(send_len,dpid);
send_len = set_wifi_uart_byte(send_len,DP_TYPE_BITMAP);
//
send_len = set_wifi_uart_byte(send_len,0);
if((value | 0xff) == 0xff) {
send_len = set_wifi_uart_byte(send_len,1);
send_len = set_wifi_uart_byte(send_len,value);
}else if((value | 0xffff) == 0xffff) {
send_len = set_wifi_uart_byte(send_len,2);
send_len = set_wifi_uart_byte(send_len,value >> 8);
send_len = set_wifi_uart_byte(send_len,value & 0xff);
}else {
send_len = set_wifi_uart_byte(send_len,4);
send_len = set_wifi_uart_byte(send_len,value >> 24);
send_len = set_wifi_uart_byte(send_len,value >> 16);
send_len = set_wifi_uart_byte(send_len,value >> 8);
send_len = set_wifi_uart_byte(send_len,value & 0xff);
}
wifi_uart_write_frame(STATE_UPLOAD_CMD, MCU_TX_VER, send_len);
return SUCCESS;
}
/**
* @brief 系統(tǒng)所有dp點(diǎn)信息上傳,實(shí)現(xiàn)APP和muc數(shù)據(jù)同步
* @param Null
* @return Null
* @note 此函數(shù)SDK內(nèi)部需調(diào)用,MCU必須實(shí)現(xiàn)該函數(shù)內(nèi)數(shù)據(jù)上報(bào)功能,包括只上報(bào)和可上報(bào)可下發(fā)型數(shù)據(jù)
*/
void all_data_update(void)
{
mcu_dp_raw_update(DPID_MEAL_PLAN,0,0); //當(dāng)前蜂箱狀況檢測(cè)指針,當(dāng)前蜂箱狀況檢測(cè)數(shù)據(jù)長(zhǎng)度RAW型數(shù)據(jù)上報(bào);
mcu_dp_value_update(DPID_BATTERY_PERCENTAGE,0); //當(dāng)前電池電量VALUE型數(shù)據(jù)上報(bào);
mcu_dp_bool_update(DPID_CHARGE_STATE,0); //當(dāng)前充電狀態(tài)BOOL型數(shù)據(jù)上報(bào);
mcu_dp_enum_update(DPID_COVER_STATE,0); //當(dāng)前蜂箱蓋狀態(tài)枚舉型數(shù)據(jù)上報(bào);
mcu_dp_fault_update(DPID_FAULT,0); //當(dāng)前故障告警故障型數(shù)據(jù)上報(bào);
mcu_dp_value_update(DPID_FEED_REPORT,0); //當(dāng)前檢測(cè)結(jié)果上報(bào)VALUE型數(shù)據(jù)上報(bào);
mcu_dp_value_update(DPID_VOICE_TIMES,0); //當(dāng)前語(yǔ)音播放次數(shù)VALUE型數(shù)據(jù)上報(bào);
mcu_dp_bool_update(DPID_LIGHT,0); //當(dāng)前小夜燈BOOL型數(shù)據(jù)上報(bào);
mcu_dp_value_update(DPID_NOW_TEMP,0); //當(dāng)前溫度檢測(cè)VALUE型數(shù)據(jù)上報(bào);
mcu_dp_value_update(DPID_HUM,90); //當(dāng)前濕度檢測(cè)VALUE型數(shù)據(jù)上報(bào);
mcu_dp_bool_update(DPID_CHECK,0); // 當(dāng)前巢蟲(chóng)檢測(cè) BOOL型數(shù)據(jù)上報(bào);
mcu_dp_value_update(DPID_LIGHT,0); //VALUE型數(shù)據(jù)上報(bào);
}調(diào)試:調(diào)試過(guò)程中我采用的是一個(gè)傳感器一個(gè)傳感器的調(diào),出錯(cuò)容易找,然后在進(jìn)行多個(gè)傳感器的融合
創(chuàng)建好工程后,編寫(xiě)按鍵(實(shí)現(xiàn)按鍵VWXR2復(fù)位與配網(wǎng)模式切換),LED(實(shí)現(xiàn)AB32VG1開(kāi)發(fā)板正常運(yùn)行觀察,避免出現(xiàn)卡死情況然后并不知道哪里出了問(wèn)題)功能。
//貼的主要代碼,全部代碼已經(jīng)放入gitee
static void key_thread_entry(void* p)
{
uint8_t byn_value = 0;
while(1)
{
byn_value = btn_scan(0);
switch(byn_value)
{
case KEY0_PRES:
rt_kprintf("key0 pushed\n");
mcu_reset_wifi();
rt_kprintf("mcu_reset_wifi\n");//使VWXR2開(kāi)發(fā)板復(fù)位,并進(jìn)入配網(wǎng)模式
break;
case KEY1_PRES:
rt_kprintf("key1 pushed\n");
mcu_set_wifi_mode(0);
rt_kprintf("smart_wifi_mode");//實(shí)現(xiàn)智能配網(wǎng)
break;
default:
break;
}
rt_thread_mdelay(100);
}
}
int rt_thread_key(void)
{
rt_thread_t key_ret = RT_NULL;
key_init();
key_ret = rt_thread_create("key", key_thread_entry, RT_NULL, 512, 9, 10);
if(key_ret == RT_NULL)
{
rt_kprintf("key init ERROR");
return RT_ERROR;
}
else {
rt_kprintf("rt_thread_key succeed....\n");
}
rt_thread_startup(key_ret);
}
INIT_APP_EXPORT(rt_thread_key);打開(kāi)調(diào)試助手觀察串口輸出情況

按下key0后VWXR2開(kāi)發(fā)板會(huì)播報(bào)“我已進(jìn)入配網(wǎng)狀態(tài),請(qǐng)下載APP為我完成配網(wǎng)”,演示如下:
2.DHT11調(diào)試與數(shù)據(jù)上報(bào)
在RT-Thread Setting中添加DHT11的sdk包,選擇第一個(gè)并保存

配置自己分配的引腳

刪掉SDK包中的void rt_hw_us_delay(rt_uint32_t us)函數(shù)
在board.c中添加自己的硬件定時(shí)器us函數(shù),uint8_t等會(huì)報(bào)錯(cuò),在前面加上rt_就可以了
void rt_hw_us_delay(rt_uint32_t us)
{
rt_uint32_t ticks;
rt_uint32_t told, tnow, tcnt = 0;
rt_uint32_t reload = TMR0PR;
ticks = us * reload / (1000);
told = TMR0CNT;
while (1)
{
tnow = TMR0CNT;
if (tnow != told)
{
if (tnow > told)
{
tcnt += tnow - told;
}
else
{
tcnt += reload - told + tnow;
}
told = tnow;
if (tcnt >= ticks)
{
break;
}
}
}
}觀察串口輸出

測(cè)試成功,在線程中添加數(shù)據(jù)上報(bào)代碼
#define DHT11_DATA_PIN GET_PIN(A, 0)
static void read_temp_entry(void *parameter)
{
rt_device_t dev = RT_NULL;
struct rt_sensor_data sensor_data;
rt_size_t res;
rt_uint8_t get_data_freq = 1; /* 1Hz */
dev = rt_device_find("temp_dht11");
if (dev == RT_NULL)
{
return;
}
if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK)
{
rt_kprintf("open device failed!\n");
return;
}
rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)(&get_data_freq));
while (1)
{
res = rt_device_read(dev, 0, &sensor_data, 1);
if (res != 1)
{
rt_kprintf("read data failed! result is %d\r\n", res);
rt_device_close(dev);
return;
}
else
{
if (sensor_data.data.temp >= 0)
{
uint8_t temp = (sensor_data.data.temp & 0xffff) >> 0; // get temp
uint8_t humi = (sensor_data.data.temp & 0xffff0000) >> 16; // get humi
rt_kprintf("temp:%d, humi:%d\n" ,temp, humi);
mcu_dp_value_update(DPID_NOW_TEMP,temp); //當(dāng)前溫度檢測(cè)VALUE型數(shù)據(jù)上報(bào);
mcu_dp_value_update(DPID_HUM,humi); //當(dāng)前濕度檢測(cè)VALUE型數(shù)據(jù)上報(bào);
}
}
rt_thread_delay(3000);
}
}
static int dht11_read_temp_sample(void)
{
rt_thread_t dht11_thread;
dht11_thread = rt_thread_create("dht_tem",read_temp_entry, RT_NULL,1024,13,20);
if(dht11_thread==RT_NULL)
{
rt_kprintf("dht11_thread fail....\n");
}
else {
rt_kprintf("dht11_thread succeed....\n");
}
rt_thread_startup(dht11_thread);
}
INIT_APP_EXPORT(dht11_read_temp_sample);
static int rt_hw_dht11_port(void)
{
struct rt_sensor_config cfg;
cfg.intf.user_data = (void *)DHT11_DATA_PIN;
rt_hw_dht11_init("dht11", &cfg);
return RT_EOK;
}
INIT_COMPONENT_EXPORT(rt_hw_dht11_port);打開(kāi)手機(jī)APP,觀察數(shù)據(jù)

app對(duì)溫度進(jìn)行了一個(gè)縮小10的處理
3.HC-SR04
添加SDK包,并且修改引腳,并進(jìn)行數(shù)據(jù)上報(bào)
#define SR04_TRIG_PIN GET_PIN(E, 0)
#define SR04_ECHO_PIN GET_PIN(A, 6)
int sr04_read_distance_sample(void);
int rt_hw_sr04_port(void);
static void sr04_read_distance_entry(void *parameter)
{
rt_device_t dev = RT_NULL;
struct rt_sensor_data sensor_data;
rt_size_t res;
rt_uint16_t distance=0;
dev = rt_device_find(parameter);
if (dev == RT_NULL) {
rt_kprintf("Can't find device:%s\n", parameter);
return;
}
if (rt_device_open(dev, RT_DEVICE_FLAG_RDWR) != RT_EOK) {
rt_kprintf("open device failed!\n");
return;
}
rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)100);
while (1) {
res = rt_device_read(dev, 0, &sensor_data, 1);
if (res != 1) {
rt_kprintf("read data failed!size is %d\n", res);
rt_device_close(dev);
return;
}
else {
distance=sensor_data.data.proximity / 10+sensor_data.data.proximity % 10;
if(distance>=20&&distance<=400)
//rt_kprintf("distance:%3d.%dcm, timestamp:%5d\n", sensor_data.data.proximity / 10, sensor_data.data.proximity % 10, sensor_data.timestamp);
if(distance>30)
mcu_dp_bool_update(DPID_CHECK,0); // 當(dāng)前巢蟲(chóng)檢測(cè) BOOL型數(shù)據(jù)上報(bào);
else {
mcu_dp_bool_update(DPID_CHECK,1); // 當(dāng)前巢蟲(chóng)檢測(cè) BOOL型數(shù)據(jù)上報(bào);
}
}
rt_thread_mdelay(2000);
}
}
int sr04_read_distance_sample(void)
{
rt_thread_t sr04_thread;
sr04_thread = rt_thread_create("sr04",
sr04_read_distance_entry,
"pr_sr04",
1024,
11,
20);
if (sr04_thread != RT_NULL) {
rt_thread_startup(sr04_thread);
}
return RT_EOK;
}
INIT_APP_EXPORT(sr04_read_distance_sample);4.AB32VG1與VWXR2之間的通信
#include"uart1.h"
/* 用于接收消息的信號(hào)量 */
static struct rt_semaphore rx_sem;
rt_device_t serial;
/* 接收數(shù)據(jù)回調(diào)函數(shù) */
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
/* 串口接收到數(shù)據(jù)后產(chǎn)生中斷,調(diào)用此回調(diào)函數(shù),然后發(fā)送接收信號(hào)量 */
rt_sem_release(&rx_sem);
return RT_EOK;
}
static void serial_thread_entry(void *parameter)
{
char ch;
rt_kprintf("test UART1 \n");
while (1)
{
/* 從串口讀取一個(gè)字節(jié)的數(shù)據(jù),沒(méi)有讀取到則等待接收信號(hào)量 */
while (rt_device_read(serial, -1, &ch, 1) != 1)
{
/* 阻塞等待接收信號(hào)量,等到信號(hào)量后再次讀取數(shù)據(jù) */
rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
}
uart_receive_input(ch);
}
}
static int uart_sample(int argc, char *argv[])
{
rt_err_t ret = RT_EOK;
char uart_name[RT_NAME_MAX];
char str[] = "hello RT-Thread!\r\n";
if (argc == 2)
{
rt_strncpy(uart_name, argv[1], RT_NAME_MAX);
}
else
{
rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);
}
/* 查找系統(tǒng)中的串口設(shè)備 */
serial = rt_device_find(uart_name);
if (!serial)
{
rt_kprintf("find %s failed!\n", uart_name);
return RT_ERROR;
}
/* 初始化信號(hào)量 */
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
/* 以中斷接收及輪詢(xún)發(fā)送模式打開(kāi)串口設(shè)備 */
rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
/* 設(shè)置接收回調(diào)函數(shù) */
rt_device_set_rx_indicate(serial, uart_input);
/* 發(fā)送字符串 */
rt_device_write(serial, 0, str, (sizeof(str) - 1));
/* 創(chuàng)建 serial 線程 */
rt_thread_t thread = rt_thread_create("serial", serial_thread_entry,
RT_NULL, 1024, 7, 10);
/* 創(chuàng)建成功則啟動(dòng)線程 */
if (thread != RT_NULL)
{
rt_kprintf("uart1_thread succeed....\n");
rt_thread_startup(thread);
}
else
{
ret = RT_ERROR;
}
return ret;
}
//在protel.c中添加單字節(jié)函數(shù),進(jìn)行數(shù)據(jù)的上報(bào)
/**
* @brief 串口發(fā)送數(shù)據(jù)
* @param[in] {value} 串口要發(fā)送的1字節(jié)數(shù)據(jù)
* @return Null
*/
void uart_transmit_output(unsigned char value)
{
rt_device_write(serial, 0,&value, 1);//單字節(jié)上報(bào)
}程序?qū)懞煤?,打開(kāi)涂鴉調(diào)試助手,選擇模擬模組,因?yàn)槲乙{(diào)試我寫(xiě)的程序是否和模組通信

VWXR2與串口接線如圖所示
![]()

當(dāng)調(diào)試助手出現(xiàn)下面這個(gè)界面時(shí),證明程序沒(méi)問(wèn)題,然后就可以和模組連接了

項(xiàng)目代碼地址:
https://gitee.com/AB32VG1/ab32.git