0 前言
這兩年開(kāi)始畢業(yè)設(shè)計(jì)和畢業(yè)答辯的要求和難度不斷提升,傳統(tǒng)的畢設(shè)題目缺少創(chuàng)新和亮點(diǎn),往往達(dá)不到畢業(yè)答辯的要求,這兩年不斷有學(xué)弟學(xué)妹告訴學(xué)長(zhǎng)自己做的項(xiàng)目系統(tǒng)達(dá)不到老師的要求。
為了大家能夠順利以及最少的精力通過(guò)畢設(shè),學(xué)長(zhǎng)分享優(yōu)質(zhì)畢業(yè)設(shè)計(jì)項(xiàng)目,今天要分享的是
基于單片機(jī)的便攜式空氣質(zhì)量檢測(cè)儀
1、簡(jiǎn)介
基于IDT的便攜式無(wú)線(xiàn)供電空氣質(zhì)量檢測(cè)儀,隨著近些年環(huán)保問(wèn)題的日益嚴(yán)峻,身邊的朋友也越來(lái)越重視自己的生存環(huán)境,尤其是對(duì)空氣質(zhì)量的關(guān)注度日益增高。我就打算自己設(shè)計(jì)制作一套便攜式的空氣質(zhì)量檢測(cè)儀,采用無(wú)線(xiàn)供電的方式來(lái)運(yùn)行保證檢測(cè)儀的運(yùn)行,同時(shí)利用無(wú)線(xiàn)供電系統(tǒng)給檢測(cè)儀內(nèi)部的鋰電池進(jìn)行充電。(本項(xiàng)目采用的是IDT 5W無(wú)線(xiàn)充電開(kāi)發(fā)套件)
2、主要器件
IDT15W無(wú)線(xiàn)充電開(kāi)發(fā)套件
Arduino?LGT8F328D單片機(jī)
A003最新款顆粒物傳感器
S80053二氧化碳傳感器
2.2寸串口屏
18650鋰電池,容量2600mah
ETA9640充放電芯片,最大充放電電流1000ma
3、實(shí)現(xiàn)效果
IDT無(wú)線(xiàn)供電系統(tǒng)接收板
無(wú)線(xiàn)充電過(guò)程
4、設(shè)計(jì)原理
硬件說(shuō)明
通過(guò)設(shè)計(jì)計(jì)算,整機(jī)負(fù)載電流約500ma,考慮到設(shè)計(jì)的充電電流是1000ma,所以項(xiàng)目選用了IDT 5W無(wú)線(xiàn)供電系統(tǒng),該系統(tǒng)可以提供5V 1A的最大5W的功率輸出,完全滿(mǎn)足設(shè)計(jì)要求。(本項(xiàng)目采用的是IDT 5W無(wú)線(xiàn)充電開(kāi)發(fā)套件)
包含三大部分組成:
1、無(wú)線(xiàn)供電鋰電池充放電部分,由于傳感器的TTL輸出電平是3.3V,所以還需要通過(guò)一個(gè)LDO將MCU供電電源降為3.3V。傳感器供電部分是5V(內(nèi)部有LDO降壓),有系統(tǒng)直接供電即可。本項(xiàng)目用的電池選用了常見(jiàn)的18650鋰電池,容量2600mah。充放電芯片選用上海鈺泰的ETA9640一體式芯片,最大充放電電流1000ma,自帶鋰電池保護(hù)電路,無(wú)需外圍再加保護(hù)電路。無(wú)線(xiàn)供電接收板接口直接與USB供電接口并接,既可以采用USB供電,也可以采用IDT無(wú)線(xiàn)系統(tǒng)供電。
2、MCU部分選用了AVR內(nèi)核的8位單片機(jī),LGT8F328D,傳感器選用攀藤科技的A003最新款顆粒物傳感器和森爾電子的S8 0053二氧化碳傳感器(由于二氧化碳傳感器價(jià)格較貴,最終未進(jìn)行購(gòu)買(mǎi))。
3、顯示屏幕選用了2.2寸串口屏,便于快速開(kāi)發(fā),降低開(kāi)發(fā)難度。
在這里插入圖片描述
在這里插入圖片描述
項(xiàng)目的PCB圖和3D圖部分:
這個(gè)PCB板子尺寸為80*70mm,正面為主要電路和屏幕部分,反面為18650電池倉(cāng)和兩個(gè)傳感器接口。
最終PCB板和焊接好的PCB板:
在這里插入圖片描述
軟件部分
本項(xiàng)目軟件設(shè)計(jì)采用Arduino IDE開(kāi)源編程框架,主要分為系統(tǒng)初始化和循環(huán)執(zhí)行兩大部分構(gòu)成。
5 部分核心代碼
#include? SoftwareSerial?pm(2,?NULL); SoftwareSerial?co(4,?NULL); unsigned?int?CO2; unsigned?int??pm25; void?getCO2(unsigned?char?Data)? { ??staTIc?unsigned?char?RxBuffer[7]; ??staTIc?unsigned?char?RxCnt?=?0; ??RxBuffer[RxCnt++]?=?Data; ??if?(RxBuffer[0]?!=?0xFE?&&?RxBuffer[1]?!=?0x04) ??{ ????RxCnt?=?0; ????return; ??} ??if?(RxCnt?>?6) ??{ ????CO2?=?(int)?RxBuffer[3]?*?256?+?(int)?RxBuffer[4]; ????RxCnt?=?0; ????return; ??} } void?getPM25() { ??uint8_t?mData?=?0; ??uint8_t?i?=?0; ??uint8_t?mPkt[32]?=?{0}; ??int?mCheck?=?0; ??pm.listen();?? ??delay(100); ??while?(pm.available()?>?0) ??{ ????mData?=?pm.read(); ????delay(2); ????if?(mData?==?0x42)? ????{ ??????mPkt[0]?=??mData; ??????mData?=?pm.read(); ??????delay(2); ??????if?(mData?==?0x4d)? ??????{ ????????mPkt[1]?=??mData; ????????mCheck?=?66?+?77; ????????for?(?i?=?2;?i?<?30;?i++)? ????????{ ??????????mPkt[i]?=?pm.read(); ??????????delay(2); ??????????mCheck?+=?mPkt[i]; ????????} ????????mPkt[30]?=?pm.read(); ????????delay(2); ????????mPkt[31]?=?pm.read(); ????????delay(2); ????????if?(mCheck?==?mPkt[30]?*?256?+?mPkt[31])? ????????{ ??????????pm25?=?mPkt[12]?*?256?+?mPkt[13]; ?????????? ??????????Serial.flush(); ??????????return; ????????} ??????} ????} ??} } void?setup() { ??Serial.begin(9600); ??pm.begin(9600); ??co.begin(9600); ??delay(5000); ??Serial.println("SPG(2);");? ??delay(100); } void?loop() { ??getPM25(); ??co.listen();?? ??delay(100); ??staTIc?unsigned?char?TxBuffer[]?=?{0xFE,?0x04,?0x00,?0x03,?0x00,?0x01,?0xD5,?0xC5}; ??co.write(TxBuffer,?8); ??delay(100); ??while?(co.available()) ??{ ????getCO2(co.read()); ??} ??Serial.print("LABL(48,0,40,159,'");??Serial.print(pm25);??Serial.print("',");??Serial.print(15);??Serial.println(",1);"); ??Serial.print("LABL(48,161,40,319,'");??Serial.print(CO2);??Serial.print("',");??Serial.print(15);??Serial.println(",1);"); }