日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > > 嵌入式云IOT技術圈
[導讀]前陣子開源了一個基于TencentOS tiny物聯(lián)網(wǎng)操作系統(tǒng)的危險氣體探測儀項目,這次,我們再來開源一個新的項目-甲醛檢測儀,但是做項目之前,有必要了解下接下來要做的一些模塊以及如何來進行集成。

前陣子開源了一個基于TencentOS tiny物聯(lián)網(wǎng)操作系統(tǒng)的危險氣體探測儀項目,這次,我們再來開源一個新的項目-甲醛檢測儀,但是做項目之前,有必要了解下接下來要做的一些模塊以及如何來進行集成。

1、簡介

WZ-S型甲醛檢測模組是英國達特公司開發(fā)的,是用于將環(huán)境中甲醛的含量轉(zhuǎn)換成濃度值,標準化數(shù)字輸出,便于系統(tǒng)集成。

2、特點

3、典型應用場景

4、硬件引腳及技術指標

5、傳感器通訊協(xié)議

該傳感器采用的是串行通訊方式,也就是我們常用的串口,串口配置參數(shù)如下:

  • 波特率:9600

  • 數(shù)據(jù)位:8位

  • 停止位:1位

  • 校驗位:無

傳感器在出廠后默認為主動上報,每隔1s上報一次濃度值,命令行格式如下:

一般情況下我們直接拿來用即可。

6、軟件編程(以STM32為例)

以下開發(fā)板為TOS_EVB_GO開發(fā)板,也就是前陣子TencentOS公眾號發(fā)表的一篇文章的那個,鏈接如下:

基于TencentOS Tiny接入騰訊連連微信小程序,打造您自己的智能家居產(chǎn)品

TOS_EVB_G0 開發(fā)板是由騰訊TencentOS-tiny團隊設計的一款物聯(lián)網(wǎng)開發(fā)板,板載資源如下:

  • 主控芯片采用STM32G070RB,F(xiàn)lash空間僅有128KB、RAM空間僅有20KB;
  • 板載騰訊云定制固件版ESP8266 WIFI模組;
  • 板載E53傳感器標準接口,方便連接各種E53傳感器;
  • 板載0.91'OLED顯示屏幕;
  • 板載8MB SPI Flash,可用于固件升級;
  • 板載CH340 轉(zhuǎn)串口連接,可以使用一根USB線連接至電腦,查看串口日志;

基于該開發(fā)板編寫的達特傳感器驅(qū)動例程位于:

https://gitee.com/morixinguan/bear-pi.git

以上拓展模塊是騰訊基于E53接口設計的一個傳感器模塊,所以小熊派也是支持的,如下:


由于在小熊派上使用比較順手,所以現(xiàn)在我已經(jīng)對它愛不釋手了,無論是工作做實驗還是平時練習,以下配置、編程基于小熊派開發(fā)板。

6.1、STM32CubeMX關于傳感器的配置

配置DMA接收,個人習慣DMA+空閑中斷的方式。

6.2、其它配置
6.2.1 時鐘

6.2.2 SWD調(diào)試口

6.2.3 調(diào)試串口

6.2.4 SPI OLED配置

其余的部分直接復用之前文章的一些接口即可,然后生成工程:

6.3 程序編寫

在程序編寫之前先來了解一些基本的概念,有助于我們后面產(chǎn)品的實現(xiàn)。

(1)ppm、ppb、ppt是什么?

表達溶液的濃度時,1ppm=1ug/mL;表達固體中成分含量時,1ppm即為1ug/g或1g/t。

所以1ppb=1ppm的千分之一,ppm即百萬分之一,ppb即1億分之一,ppt即千億分之一。

所以ppm是10的-6次方,ppb是10的-9次方,ppt是10的-12次方

(2)濃度及濃度單位換算

1ppm = 1000ppb

1ppb ?= 1000ppt

ppm 即:mg/L(毫克/升)

ppm 即:mg/L(毫克/升)

ppm 即:mg/L(毫克/升)

6.3.1 達特傳感器通訊協(xié)議解析

