技術(shù)背景
在日常生活中,我們常見(jiàn)的電子測(cè)溫器有較大的弊端,首先大部分電子測(cè)溫計(jì)都無(wú)法自動(dòng)保存儲(chǔ)存數(shù)據(jù),無(wú)法得知過(guò)去幾天的溫度與濕度。
同時(shí)常見(jiàn)的電子測(cè)溫計(jì)會(huì)始終處于工作狀態(tài),LCD始終亮屏功耗較高。我們組設(shè)計(jì)的無(wú)接觸式自動(dòng)測(cè)溫器可以很好的解決以上問(wèn)題。同時(shí)在以低功耗消耗的同時(shí),仍然以較高精度地對(duì)溫度和濕度完成測(cè)量。
除此之外,我們?cè)O(shè)計(jì)的電子測(cè)溫器仍然具有超過(guò)溫度閾值自動(dòng)報(bào)警引起注意、獲取實(shí)時(shí)天氣系統(tǒng)API等功能,實(shí)現(xiàn)了更多的功能完善。
技術(shù)目標(biāo)
我們組設(shè)計(jì)的目標(biāo)是自動(dòng)化零接觸式溫濕度傳感器,它會(huì)始終測(cè)量空氣中的溫度和濕度,同時(shí)將其數(shù)據(jù)上傳至OneNET云平臺(tái)并進(jìn)行儲(chǔ)存,同時(shí)會(huì)以折線圖等形式數(shù)據(jù)化展現(xiàn),便于處理。
同時(shí)他具有自動(dòng)檢測(cè)空氣溫度,若溫度超過(guò)設(shè)定閾值便會(huì)報(bào)警的功能。同時(shí)他會(huì)自動(dòng)檢測(cè)和人們的距離,若沒(méi)有人靠近,LCD會(huì)處于息屏狀態(tài)減少消耗,只是在后臺(tái)記錄數(shù)據(jù)。若人們靠近,LCD會(huì)展示測(cè)量的溫度和濕度,便于觀察。
我們也獲得了天氣API,得到廣州市的實(shí)時(shí)天氣信息,可以將室外的溫濕度與室內(nèi)的溫濕度進(jìn)行比較。
AP3216接近傳感器測(cè)接近值,AHT20溫濕度線程將溫度與濕度數(shù)據(jù)傳給240x240并行LCD線程.
同時(shí)傳給OneNET 云平臺(tái)接入線程,然后將溫度數(shù)據(jù)傳給蜂鳴器線程。接近傳感器線程返回值傳遞給240x240 并行LCD線程。
LCD和配置顯示:
如下圖所示,星火1號(hào)開(kāi)發(fā)板中裝載有240*240的LCD顯示屏。顯示屏的驅(qū)動(dòng)芯片是ST7789 v3,通信接口8080并口。通過(guò) fsms 模擬出驅(qū)動(dòng)時(shí)序和單片機(jī)進(jìn)行通訊。
在main函數(shù)里,通過(guò)調(diào)用已經(jīng)封裝哈的LCD API函數(shù),進(jìn)行清屏操作。通過(guò)將背景刷為白色和黑色,進(jìn)行屏幕的亮熄屏操作,同時(shí)在LCD上顯示溫濕度傳感器所測(cè)量到的數(shù)值。
配置ap3216c進(jìn)行距離檢測(cè)
單片機(jī)通過(guò)I2C scl 、 I2C sda 對(duì)ap3216c 發(fā)送命令、讀取數(shù)據(jù)等。
我們先初始傳感器ap3216c,傳入參數(shù)i2c1為該傳感器掛載的i2c總線的名稱;然后將返回設(shè)備對(duì)象分別傳入獲取的ps函數(shù),獲得測(cè)量的ps值。通過(guò)最后串口返回的ps值大小代表是否有人靠近,如果靠近便會(huì)亮屏顯示數(shù)據(jù),未靠近便會(huì)息屏節(jié)省功耗。
收集數(shù)據(jù)并可視化
先通過(guò)rw007軟件包使用 SPI 與主機(jī)通信,在終端輸入wifi join的指令,將星火一號(hào)開(kāi)發(fā)板接入網(wǎng)絡(luò)。
獲取溫度濕度數(shù)據(jù)
將aht10采集到的溫濕度數(shù)據(jù)信息同步。
將數(shù)據(jù)上傳至云平臺(tái)
OneNET平臺(tái)將會(huì)收錄數(shù)據(jù)并形成折線圖,以便用戶看到溫度濕度的變化趨勢(shì)。
將數(shù)據(jù)直觀展示
為了更方便的讓用戶查詢溫濕度信息,將數(shù)據(jù)可視化的展示在頁(yè)面上,并且實(shí)時(shí)更新。這樣用戶就可以遠(yuǎn)程查詢溫濕度。
查詢實(shí)時(shí)天氣
從網(wǎng)頁(yè)獲取API密匙,并生成API接口地址。
連網(wǎng)后,通過(guò)軟件代碼用API獲取實(shí)時(shí)天氣數(shù)據(jù)。
設(shè)計(jì)心得
我們通過(guò)這次實(shí)訓(xùn)學(xué)習(xí)到了很多知識(shí):
首先是在前面5天,我們了解了嵌入式操作系統(tǒng)的應(yīng)用與發(fā)展,學(xué)習(xí)了rt-thread的基本知識(shí),初步明白了線程的運(yùn)行原理和通過(guò)線程來(lái)控制系統(tǒng)的運(yùn)行。
因?yàn)槭堑谝淮谓佑|這些知識(shí),我們遇到了很多的困難,但因?yàn)橛袠?lè)于幫助的老師和同學(xué),困難都被一一解決。
同時(shí)我們還明白了借助已有的軟件包和代碼資源來(lái)實(shí)現(xiàn)功能的重要性,畢竟在短時(shí)間內(nèi)想自己寫出強(qiáng)大而復(fù)雜的程序?qū)τ谖覀兂鯇W(xué)者而言是極其困難的。
除此之外,體會(huì)最深的就是不斷練習(xí)才是掌握這門技術(shù)最有效的方法,即使課上聽(tīng)懂了的內(nèi)容也要課后自己練習(xí),只有當(dāng)工程運(yùn)行成功的那一刻,才算是真正的了解。
以下是我們?cè)O(shè)計(jì)的代碼:
#include
#include
#include
#include "aht10.h"
#include "ap3216c.h"
#include
#include
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include
/* 配置 KEY 輸入引腳 /
#define PIN_KEY1 GET_PIN(C, 1) // PC1: KEY1 --> KEY
#define PIN_WK_UP GET_PIN(C, 5) // PC5: WK_UP --> KEY
/ 配置蜂鳴器引腳 /
#define PIN_BEEP GET_PIN(B, 0) // PA1: BEEP --> BEEP (PB1)
/ 中斷回調(diào) */
void irq_callback(void args)
{
rt_uint32_t sign = (rt_uint32_t) args;
switch (sign)
{
case PIN_WK_UP :
rt_pin_write(PIN_BEEP,PIN_HIGH);
LOG_D("WK_UP interrupt. beep on.");
break;
case PIN_KEY1 :
rt_pin_write(PIN_BEEP,PIN_LOW);
LOG_D("KEY1 interrupt. beep off.");
break;
default:
LOG_E("error sign= %d !", sign);
break;
}
}
int main(void)
{
/ 設(shè)置按鍵引腳為輸入模式 /
rt_pin_mode(PIN_KEY1, PIN_MODE_INPUT_PULLUP);
rt_pin_mode(PIN_WK_UP, PIN_MODE_INPUT_PULLUP);
/ 設(shè)置蜂鳴器引腳為輸出模式 /
rt_pin_mode(PIN_BEEP, PIN_MODE_OUTPUT);
/ 設(shè)置按鍵中斷模式與中斷回調(diào)函數(shù) */
rt_pin_attach_irq(PIN_KEY1, PIN_IRQ_MODE_FALLING, irq_callback, (void *) PIN_KEY1);
rt_pin_attach_irq(PIN_WK_UP, PIN_IRQ_MODE_FALLING, irq_callback, (void ) PIN_WK_UP);
/ 使能中斷 /
rt_pin_irq_enable(PIN_KEY1, PIN_IRQ_ENABLE);
rt_pin_irq_enable(PIN_WK_UP, PIN_IRQ_ENABLE);
float humidity, temperature;
aht10_device_t dev;
/ 總線名稱 */
const char *i2c_bus_name = "i2c3";
int count = 0;
ap3216c_device_t dev1;
const char i2c_bus_name1 = "i2c2";
/ 等待傳感器正常工作 /
rt_thread_mdelay(2000);
/ 初始化 aht10 /
dev = aht10_init(i2c_bus_name);
if (dev == RT_NULL)
{
LOG_E(" The sensor initializes failure");
return 0;
}
/ 初始化 ap3216c /
dev1 = ap3216c_init(i2c_bus_name1);
if (dev1 == RT_NULL)
{
LOG_E("The sensor initializes failure.");
return 0;
}
while (count++ < 100)
{
rt_uint16_t ps_data;
/ 讀接近感應(yīng)值 /
ps_data = ap3216c_read_ps_data(dev1);
if (ps_data == 0)
{
LOG_D("object is not proximity of sensor.");
}
else
{
LOG_D("current ps data : %d.", ps_data);
}
/ 讀取濕度 /
humidity = aht10_read_humidity(dev);
/ 讀取溫度 /
temperature = aht10_read_temperature(dev);
rt_thread_mdelay(1000);
if(temperature>35)
{
rt_pin_write(PIN_BEEP, PIN_HIGH);
}
if(ps_data>=10)
{
lcd_clear(WHITE);
lcd_show_image(0, 0, 240, 69, image_rttlogo);
/ set the background color and foreground color /
lcd_set_color(WHITE, BLACK);
/ show some string on lcd /
lcd_show_string(10, 69, 24, "Temperature:");
lcd_show_string(10, 69+24, 24, "Humidity:");
lcd_show_num(170,69,temperature,4,24);
lcd_show_num(170,69+24,humidity,7,24);
/ draw a line on lcd /
lcd_draw_line(0, 69 + 16 + 24 + 32, 240, 69 + 16 + 24 + 32);
/ draw a concentric circles */
lcd_draw_point(120, 194);
for (int i = 0; i < 46; i += 4)
{
lcd_draw_circle(120, 194, i);
}
}
else
lcd_clear(BLACK);
}
return 0;
}
評(píng)論