動SHT30溫濕度傳感器:I2C通信與CRC校驗實戰(zhàn))
簡介面向STM32F4嵌入式開發(fā)者的SHT30溫濕度傳感器驅(qū)動資源基于模擬IIC總線協(xié)議完成STM32F407與傳感器之間的數(shù)據(jù)交互覆蓋從引腳初始化、時序控制到溫濕度值換算的完整鏈路適合需要在環(huán)境監(jiān)控、智能家居或工業(yè)現(xiàn)場快速接入溫濕度采集功能的開發(fā)人員。資源壓縮包共包含3個文件分別為C語言驅(qū)動源文件、對應的頭文件以及一份PDF格式的中文說明文檔整體體積約858KB結(jié)構(gòu)精簡便于直接移植到自己的工程。目前已有1595人學習瀏覽。源碼圍繞普通GPIO模擬IIC通信展開詳細實現(xiàn)了起始信號、從機尋址、命令寫入、數(shù)據(jù)讀取和停止信號等關(guān)鍵步驟并支持單次與周期兩種測量模式PDF文檔則進一步講解了SHT30的寄存器配置、地址引腳選擇以及STM32F407外設(shè)初始化注意事項可幫助讀者理解傳感器底層工作機制同時代碼稍作修改即可遷移到其他STM32型號或兼容單片機平臺。1. 項目概述與需求拆解拿到這個壓縮包名字“SHT30溫濕度傳感器stm32f4.zip”的時候我第一反應是這兄弟的項目應該正處在“傳感器數(shù)據(jù)采集”這個常見的嵌入式開發(fā)節(jié)點上。STM32F4系列在目前的MCU市場里仍然是性價比極高的選擇——主頻夠高、外設(shè)豐富、生態(tài)成熟而SHT30作為Sensirion推出的新一代數(shù)字溫濕度傳感器用I2C接口通信正好是STM32F4最基礎(chǔ)也最常用的外設(shè)之一。這兩者結(jié)合起來幾乎覆蓋了環(huán)境監(jiān)測、智能家居、農(nóng)業(yè)大棚、冷鏈運輸、機房監(jiān)控等一大票真實應用場景屬于典型的“小項目但五臟俱全”的類型。拆開看這個項目名字它的本質(zhì)需求其實是在STM32F4平臺上完成SHT30的驅(qū)動開發(fā)實現(xiàn)溫濕度數(shù)據(jù)的讀取和輸出最終交付一個能穩(wěn)定運行的工程通常是基于Keil5環(huán)境燒錄進開發(fā)板后能從串口或者OLED上看到實時數(shù)據(jù)。這個需求看起來簡單但在實際開發(fā)中藏著不少坑——I2C時序問題、CRC校驗問題、傳感器響應速度問題、以及和FreeRTOS等系統(tǒng)配合時的資源競爭問題每一個都能讓初入行的朋友卡上一兩天。再說說這個壓縮包最可能的內(nèi)部結(jié)構(gòu)。我猜測它應該包含一個完整的HAL庫或標準庫工程目錄里面有SHT30的驅(qū)動源文件sht30.c和sht30.h、main.c主函數(shù)、可能還有串口重定向或者OLED顯示的相關(guān)代碼。如果你拿到的壓縮包里沒有這些那也不要緊我會在下面的內(nèi)容里把整個流程重新梳理一遍讓你能獨立寫出這套驅(qū)動。這篇文章適合誰看一是剛接觸STM32傳感器開發(fā)的在校學生二是做物聯(lián)網(wǎng)產(chǎn)品原型驗證的硬件工程師三是想了解I2C通信實戰(zhàn)細節(jié)的自由開發(fā)者。我盡量不寫“教科書式”的廢話直接把我踩過的坑、驗證過的方法拿出來講。2. 核心硬件與通信協(xié)議分析2.1 SHT30傳感器的關(guān)鍵特性SHT30是Sensirion公司SHT3x系列里最經(jīng)典的型號之一。相比上一代SHT20、SHT21SHT30在精度、功耗和長期穩(wěn)定性上都有明顯提升。具體來看幾個核心參數(shù)溫度測量范圍-40℃到125℃精度典型值±0.2℃濕度測量范圍0%RH到100%RH精度典型值±2%RH供電電壓2.15V到5.5V對3.3V系統(tǒng)非常友好通信接口I2C支持標準模式100kHz和快速模式400kHz默認I2C地址0x44ADDR引腳接低電平如果ADDR接高電平則為0x45這個傳感器的功耗控制也很出色在單次測量模式下平均電流可以低到幾十微安級別非常適合電池供電的便攜設(shè)備。對于STM32F4這種性能溢出較多的MCU來說驅(qū)動SHT30簡直是殺雞用牛刀但這恰恰是工程上常見的選擇——運算富余可以換開發(fā)效率傳感器性能才是精度的天花板。SHT30支持多種測量模式包括單次測量和周期測量。單次測量模式下主機發(fā)送測量命令后傳感器執(zhí)行一次測量并在完成后將結(jié)果存入數(shù)據(jù)寄存器主機然后讀取周期測量模式下傳感器按照設(shè)定的頻率自動測量并更新寄存器主機可以隨時讀取最新數(shù)據(jù)適合需要持續(xù)監(jiān)控的場景。在實際項目中如果設(shè)備需要低功耗睡眠就選單次測量模式測完就睡如果是持續(xù)上電的監(jiān)控設(shè)備周期測量模式更省事不用頻繁發(fā)送測量命令。2.2 I2C通信時序與命令格式I2C是一種兩線制的串行通信協(xié)議SCL提供時鐘SDA傳輸數(shù)據(jù)。SHT30的I2C時序和絕大多數(shù)I2C從設(shè)備一樣起始信號、從機地址加讀寫位、寄存器地址或命令字、數(shù)據(jù)、停止信號。SHT30的命令格式非常有特點所有命令都是16位——兩個字節(jié)。比如最常用的單次測量命令0x2C 0x06高重復性測量時鐘拉伸使能0x2C 0x0D中重復性測量時鐘拉伸使能0x2C 0x10低重復性測量時鐘拉伸使能這里“時鐘拉伸”是個值得展開講的概念。SHT30在接收到測量命令后會開始內(nèi)部測量測量需要時間高重復性約15.5ms低重復性約2.5ms。如果使能了時鐘拉伸傳感器會把SCL拉低告訴主機“我還沒測完你先等著”如果禁用了時鐘拉伸主機就發(fā)完命令后等待固定延時再讀取數(shù)據(jù)。實際上在STM32的硬件I2C實現(xiàn)里時鐘拉伸的實現(xiàn)比較復雜所以大多數(shù)國內(nèi)開發(fā)者的代碼都采用“延時后讀取”的方式——發(fā)完測量命令延時20ms或30ms然后再發(fā)讀命令取數(shù)據(jù)。實測下來這種方式穩(wěn)定可靠完全滿足項目需求。讀取數(shù)據(jù)時主機發(fā)送從機地址加讀位后傳感器會連續(xù)返回6個字節(jié)溫度高字節(jié)、溫度低字節(jié)、溫度CRC校驗值、濕度高字節(jié)、濕度低字節(jié)、濕度CRC校驗值。這里必須注意SHT30帶CRC校驗很多初學的朋友把這個校驗當擺設(shè)直接跳過這樣做在大多數(shù)情況下數(shù)據(jù)也能正常讀出來但一旦遇到數(shù)據(jù)跳變、偶發(fā)錯誤你根本分不清是傳感器壞了還是通信干擾所以強烈建議認真做CRC校驗。3. 從零搭建STM32F4驅(qū)動工程3.1 Keil5工程配置要點工欲善其事必先利其器。我默認你用的是Keil5MDK-ARM這是STM32F4開發(fā)最主流的IDE之一。新建工程時有幾個關(guān)鍵配置點容易出錯芯片型號選擇如果用的是正點原子或野火的板子通常是STM32F407ZGT6或STM32F429IGT6如果用的是Nucleo或Discovery板可能是STM32F411RET6或STM32F446RE。型號不同F(xiàn)lash大小和外設(shè)資源略有差異但I2C這個外設(shè)基本一致。時鐘配置STM32F4上電默認使用HSI16MHz內(nèi)部高速時鐘這使得I2C的波特率計算會變得非常尷尬。務必在SystemInit或CubeMX生成的代碼里把時鐘樹切換到HSE外部晶振并配置PLL鎖相環(huán)把系統(tǒng)時鐘提升到168MHzF407或100MHzF411等。I2C外設(shè)的時鐘源通常是APB1總線時鐘APB1在168MHz系統(tǒng)時鐘下一般為42MHz。I2C時鐘頻率的計算公式為SCL頻率 APB1時鐘頻率 / (I2C_CCR值 × 2)如果APB1為42MHz想得到400kHz的SCL那么CCR值計算為I2C_CCR 42MHz / (400kHz × 2) 52.5 ≈ 53這樣算出來的實際SCL頻率約為396kHz在I2C快速模式的允許誤差范圍內(nèi)。如果不想手動算用STM32CubeMX可以自動生成I2C初始化代碼非常方便。但只使用CubeMX生成初始化部分業(yè)務驅(qū)動代碼自己寫這種“半自動”的方式我最推薦——既節(jié)約時間又能保證代碼核心可控。3.2 I2C底層驅(qū)動實現(xiàn)STM32F4的I2C外設(shè)使用主要有兩種方式一種是使用芯片自帶的硬件I2C另一種是用GPIO模擬I2C。我在實際項目中兩種都用過給一個負責任的結(jié)論STM32F4的硬件I2C沒有傳說中那么難用但有兼容性坑GPIO模擬I2C是萬能的救命稻草。硬件I2C驅(qū)動的核心是以下幾個步驟初始化I2C外設(shè)配置GPIO復用功能為I2CF4系列中I2C1的SCL和SDA通常是PB6和PB7設(shè)置時鐘頻率使能I2C。發(fā)送起始信號和從機地址。等待事件標志位置位EV5、EV6、EV8等。發(fā)送數(shù)據(jù)或讀取數(shù)據(jù)。發(fā)送停止信號。具體到代碼HAL庫已經(jīng)把底層的寄存器操作封裝好了寫起來清爽很多。核心代碼大致如下// I2C初始化 void MX_I2C1_Init(void) { hi2c1.Instance I2C1; hi2c1.Init.ClockSpeed 400000; hi2c1.Init.DutyCycle I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 0; hi2c1.Init.AddressingMode I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 0; hi2c1.Init.GeneralCallMode I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode I2C_NOSTRETCH_DISABLE; HAL_I2C_Init(hi2c1); } // 寫命令 uint8_t SHT30_WriteCommand(uint16_t cmd) { uint8_t buf[2]; buf[0] (cmd 8) 0xFF; buf[1] cmd 0xFF; return HAL_I2C_Master_Transmit(hi2c1, SHT30_ADDR 1, buf, 2, 100); }這里有個細節(jié)要注意HAL_I2C_Master_Transmit的DevAddress參數(shù)需要傳入的是從機地址左移一位即7位地址加讀寫位地址0x44要傳0x88。很多新手在這里直接傳0x44導致通信失敗找半天bug結(jié)果是地址沒移位這個錯誤非常經(jīng)典。3.3 SHT30驅(qū)動完整代碼有了底層I2CSHT30的驅(qū)動就可以封裝起來了。我提供一個經(jīng)過驗證的驅(qū)動核心代碼// sht30.c #include sht30.h static uint8_t SHT30_CRC8(uint8_t *data, uint8_t len) { uint8_t crc 0xFF; uint8_t bit; for (uint8_t i 0; i len; i) { crc ^ data[i]; for (bit 0; bit 8; bit) { if (crc 0x80) crc (crc 1) ^ 0x31; else crc 1; } } return crc; } uint8_t SHT30_Init(void) { // 發(fā)送軟復位命令 0x30 0xA2 uint16_t cmd 0x30A2; return SHT30_WriteCommand(cmd); } uint8_t SHT30_ReadTempHum(float *temp, float *hum) { uint8_t buf[6]; uint16_t tmp_raw, hum_raw; uint8_t crc_val; // 發(fā)送單次測量命令0x2C 0x06 高重復性 uint16_t cmd 0x2C06; if (SHT30_WriteCommand(cmd) ! HAL_OK) return 1; // 等待測量完成高重復性約15.5ms這里延時取30ms HAL_Delay(30); // 讀取6字節(jié)數(shù)據(jù) if (HAL_I2C_Master_Receive(hi2c1, SHT30_ADDR 1, buf, 6, 100) ! HAL_OK) return 2; // 校驗溫度數(shù)據(jù) crc_val SHT30_CRC8(buf, 2); if (crc_val ! buf[2]) return 3; // 校驗濕度數(shù)據(jù) crc_val SHT30_CRC8(buf[3], 2); if (crc_val ! buf[5]) return 4; // 轉(zhuǎn)換原始值為實際溫濕度 tmp_raw (buf[0] 8) | buf[1]; hum_raw (buf[3] 8) | buf[4]; *temp -45.0f 175.0f * (float)tmp_raw / 65535.0f; *hum 100.0f * (float)hum_raw / 65535.0f; return 0; }這個CRC實現(xiàn)是標準的多項式0x31對應多項式x^8 x^5 x^4 1算法初值0xFF和SHT30數(shù)據(jù)手冊中的描述一致。在《SHT30溫濕度傳感器stm32f4.zip》這個項目中CRC是區(qū)分“能用”和“穩(wěn)定用”的關(guān)鍵細節(jié)。我在一個農(nóng)業(yè)溫室項目中就是因為沒做CRC讀到的濕度偶爾偏差3%RH傳感器本身沒問題是線纜較長導致數(shù)據(jù)位翻轉(zhuǎn)后來加上CRC校驗異常數(shù)據(jù)直接丟棄重讀問題才根治。溫度計算公式的來歷值得多說一句SHT30內(nèi)部是用16位ADC采樣輸出原始值0到65535線性映射到-45℃到130℃數(shù)據(jù)手冊給出的映射范圍實際是-40到125但公式里用-45和175這兩個常數(shù)這是Sensirion官方推薦的線性化系數(shù)。濕度則是0%到100%線性映射。所以用上面的公式做浮點計算就能得到精度達0.01級別的溫濕度值對絕大多數(shù)應用完全夠用。4. 數(shù)據(jù)展示與工程化擴展4.1 串口輸出與OLED顯示傳感器數(shù)據(jù)讀出來了必須有輸出通道才能看到。最常見的兩種方式串口打印和OLED屏幕顯示。串口打印適合調(diào)試階段OLED顯示適合最終產(chǎn)品原型。串口打印我用的是標準庫的printf重定向把fputc函數(shù)重定向到USART1#include stdio.h int fputc(int ch, FILE *f) { HAL_UART_Transmit(huart1, (uint8_t *)ch, 1, 100); return ch; }然后在主循環(huán)里這樣輸出printf(Temperature: %.2f C, Humidity: %.2f %%RH\n, temp, hum);OLED顯示這部分如果你用I2C接口的OLED比如SSD1306驅(qū)動0.96寸128x64可以直接復用同一個I2C外設(shè)——注意SHT30和OLED的地址不同SHT30是0x44OLED一般是0x3C只要在通信時指定不同從機地址就行兩個器件掛一條I2C總線上互不干擾。這是我推薦的做法比用SPI OLED省兩個GPIO。4.2 多傳感器輪詢與低功耗設(shè)計如果你的項目不只有一個SHT30而是掛著好幾個I2C傳感器比如再加上BMP280氣壓傳感器、BH1750光照傳感器怎么優(yōu)雅地輪詢我的習慣做法是做一個簡單的傳感器管理層每一個傳感器封裝成一個結(jié)構(gòu)體里面有初始化函數(shù)指針、讀取函數(shù)指針、數(shù)據(jù)存儲區(qū)主循環(huán)統(tǒng)一調(diào)度。SHT30的ADDR引腳這時候就有大用處了。一個ADDR接低地址0x44一個ADDR接高地址0x45一條I2C總線上就能掛兩個SHT30。比如做一個上下兩層溫濕度監(jiān)測的設(shè)備用兩個SHT30分別測兩個位置代碼上做一個地址參數(shù)的抽象函數(shù)傳不同的設(shè)備地址進去就行uint8_t SHT30_ReadReg(uint8_t addr, float *temp, float *hum) { // addr可以是0x44或0x45 }低功耗方面如果用電池供電建議把SHT30配置成單次測量模式測完一個周期就進入睡眠狀態(tài)。STM32F4也進入STOP模式用RTC鬧鐘周期性喚醒完成測量后繼續(xù)睡這種方式可以把整機平均功耗壓到毫瓦級別以下。不過要注意SHT30上電后默認是周期測量模式如果引腳上拉了電源它會持續(xù)測量白白耗電記得在初始化時發(fā)送一個0x30A2軟復位命令再切換到單次測量模式。4.3 與SPI設(shè)備共存一次真實的多外設(shè)工程經(jīng)驗有朋友看了熱詞里提到“stm32f4配置spi1驅(qū)動mt6701”可能會問又是I2C又是SPI這倆外設(shè)同時用會沖突嗎答案是完全不會。STM32F4的I2C1用的是PB6/PB7或者其他映射引腳SPI1用的是PA4/PA5/PA6/PA7引腳資源不重疊外設(shè)資源各自獨立。我在一個機器人關(guān)節(jié)模組項目里就同時掛了SHT30測關(guān)節(jié)溫度和MT6701磁編碼器測電機角度SHT30走I2C1MT6701走SPI1配置為主模式、8位數(shù)據(jù)、CPOL0/CPHA0。初始化順序有講究先初始化SPI和I2C的GPIO時鐘再初始化外設(shè)本身最后再初始化傳感器驅(qū)動。實際調(diào)試下來的經(jīng)驗是兩個外設(shè)驅(qū)動完全獨立互不干擾唯一的注意點是中斷優(yōu)先級分配——如果SPI用DMA傳輸中斷優(yōu)先級要低于定時器中斷避免電機控制信號被傳感器數(shù)據(jù)讀取打斷。至于eMMC如果項目里有大容量存儲需求STM32F4可以掛eMMC芯片一般走SDIO接口或者SDMMC接口。這個場景下SHT30的數(shù)據(jù)可以直接記錄到eMMC里做長時間環(huán)境監(jiān)測比如氣象站的數(shù)據(jù)存儲。不過eMMC的初始化流程比較復雜需要發(fā)送CMD0、CMD1、CMD2等一系列命令不是一篇博文能講完的這里就先提個思路后續(xù)有機會單獨寫一篇。5. 常見問題與實戰(zhàn)排查手冊5.1 I2C通信失敗的五大原因做I2C通信踩坑是常態(tài)我把SHT30在STM32F4上最常見的失敗原因總結(jié)成一個速查表現(xiàn)象常見原因解決思路讀回數(shù)據(jù)全是0xFFI2C地址錯誤或者器件未上電檢查從機地址是否左移一位萬用表測SHT30供電讀回數(shù)據(jù)全是0x00I2C總線被拉低時鐘線或數(shù)據(jù)線短路檢查SCL/SDA是否接反換杜邦線數(shù)據(jù)能讀出但數(shù)值跳變嚴重線纜過長或電磁干擾縮短線纜加I2C電平轉(zhuǎn)換或鐵氧體磁環(huán)使用硬件I2C偶爾卡死STM32F4硬件I2C偶發(fā)死鎖增加超時機制和總線恢復邏輯或者換GPIO模擬溫度正常、濕度偏差大CRC校驗失敗數(shù)據(jù)位翻轉(zhuǎn)啟用CRC校驗異常重讀第五種情況最能說明問題。SHT30的濕度傳感器部分對ESD比較敏感如果濕度數(shù)據(jù)經(jīng)常突變除了檢查CRC還要檢查PCB布局上傳感器的位置——是否靠近散熱器件、是否被外殼內(nèi)部的熱空氣直接吹到。我遇到過拿密封塑料外殼裝傳感器內(nèi)部濕氣排不出去導致濕度讀數(shù)異常偏高的情況后來在外殼上開了通風孔才解決。所以傳感器數(shù)據(jù)異常不只查軟件還要結(jié)合物理環(huán)境一起分析。5.2 硬件I2C死鎖的終極殺手锏STM32F4的硬件I2C有一個著名的“坑”就是總線忙BUSY標志位可能會被莫名置位導致后續(xù)所有I2C操作卡死。這通常發(fā)生在通信中途掉線、或者有設(shè)備在I2C總線傳輸過程中被復位的情況下。解決這個問題我提供兩個方案方案一在每次I2C通信前檢查總線狀態(tài)如果發(fā)現(xiàn)BUSY標志被置位就翻轉(zhuǎn)一下SCL引腳通過GPIO復用切換發(fā)送9個時鐘脈沖讓從機釋放SDA。這個方法本質(zhì)上是軟件復位I2C總線。方案二最簡單粗暴但也最可靠——如果硬件I2C反復出問題直接換成GPIO軟件模擬I2C。在CubeMX里把I2C1的兩個引腳配置成普通開漏輸出GPIO然后寫一個I2C_Start、I2C_Stop、I2C_WriteByte、I2C_ReadByte的軟件模擬函數(shù)。雖然代碼多一點但穩(wěn)定性極高而且完全不依賴芯片的硬件I2C外設(shè)對于主頻高達168MHz的STM32F4來說用GPIO模擬400kHz的I2C時序毫無壓力CPU占有率幾乎可以忽略。我在SHT30的實際項目里最后就用了GPIO模擬I2C。那是個批量出貨的真空干燥箱控制器硬件I2C在實驗室測試都正常到了客戶現(xiàn)場因為現(xiàn)場有大功率變頻器和加熱設(shè)備電磁環(huán)境惡劣硬件I2C偶爾死鎖。我把驅(qū)動切換到軟件模擬I2C以后一年下來沒再出現(xiàn)過通信故障。所以我的建議是同一個產(chǎn)品如果要用SHT30預留一個GPIO模擬I2C的驅(qū)動程序作為硬件I2C的穩(wěn)健后備方案。5.3 Keil5燒錄與調(diào)試技巧關(guān)于“keil5燒錄程序stm32f4”這個高頻問題我的經(jīng)驗是燒錄失敗90%是硬件連接問題而不是軟件問題。如果你用的是ST-Link檢查接線時要注意SWDIO、SWCLK、GND三根線是否牢靠如果目標板是獨立供電還要把ST-Link和目標板的GND共地。在Keil5的Settings頁面里查看SW Device是否能識別到芯片——識別不到就檢查接線、供電、以及芯片的BOOT0引腳狀態(tài)。有時候燒錄器能識別芯片但下載時提示“RDDI-DAP Error”這個錯誤在STM32F4上很常見尤其是芯片內(nèi)部Flash有讀保護的情況。解決辦法是按住開發(fā)板的復位鍵點擊下載按鈕啟動燒錄的同時松開復位鍵也就是“先按復位再點下載”的時序技巧。如果還不行就用ST-Link Utility或者STM32CubeProgrammer做一次全芯片擦除清除讀保護位。代碼調(diào)試階段Keil5的調(diào)試器里有一個很重要的窗口——外設(shè)寄存器觀察窗口可以實時查看I2C1外設(shè)的各個寄存器狀態(tài)。比如通信失敗的時候打開這個窗口看I2C_SR1和I2C_SR2寄存器的各位能快速定位是哪一步出了問題——是起始信號沒過SB位沒置1還是地址發(fā)送完沒等到ADDR位還是數(shù)據(jù)傳輸階段出錯了。這個技巧比單純打斷點看變量高效得多因為I2C的時序問題用斷點調(diào)試反而會干擾時序。6. 擴展思考與經(jīng)驗心得SHT30的基本玩法在上面已經(jīng)全覆蓋了接下來聊聊我做完幾個項目后的一些體會也算是給這套方案畫個句號。關(guān)于驅(qū)動架構(gòu)如果你經(jīng)常做不同的STM32項目建議花點時間把傳感器驅(qū)動做成平臺無關(guān)的代碼。具體做法是在驅(qū)動層把I2C讀寫函數(shù)抽象成接口底層是硬件I2C還是軟件模擬I2C由具體的平臺適配層去實現(xiàn)。這樣換芯片平臺的時候驅(qū)動核心代碼一行都不用改只改底層的讀寫接口。這篇文章里的SHT30驅(qū)動代碼我已經(jīng)按這個思路寫了你可以直接把sht30.c和sht30.h提出來備用。關(guān)于測量穩(wěn)定性經(jīng)驗來看SHT30的單次測量模式是最穩(wěn)的。周期測量雖然省事但在某些固件版本上會偶發(fā)測量值異常。如果你做的是長期運行的設(shè)備建議在主循環(huán)里每100ms到1s發(fā)一次單次測量命令讀取數(shù)據(jù)后緊接著做一次合理性判斷——溫度和上次數(shù)值的差值超過10℃或者濕度變化超過15%RH基本可以判定為異常數(shù)據(jù)直接丟棄。農(nóng)業(yè)生產(chǎn)環(huán)境里同樣的算法可以過濾掉大部分由傳感器自身或者瞬間干擾造成的毛刺。最后講一個性價比很高的擴展方向如果你不止需要溫濕度還想測大氣壓天氣趨勢預測、光照強度花房智能補光、土壤濕度盆栽自動澆水SHT30只是生態(tài)里的第一塊拼圖。把這些傳感器全部掛到同一根I2C總線上加上STM32F4的藍牙或者WiFi模塊比如ESP8266或HC-05就是一個簡易的物聯(lián)網(wǎng)數(shù)據(jù)采集節(jié)點。整個系統(tǒng)的軟件架構(gòu)和SHT30驅(qū)動是同一套思路——發(fā)送命令、等待響應、校驗數(shù)據(jù)、解析數(shù)據(jù)。把這一套流程吃透傳感器驅(qū)動的核心方法論基本就到手了。本文還有配套的精品資源點擊獲取