由于達特甲醛傳感器出廠時固定是發(fā)9個字節(jié),所以我們可以直接用下面這個結構體來表示:

/*甲醛傳感器協(xié)議*/
typedef?struct
{
?/*起始位*/
?uint8_t?start_bit?;
?/*氣體名稱*/
?uint8_t?gas_name??;
?/*單位*/
?uint8_t?unit?;
?/*小數(shù)位數(shù)*/
?uint8_t?decimal_places?;
?/*氣體濃度高位*/
?uint8_t?gas_density_high?;
?/*氣體濃度低位*/
?uint8_t?gas_density_low?;
?/*滿量程高位*/
?uint8_t?full_range_high?;
?/*滿量程低位*/
?uint8_t?full_range_low?;
?/*校驗值*/
?uint8_t?checksum_value?;
}Dart_Sensor_Procol_TypeDef?;

針對以上結構體我們很容易根據(jù)官方手冊說明寫出如下解析函數(shù):

Dart_Sensor_Procol_TypeDef?Dart_Sensor_Data_Parse(uint8_t?*Data)
{
?uint16_t?temp?=?0?;
?uint16_t?check_sum?=?0?;
?uint16_t?check_sum_negate?=?0?;
?Dart_Sensor_Procol_TypeDef?dart_sensor?;
??/*將接收到的協(xié)議數(shù)據(jù)直接轉(zhuǎn)到結構體里進行存儲*/
?memcpy(&dart_sensor,Data,sizeof(Dart_Sensor_Procol_TypeDef));
??/*計算校驗值*/
?check_sum?=?dart_sensor.gas_name?+?dart_sensor.unit?+??????\
?dart_sensor.gas_density_low?+?dart_sensor.gas_density_high?+???\
?dart_sensor.full_range_high?+?dart_sensor.full_range_low?+?dart_sensor.decimal_places?;
?check_sum_negate?=?~check_sum?;
?temp?=?check_sum_negate?+?1?;
?if((temp?&?0xff)?!=?dart_sensor.checksum_value)?
?{
??memset(&dart_sensor,0,sizeof(Dart_Sensor_Procol_TypeDef));
??return?dart_sensor?;
?}
?return?dart_sensor?;
}

關于這個Data是怎么直接轉(zhuǎn)結構體的,可以參考我的一位朋友鄧工最近發(fā)表的一篇文章,里面圖文并茂的說明了這種騷操作,文章鏈接如下,點擊即可跳轉(zhuǎn):

【進階】"結構體嵌入共聯(lián)體"在協(xié)議解析中的神操作!

在用戶層次,用戶不需要關心協(xié)議是怎么解析的,所以我們只需要給用戶提供一個獲取數(shù)據(jù)的結構體和函數(shù)即可,然后通過頭文件dart_sensor.h提供給用戶,而協(xié)議解析部分直接放在dart_sensor.c文件里就可以了,如下:

#ifndef?__DART_SENSOR_H
#define?__DART_SENSOR_H
#include?
#include?
/*
1ppm?=?1000ppb
1ppb?=?1000ppt

ppm?=?mg/L(毫克/升)
ppb?=?ug/L(微克/升)
ppt?=?ng/L(納克/升)
*/

typedef?struct
{
?/*氣體濃度*/
?float?gas_density?;?//ppm
?/*滿量程*/
?float?full_range?;??
}Dart_Sensor?;


Dart_Sensor?Get_Dart_Sensor_Density(uint8_t?*Data);
#endif?//__DART_SENSOR_H

獲取濃度Get_Dart_Sensor_Density函數(shù)的實現(xiàn):

我看過的大多數(shù)濃度單位標識都是ppm,也就是xxx/mg/L的這種表示方法,所以這個接口就設計成下面這樣。

