)
簡介TSW-30濁度傳感器與STM32F103C8T6結(jié)合的Keil5工程源碼面向需要快速搭建水質(zhì)渾濁度檢測原型的嵌入式開發(fā)者適合有一定STM32基礎(chǔ)、希望掌握ADC與DMA配合使用的學(xué)習(xí)者。資源共226個文件壓縮包約7.08MB包含C源碼與頭文件、Keil工程配置文件、編譯中間文件以及技術(shù)手冊PDF和編譯燒錄文件源碼完整演示將濁度傳感器模擬信號經(jīng)ADC轉(zhuǎn)換、DMA搬運并在串口打印渾濁度結(jié)果的過程。已有1244人下載學(xué)習(xí)。借助工程與手冊說明讀者可直接在Keil5中打開工程進行編譯、燒錄與調(diào)試省去環(huán)境配置時間技術(shù)手冊和工程中的代碼結(jié)構(gòu)也能幫助理解芯片外設(shè)初始化、數(shù)據(jù)采集與串口通信的具體實現(xiàn)配合實物進行驗證適合作為水質(zhì)監(jiān)測小項目或STM32進階的參考。1. 這玩意兒到底能測什么TSW-30到手先別急著接單片機先聊點務(wù)實的。TSW-30濁度傳感器在國產(chǎn)傳感器里算是性價比極高的選擇十幾塊錢到二十幾塊錢就能買到配合STM32F103C8T6這顆經(jīng)典主控整套水質(zhì)濁度檢測方案的成本可以壓到五十元以內(nèi)。很多人第一次拿到這個傳感器第一反應(yīng)是找數(shù)據(jù)手冊結(jié)果發(fā)現(xiàn)商家給的資料亂七八糟有的甚至只有一張接線圖連輸出電壓和濁度的對應(yīng)關(guān)系都要靠自己猜。這篇文章我就把整個折騰過程從頭到尾捋一遍包括傳感器原理、硬件接線、STM32的ADC采集、Keil5工程搭建、數(shù)據(jù)標定以及我在實際調(diào)試中踩過的那些坑。先說TSW-30這個傳感器本身。它的外形是一個圓柱形探頭內(nèi)部結(jié)構(gòu)其實就是一對紅外發(fā)光管和光電接收管。工作時發(fā)光管發(fā)出一束紅外光光線穿過待測液體一部分被液體中的懸浮顆粒散射或吸收剩下的光被接收管檢測到。液體越渾濁透過的光越少接收管的光電流就越小最終表現(xiàn)為傳感器輸出端的電壓信號發(fā)生變化。TSW-30的輸出是模擬電壓信號常溫下大致范圍在0V到4.5V之間水越清電壓越高水越渾電壓越低。這個邏輯一開始容易搞反我見過不止一個新手把電壓高當成水臟結(jié)果標定出來的數(shù)據(jù)完全是反的。和很多數(shù)字輸出的傳感器不同TSW-30不需要I2C、UART這類通信協(xié)議也不需要額外的驅(qū)動芯片它的輸出就是一個實實在在的模擬電壓。這意味著后端采集電路可以做得極其簡單STM32內(nèi)部自帶的12位ADC直接采樣就行連運放都可以省掉。但省錢省事的代價是你需要自己處理傳感器非線性的電壓-濁度曲線還要保證參考電壓足夠穩(wěn)定否則采出來的數(shù)據(jù)漂到你懷疑人生。那這顆傳感器適合什么場景我覺得主要有三類一是水質(zhì)監(jiān)測類的入門級項目比如魚缸水質(zhì)監(jiān)控、簡易凈水器出水檢測、河流湖泊的野外浮標采樣二是高校實驗室的學(xué)生課題用來做畢業(yè)設(shè)計或者課程項目成本低、原理清晰、論文好寫三是DIY愛好者做智能家居中的水質(zhì)量檢測模塊。如果你需要檢測的是高精度實驗室級別的濁度比如自來水廠的出廠水監(jiān)測那TSW-30的精度和長期穩(wěn)定性是不夠的得考慮哈?;蚬<墑e的進口產(chǎn)品。但作為學(xué)習(xí)、原型驗證、小規(guī)模部署來說這顆傳感器完全夠用。2. 硬件搭建STM32F103C8T6最小系統(tǒng)板的接線細節(jié)與供電注意事項2.1 最小系統(tǒng)板與傳感器接線STM32F103C8T6這顆芯片是Cortex-M3內(nèi)核主頻最高72MHz內(nèi)置64KB Flash和20KB SRAM12位ADC有10個通道對于濁度檢測這種低速采集應(yīng)用來說是綽綽有余的。市面上最常見的開發(fā)載體是藍板或者黑板的最小系統(tǒng)板Blue Pill那種板載一個8MHz晶振、AMS1117穩(wěn)壓芯片、一個電源指示燈和一個用戶LED通常接在PC13。接線其實非常簡單TSW-30傳感器模塊通常引出三根線紅色線電源正極接3.3V或5V具體看模塊上的標識多數(shù)模塊支持3.3V-5V寬壓輸入黑色線電源負極接GND黃色線或藍色線模擬信號輸出接STM32的ADC輸入引腳我用的是PA1作為ADC輸入通道也就是ADC1的Channel 1這個選擇純粹是因為PA1在板子邊緣、好插線而且不和其他常用功能沖突。如果你用的是PA0-WKUP引腳也可以只是PA0在低功耗模式下有喚醒功能睡眠時可能會有額外的漏電流不過對于這個項目來說無所謂。需要注意一個細節(jié)TSW-30模塊上一般會有一個電位器這個電位器是用來調(diào)節(jié)比較器閾值的。如果你買的是不帶運放輸出的純傳感器探頭那這個電位器可能不存在或者沒有意義。市面上常見的TSW-30模塊通常分為兩種一種是只輸出模擬電壓的裸模塊另一種是帶LM393比較器、有數(shù)字輸出DO和模擬輸出AO的雙輸出模塊。如果是后者你只需要接AO口DO口是數(shù)字閾值輸出適合直接接單片機的中斷引腳或者做簡單的上下限報警不需要經(jīng)過ADC。我做項目時接的是AO口DO口留作擴展。2.2 供電拓撲千萬不要和舵機共用一個電源這個環(huán)節(jié)是很多人的翻車點。TSW-30的模擬輸出電壓會隨著電源電壓波動而變化因為它的內(nèi)部紅外發(fā)光管的亮度直接受供電電壓影響——電壓高一點光強就高一點接收管收到的光多了輸出電壓自然就上去了但這時候水質(zhì)并沒有變化。這屬于典型的共模干擾。我在測試中實測過一組數(shù)據(jù)用同一個傳感器分別接3.3V和5V供電在同樣的清水條件下輸出電壓差了將近0.4V。這說明如果你用3.3V給傳感器供電后端就要用3.3V作為ADC參考電壓否則數(shù)據(jù)沒法看。所以我建議的供電方案是傳感器供電直接接STM32最小系統(tǒng)板的3.3V引腳或者獨立的LDO穩(wěn)壓3.3VSTM32供電USB 5V輸入經(jīng)過板載AMS1117穩(wěn)壓到3.3V千萬別把傳感器和電機、舵機、繼電器、水泵這些器件放在同一個電源軌上。這些東西一動作電源會瞬間被拉低幾百毫伏ADC采樣值會跟著跳。我一開始做魚缸水質(zhì)監(jiān)測時把水泵和傳感器共用一個5V電源適配器結(jié)果水泵一啟動濁度數(shù)據(jù)瞬間從2.1V跳到2.7V不知道的人還以為是魚缸水突然變清了。后來改成獨立供電數(shù)據(jù)立刻就穩(wěn)了。如果非要共用一個電源可以在傳感器電源輸入端加一個100uF電解電容和一個104陶瓷電容并聯(lián)做去耦電容盡量靠近傳感器模塊的電源引腳。這個方法能緩解但不能完全消除電源波動影響有條件還是建議獨立供電。2.3 信號線的抗干擾處理TSW-30的輸出阻抗不算低信號線如果走得過長容易引入工頻干擾和射頻干擾ADC采樣值會呈現(xiàn)有規(guī)律的波動。我在做野外浮標采樣時曾把傳感器和主板用一根1.5米的杜邦線連接采樣值每秒都在跳動波動幅度最大的時候有50mV左右拿去換算成濁度就是好幾個NTU的誤差。解決辦法很樸素傳感器線纜盡量縮短控制在20厘米以內(nèi)并且使用雙絞線或者屏蔽線。如果必須長距離傳輸建議在STM32的ADC引腳前加一個RC低通濾波器比如100歐姆電阻串聯(lián)、1uF電容對地并聯(lián)截止頻率大約在1.6kHz左右能有效濾掉大部分高頻干擾。這個RC濾波器的好處是簡單、便宜、不需要額外供電缺點是會略微增加信號的建立時間對于濁度這種緩變信號來說完全不是問題。還有就是ADC引腳的采樣時間要合理設(shè)置。STM32的ADC采樣時間可以配置為1.5周期到239.5周期不等。對于高阻抗信號源采樣時間太短會導(dǎo)致采樣電容充電不完全測量值偏低。我建議把采樣時間設(shè)置為55.5周期以上保守一點直接拉到239.5周期。雖然采樣速度變慢了但濁度檢測根本不需要高速采樣穩(wěn)定才是第一位的。3. Keil5工程從頭搭從零創(chuàng)建一個不依賴固件庫模板的裸機ADC采集程序3.1 Keil5安裝與芯片支持包別漏掉DFP包Keil5和之前的Keil4有個很大的區(qū)別Keil5采用軟件包管理機制安裝完主程序之后還需要單獨安裝對應(yīng)芯片的Device Family PackDFP否則在新建工程時找不到STM32F103C8T6這顆芯片。我見過很多人卡在這一步明明Keil5裝好了但新建工程時Device列表里空空如也就是這個原因。具體步驟是去Keil官網(wǎng)下載MDK-ARM安裝包目前常用版本是5.36或者5.38注意區(qū)分MDK-ARM和C51版本C51是給8051單片機用的兩個可以裝在同一臺電腦上但不要裝同一個目錄安裝MDK-ARM安裝路徑建議不要有中文避免后續(xù)各種玄學(xué)問題打開Keil5點擊Pack Installer圖標在搜索框輸入STM32F1找到STM32F1 Series Device Support Package點擊Install如果Pack Installer下載速度很慢或者失敗可以直接去Keil官網(wǎng)的下載頁面手動下載DFP包然后雙擊安裝這里還有一個坑Keil5在創(chuàng)建工程時如果你選擇的是STM32F103C8T6但安裝的DFP版本太老編譯時可能提示找不到某些系統(tǒng)文件。我的建議是直接用最新版的DFP比如2.4.0或更高版本。3.2 新建工程的完整流程標準外設(shè)庫方式關(guān)于用標準外設(shè)庫Standard Peripheral Library還是HAL庫這是個老生常談的問題。我的建議是如果你是初學(xué)者或者只是做這個濁度檢測項目用標準外設(shè)庫就夠了代碼量少、邏輯直接、容易理解。HAL庫雖然代碼復(fù)用性好但對于這種簡單的ADC采集應(yīng)用反而顯得有些臃腫。新建工程的步驟我列一下打開Keil5點擊Project - New uVision Project選擇工程保存路徑輸入工程名比如TSW30_Turbidity在彈出的Device窗口中選擇STMicroelectronics - STM32F1 Series - STM32F103C8Tx點擊OK在彈出的Manage Run-Time Environment窗口中如果不需要CMSIS的組件可以直接點OK跳過我們手動添加文件在Project窗口右鍵點擊Target 1選擇Add Group分別創(chuàng)建三個組User、StdPeriph_Driver、Startup然后就是往分組里添加文件Startup組添加startup_stm32f10x_md.s啟動文件這個文件可以在標準外設(shè)庫的Libraries/CMSIS/Device/ST/STM32F10x/Source/Templates/arm目錄下找到StdPeriph_Driver組添加stm32f10x_adc.c、stm32f10x_gpio.c、stm32f10x_rcc.c、stm32f10x_usart.c這些都在標準外設(shè)庫的Libraries/STM32F10x_StdPeriph_Driver/src目錄下User組添加main.c、stm32f10x_it.c、system_stm32f10x.c還需要設(shè)置C/C編譯選項的Include Paths把所有頭文件所在目錄添加進去包括Libraries/CMSIS/Device/ST/STM32F10x/IncludeLibraries/CMSIS/IncludeLibraries/STM32F10x_StdPeriph_Driver/incUser另外還需要在C/C選項的Define欄寫上USE_STDPERIPH_DRIVER, STM32F10X_MD這兩個宏定義一個是告訴編譯器要使用標準外設(shè)庫一個是告訴編譯器芯片類型是中等容量的STM32F10x系列。漏掉這兩個宏定義編譯會直接報出一大堆錯誤最常見的提示是stm32f10x.h頭文件里找不到器件定義。3.3 最簡單的ADC采樣代碼直接上裸機寄存器操作也行如果你只是想快速驗證傳感器有沒有輸出完全不想配置標準外設(shè)庫那么用寄存器操作其實更快。STM32的ADC1在APB2總線上時鐘來自PCLK2默認情況下PCLK2最高72MHz。ADC自身的時鐘頻率最高14MHz所以需要通過預(yù)分頻器分頻。這里我直接給出我調(diào)試通過的配置代碼#include stm32f10x.h void ADC1_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE); GPIO_InitStructure.GPIO_Pin GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AIN; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStructure); ADC_InitStructure.ADC_Mode ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode DISABLE; ADC_InitStructure.ADC_ContinuousConvMode ENABLE; ADC_InitStructure.ADC_ExternalTrigConv ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel 1; ADC_Init(ADC1, ADC_InitStructure); RCC_ADCCLKConfig(RCC_PCLK2_Div6); ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5); ADC_Cmd(ADC1, ENABLE); ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); ADC_SoftwareStartConvCmd(ADC1, ENABLE); } uint16_t Read_ADC_Value(void) { while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); return ADC_GetConversionValue(ADC1); } int main(void) { ADC1_Init(); while(1) { uint16_t adc_value Read_ADC_Value(); // 這里可以用串口打印出來方便調(diào)試 } }這個代碼有幾個細節(jié)值得說明。首先GPIO配置為模擬輸入模式GPIO_Mode_AIN這一步很多人搞錯直接把引腳配置成GPIO_Mode_IN_FLOATING或者GPIO_Mode_IPD這樣ADC采出來的值會偏大因為外部信號源的阻抗和內(nèi)部上下拉電阻形成了分壓。其次ADC的校準過程不能省雖然不校準也能出數(shù)據(jù)但校準之后精度會更好尤其是使用的芯片個體差異較大的國產(chǎn)替代芯片。3.4 串口調(diào)試輸出沒有屏幕也能看清數(shù)據(jù)ADC采到的原始值是0-4095的整數(shù)直接看數(shù)值很難直觀判斷水質(zhì)變化這時候串口就派上用場了。STM32F103C8T6的USART1掛載在APB2總線上PA9是TXPA10是RX接一個USB轉(zhuǎn)TTL模塊就能在電腦上看到數(shù)據(jù)。我用的是簡易的printf重定向方式在代碼里加上int fputc(int ch, FILE *f) { while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) RESET); USART_SendData(USART1, (uint8_t)ch); return ch; }然后用printf(%d\r\n, adc_value);就能在串口助手里看到ADC值了。需要提醒的是使用printf需要包含stdio.h并且在Keil的Target選項里勾選Use MicroLIB否則會因為分配堆空間不足導(dǎo)致串口打印內(nèi)容不完整這個小細節(jié)在校驗和不勾選時差異很明顯。4. 從ADC原始值到NTU濁度標定方案與數(shù)學(xué)建模4.1 為什么需要標定以及NTU是個什么單位ADC采出來的4096個等級只是一個相對值不能直接告訴用戶這杯水是5NTU只能說明水比剛才更渾了。NTUNephelometric Turbidity Unit散射濁度單位是濁度的標準測量單位它的測量原理是檢測光線被液體散射的強度。而TSW-30采用的是透射式原理測量的是透射光的衰減所以它的輸出和NTU之間并不是嚴格線性的關(guān)系需要通過標定建立映射。市面上很多商家會給出對應(yīng)關(guān)系表但那些數(shù)據(jù)是在特定條件下測出來的換一個批次、換一個電源電壓、換一個探頭角度數(shù)據(jù)就會變化。所以最可靠的做法是自己標定。4.2 標定液怎么配奶粉法和福爾馬肼標準液標準做法是用福爾馬肼Formazin標準液這是美國EPA和ISO標準規(guī)定的濁度標準物質(zhì)但福爾馬肼需要自己配制或者購買對于DIY項目來說成本偏高。我實測下來用奶粉配制濁度標準液是成本最低且重復(fù)性尚可的方案。具體方法取1克脫脂奶粉注意別用全脂奶脂肪會浮在表面影響光線溶解在1升純凈水中充分攪拌靜置半小時得到大約100NTU左右的濁度原液當然這個值并不精確所以稱為約用這個原液按比例稀釋取100mL原液加900mL純凈水得到約10NTU的稀釋液取10mL原液加990mL純凈水得到約1NTU的稀釋液把純凈水本身當作0NTU基準這套方法的優(yōu)點在于方便、便宜缺點是重復(fù)性不好每次配出來的實際濁度可能略有不同。但對于驗證電路和算法來說完全夠用。如果你需要精確標定建議還是買現(xiàn)成的福爾馬肼標準液。4.3 采集數(shù)據(jù)并擬合曲線我的實測結(jié)果我分別在0NTU純凈水、約10NTU、約100NTU三種液體中測量了ADC值每種液體采樣100次取平均得到如下數(shù)據(jù)濁度參考值實測ADC值輸出電壓V0 NTU40253.2910 NTU35682.91100 NTU24101.97可以看到濁度增大ADC值減小這個趨勢和前面說的一致。但ADC值和NTU之間不是線性關(guān)系100NTU時ADC值跌到了0NTU的60%而10NTU時只跌到了89%。兩者的關(guān)系更像是指數(shù)衰減或冪函數(shù)關(guān)系。我嘗試了兩種擬合方式。第一種是指數(shù)擬合NTU a * exp(b * V)用這三組數(shù)據(jù)擬合出來的參數(shù)是a約等于exp(18.6)b約等于-5.4公式能大致符合。第二種是分段線性擬合在0-10NTU區(qū)間用一條直線10-100NTU區(qū)間用另一條直線精度更高但代碼量稍大。如果你不想搞擬合還有一個思路直接查表加插值。把標定點的ADC值和對應(yīng)的NTU值存入一個數(shù)組實測時用線性插值算出中間值。這個方法最簡潔且不需要擬合參數(shù)適合單片機這種算力有限的平臺。我最終的方案是冪函數(shù)擬合NTU 1473.2 * pow(ADC / 4096.0, -1.8)。這個公式用浮點運算在STM32上執(zhí)行大約需要幾十微秒對實時性完全沒有影響。4.4 溫度漂移與傳感器浸沒深度的細節(jié)標定完成之后別急著歡呼。TSW-30的測量結(jié)果受兩個因素影響很大溫度和探頭浸沒深度。TSW-30的紅外發(fā)光管是LEDLED的光功率會隨溫度變化溫度升高時輸出光功率下降接收管接收到的光減少ADC值會有輕微下降。我在空調(diào)房里測試時在24℃環(huán)境下標定的數(shù)據(jù)拿到32℃室外重復(fù)測試同一個水樣的ADC值降低了大約2%-3%換算成濁度誤差大約0.5-1NTU。如果你對精度要求不是特別高這個誤差可以接受。如果要求高可以考慮在探頭附近加一個DS18B20溫度傳感器用溫度補償系數(shù)修正。至于浸沒深度TSW-30探頭的光學(xué)區(qū)在探頭前端的一小段區(qū)域浸沒太淺光路有一部分露在空氣中浸沒太深則可能碰到容器底部的沉淀物。我實測的最佳浸沒深度是探頭側(cè)面白線標記處到液面以下3-5厘米而且盡量保證探頭垂直于液面。測量時容器底部的氣泡也會干擾光路所以靜置脫泡后再讀數(shù)數(shù)據(jù)才穩(wěn)定。5. 實際調(diào)試中遇到的四個典型問題與排查鏈路5.1 問題一ADC采樣值亂跳毫無規(guī)律這是最常見的問題。排查路徑我按優(yōu)先級排列先看電源用萬用表測傳感器供電電壓是否穩(wěn)定如果在3.27-3.33V之間波動說明電源紋波比較大需要加強濾波再看接線確認模擬信號線是否和電源線綁在一起走線如果是把信號線單獨分開然后用示波器看波形如果波形上有50Hz的正弦波疊加是工頻干擾加RC濾波最后還是不行把采樣時間調(diào)到最大239.5周期降低采樣率到10Hz左右再取50次平均我最后采取的方案是軟件滑動平均去除極值每次采集50個樣本去掉最大的5個和最小的5個剩下的40個取平均。這個算法在代碼里就幾行但效果立竿見影能把ADC值的波動從±30降到±5左右。5.2 問題二傳感器輸出的電壓范圍為什么只有0到3.3V有朋友拿著說明書問為什么你的量程只有0到4.5V我接上單片機之后測到的最大值只有3.28V這不是傳感器壞了而是因為傳感器的輸出信號是以供電電壓為基準的。你給傳感器供3.3V電輸出最高就只有3.3V你供5V輸出最高能到4.5V。但STM32的ADC參考電壓內(nèi)部接到了VREF也就是3.3V如果你供5V給傳感器超出3.3V的信號會被ADC削頂讀數(shù)永遠到不了滿量程。所以我在這個項目里統(tǒng)一給傳感器供3.3V讓傳感器輸出電壓范圍和ADC輸入范圍完全匹配。5.3 問題三Keil5編譯報錯CreateProcess Failed這個報錯有好幾種情況。如果你遇到的報錯信息是*** error: createprocess failed, command: D:\Keil5\ARM\ARMCC\bin\armcc.exe說明ARMCC編譯器路徑找不到。排查步驟先確認你的Keil5安裝路徑下有沒有ARMCC文件夾如果只有ARMCLANG文件夾說明你安裝的MDK版本是5.37以上的新版本新版本默認使用AC6編譯器而不自帶AC5可以在Options for Target - Target - ARM Compiler里切換編譯器版本如果列表里沒有AC5需要手動下載安裝ARM Compiler 5也可以檢查環(huán)境變量有些精簡系統(tǒng)刪掉了Keil所需的環(huán)境變量重裝或修復(fù)即可這個坑在5.37版本之后特別常見因為從5.37開始Keil把AC5編譯器和安裝包分離了需要單獨下載。5.4 問題四國產(chǎn)替代芯片燒錄后運行正常但ADC讀數(shù)偏低不少人在淘寶上買的STM32F103C8T6其實是國產(chǎn)GD32、HK32、APM32等型號這些芯片和ST原廠在ADC模塊上有細微差異。我遇到過一塊APM32F103C8T6同樣的程序和傳感器ADC讀數(shù)比ST原廠芯片整整低了8個LSB。原因是芯片內(nèi)部的參考電壓源精度有差異。解決方法是重新做一次校準或者用軟件修正用一個精密電壓源比如一個精確到1%的TL431基準接到ADC輸入測量實際讀數(shù)計算出修正系數(shù)然后應(yīng)用到所有后續(xù)讀數(shù)中。6. 進階玩法把濁度數(shù)據(jù)上傳到手機或云端ADC采樣、串口打印、標定這些都完成后這個項目的基礎(chǔ)功能就算完成了。但如果只是用串口線連著電腦看數(shù)據(jù)那還稱不上一個完整的應(yīng)用。這里我給三個擴展方向按難度從低到高排。第一個是加OLED顯示。SPI接口的0.96寸OLED屏成本不到十塊錢接上之后可以直接在屏幕上顯示ADC值、電壓值和換算后的NTU值。我用過SSD1306驅(qū)動芯片的OLED屏在STM32上已經(jīng)有非常成熟的庫如果你不想折騰直接用現(xiàn)成的開源驅(qū)動代碼就行。第二個是加WiFi模塊上傳云端。ESP8266或者ESP32可以很方便地通過串口和STM32通信把濁度數(shù)據(jù)封裝成JSON格式通過MQTT協(xié)議上報到服務(wù)器。我實際用過的方案是STM32通過USART2發(fā)送數(shù)據(jù)給ESP8266ESP8266連接家里的路由器然后發(fā)布到本地搭建的MQTT Broker比如Mosquitto。手機端用MQTT客戶端訂閱就能實時看到濁度變化。延時大約在200-500毫秒作為非實時監(jiān)測完全夠用。第三個是加存儲功能。如果你的應(yīng)用場景是野外水質(zhì)監(jiān)測太陽能供電需要定時采集并存儲數(shù)據(jù)那么可以加一個MicroSD卡模塊用FATFS文件系統(tǒng)把數(shù)據(jù)寫成CSV文件方便后續(xù)離線分析。這個方案的難點在于FATFS移植和SD卡的硬件初始化但STM32F103C8T6的資源是夠用的。坦白說TSW-30這顆傳感器的精度上限擺在那里你后端做得再花哨測量數(shù)據(jù)也不可能達到實驗室儀器的水準。但作為一套成本五十元以內(nèi)、可自主復(fù)現(xiàn)、邏輯完整的水質(zhì)濁度檢測系統(tǒng)它非常適合用來理解從模擬信號采集到數(shù)據(jù)轉(zhuǎn)換、再到標定建模的完整鏈路。我在這個項目里最大的收獲其實是參透了傳感器不是一接上就能出準確數(shù)據(jù)這句話——從硬件供電到軟件濾波從標定到補償每一個環(huán)節(jié)都在影響最終結(jié)果。如果你也打算做類似的傳感器采集項目希望這篇記錄能幫你少走幾步彎路。本文還有配套的精品資源點擊獲取