/*
?獲取氣體濃度
?Data:??傳感器數(shù)據(jù)
?return:?xxx?ppm
*/
Dart_Sensor?Get_Dart_Sensor_Density(uint8_t?*Data)
{
? Dart_Sensor?sensor?;
? Dart_Sensor_Procol_TypeDef?dart_sensor?;
? dart_sensor?=?Dart_Sensor_Data_Parse(Data);
??/*計算濃度,單位為ppm*/
? sensor.gas_density?=?((dart_sensor.gas_density_high?<??/*當前傳感器量程*/
? sensor.full_range??=?((dart_sensor.full_range_high?<? return?sensor?;
}

6.3.2 達特傳感器通訊庫封裝

既然用戶不需要關心過程,那我們可以給這個簡單的解析過程做一個lib,這樣就相當于一個模塊,提供.h和.lib即可,接下來建立一個STM32L431的工程,然后將.c和.h放在一個文件夾內(nèi),通過Keil包含進來


然后在Output下選擇創(chuàng)建庫,接下來點擊編譯即可生成:

注意,這里建立的這個庫僅在該環(huán)境下適用。思考一下,如何做到平臺通用呢?

6.3.3?案例編寫

(1)開啟串口空閑中斷

/*開啟空閑中斷*/
__HAL_UART_ENABLE_IT(uartHandle,?UART_IT_IDLE);
//開啟DMA接收
memset(sensor_handler.SensorU3Buffer,?0,?SENSOR_U3_BUFFER_SIZE);
HAL_UART_Receive_DMA(&huart3,?(uint8_t*)sensor_handler.SensorU3Buffer,?SENSOR_U3_BUFFER_SIZE);

(2)串口空閑中斷處理 串口接收數(shù)據(jù)結構:

//固定9個字節(jié)
#define?SENSOR_U3_BUFFER_SIZE???????9
typedef?struct
{
??/*表示接收到了*/
??uint8_t??BufferReady;
??/*數(shù)據(jù)緩存區(qū)*/
??uint8_t??SensorU3Buffer[SENSOR_U3_BUFFER_SIZE];
}Sensor_HandleTypeDef;
extern?Sensor_HandleTypeDef?sensor_handler?;

以下是數(shù)據(jù)采集過程,非常簡單:

/**
??*?@brief?This?function?handles?USART3?global?interrupt.
??*/
void?USART3_IRQHandler(void)
{
??/*?USER?CODE?BEGIN?USART3_IRQn?0?*/
?if(RESET?!=?__HAL_UART_GET_FLAG(&huart3,?UART_FLAG_IDLE))
??{
??????__HAL_UART_CLEAR_IDLEFLAG(&huart3);
???HAL_UART_DMAStop(&huart3);
???sensor_handler.BufferReady?=?1?;
??}
??/*?USER?CODE?END?USART3_IRQn?0?*/
??HAL_UART_IRQHandler(&huart3);
??/*?USER?CODE?BEGIN?USART3_IRQn?1?*/

??/*?USER?CODE?END?USART3_IRQn?1?*/
}

當接收到空閑中斷時,代表數(shù)據(jù)已經(jīng)接收到了,此時sensor_handler.BufferReady置1,代表數(shù)據(jù)已經(jīng)接收完成。

(3)數(shù)據(jù)解析處理與應用邏輯 在while循環(huán)中編寫如下代碼:

while?(1)
{
????/*接收到一幀數(shù)據(jù)*/
????if(1?==?sensor_handler.BufferReady)
????{
????????/*接收標志位清0*/
????????sensor_handler.BufferReady?=?0?;
????????/*判斷包頭數(shù)據(jù)是否正確*/
????????if(sensor_handler.SensorU3Buffer[0]?==?0xFF?&&?sensor_handler.SensorU3Buffer[1]?==?0x17)
????????{
????????????//調(diào)用解析函數(shù)
????????????sensor?=?Get_Dart_Sensor_Density(sensor_handler.SensorU3Buffer);
????????????/*業(yè)務邏輯開始*/
????????????sprintf(display_buf,?"%.3fmg/L",?sensor.gas_density);
????????????LCD_ShowCharStr(70,?100,?170,?display_buf,?BLACK,?WHITE,?24);
????????????/*業(yè)務邏輯結束*/
????????????
????????????//重新打開DMA繼續(xù)接收新的一幀數(shù)據(jù)
????????????memset(sensor_handler.SensorU3Buffer,?0,?SENSOR_U3_BUFFER_SIZE);
????????????HAL_UART_Receive_DMA(&huart3,?(uint8_t*)sensor_handler.SensorU3Buffer,?SENSOR_U3_BUFFER_SIZE);
????????}
????}
}

如何判斷接收到的這幀數(shù)據(jù)到底對不對呢?我們只需要根據(jù)協(xié)議手冊判斷前兩個字節(jié)是否為0xff和0x17即可。

7、運行結果

8、指標衡量

模塊咱們用起來了,如何判斷來衡量甲醛含量的技術指標呢?下面這張圖截的是淘寶上某個商家對檢測標準的說明:

9、思考與練習

前面我開源了一個基于TencentOS tiny的危險氣體探測儀項目,是否能在那個項目上稍微改改,變成一個新的產(chǎn)品級項目,讓一個新項目:甲醛探測儀迅速開發(fā)出來呢?

淘寶上其實已經(jīng)有很多優(yōu)秀的產(chǎn)品案例,如下所示,界面做得相當漂亮了:

是否能做出一個跟以上界面類似的開源項目呢?

如下圖所示,小熊派開源生態(tài)社區(qū)工作小組的阿正大佬已經(jīng)做出來了一個類似的作品,給他點贊!

同時也希望更多熱愛開源的小伙伴加入我們的小熊派開源生態(tài)社區(qū)工作小組,該工作小組為高質(zhì)量社區(qū),不同于一般群,只玩技術不閑聊,不接受潛水大佬,所以人不在多而在于精;無論小伙伴們玩的是什么平臺(不局限于小熊派),只要是熱愛開源,有創(chuàng)意有想法,樂于持續(xù)分享,且目前在碼云/Github等社區(qū)有作品的玩家即可(私聊我的微信,拉你入群)

本節(jié)代碼已同步到碼云的代碼倉庫中,獲取方法如下:

1、新建一個文件夾

2、使用git clone遠程獲取小熊派例程存放的代碼倉庫

項目開源倉庫:

https://gitee.com/morixinguan/bear-pi.git


我還將之前做的一些項目以及練習例程在近期內(nèi)全部上傳完畢,與大家一起分享交流:

公眾號粉絲福利時刻

這里我給大家申請到了福利,本公眾號讀者購買小熊派開發(fā)板可享受9折優(yōu)惠,有需要購買小熊派以及騰訊物聯(lián)網(wǎng)開發(fā)板的朋友,淘寶搜索即可,跟客服說你是公眾號:嵌入式云IOT技術圈?的粉絲即可。

往期精彩

C語言將xxx.bin文件轉(zhuǎn)為數(shù)組

開源STM32產(chǎn)品:無線點菜寶使用評測

C語言表驅(qū)動法編程實踐(精華帖,建議收藏并實踐)

分享一個在Keil開發(fā)環(huán)境中配置代碼格式化工具Astyle(美化代碼風格)

覺得本次分享的文章對您有幫助,隨手點[在看]并轉(zhuǎn)發(fā)分享,也是對我的支持。

免責聲明:本文內(nèi)容由21ic獲得授權后發(fā)布,版權歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當下,工業(yè)電機作為核心動力設備,其驅(qū)動電源的性能直接關系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護是驅(qū)動電源設計中至關重要的兩個環(huán)節(jié),集成化方案的設計成為提升電機驅(qū)動性能的關鍵。

關鍵字: 工業(yè)電機 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設備的使用壽命。然而,在實際應用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護成本,還影響了用戶體驗。要解決這一問題,需從設計、生...

關鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關鍵字: LED 設計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術之一是電機驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅(qū)動系統(tǒng)中的關鍵元件,其性能直接影響到電動汽車的動力性能和...

關鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設中,街道及停車場照明作為基礎設施的重要組成部分,其質(zhì)量和效率直接關系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關鍵字: LED照明技術 電磁干擾 驅(qū)動電源

開關電源具有效率高的特性,而且開關電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關鍵字: LED 驅(qū)動電源 開關電源

LED驅(qū)動電源是把電源供應轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關鍵字: LED 隧道燈 驅(qū)動電源
關閉