項(xiàng)目成品圖片:
01
—
項(xiàng)目簡(jiǎn)介
1.功能詳解
功能如下:
STM32F103C8T6單片機(jī)作為主控單元
按鍵切換模式,支持自動(dòng)/手動(dòng)兩種模式
光敏電阻采集光照強(qiáng)度,超聲波傳感器采集坐姿距離,所有參數(shù)顯示在OLED上
智能模式:自動(dòng)識(shí)別有人開(kāi)燈,并根據(jù)環(huán)境光強(qiáng)度控制燈的亮度
按鍵模式:按鍵手動(dòng)調(diào)節(jié)燈亮度
語(yǔ)音模式:通過(guò)語(yǔ)音識(shí)別控制臺(tái)燈調(diào)光與模式切換
坐姿報(bào)警:超聲波距離報(bào)警
機(jī)智云APP:通過(guò)APP可查看數(shù)據(jù),以及控制下發(fā)
2.材料清單
STM32F103C8T6單片機(jī)
OLED 屏幕
DHT11溫濕度傳感器
光敏傳感器
SNR8016語(yǔ)音模塊
HC-SR04超聲波傳感器
ESP8266模塊(WIFI)
有源蜂鳴器
大功率LED燈模塊
02
—
原理圖設(shè)計(jì)
03
—
PCB硬件設(shè)計(jì)
PCB圖
04
—
程序設(shè)計(jì)
#include"stm32f10x.h" // Device header#include"adcx.h"#include"ldr.h"#include"oled.h"#include"dht11.h"#include"pwm.h"#include"led.h"#include"key.h"#include"tim2.h" #include"tim3.h" #include"hc_sr501.h"#include"hc_sr04.h"#include"sensormodules.h"#include"usart.h"#include"gizwits_product.h"#include"myrtc.h"#include"flash.h"#include"iwdg.h"#include"usart3.h"
#defineKEY_Long111
#defineKEY_11#defineKEY_22#defineKEY_33#defineKEY_44
#defineFLASH_START_ADDR0x0801f000//寫(xiě)入的起始地址
uint8_thc501;//存儲(chǔ)人體信號(hào)uint8_tsystemModel =0;//存儲(chǔ)系統(tǒng)當(dāng)前模式
uint8_thour,minute,second;//時(shí) 分 秒uint8_tmenu =1;//顯示菜單變量
SensorModules sensorData;//聲明傳感器數(shù)據(jù)結(jié)構(gòu)體變量SensorThresholdValue Sensorthreshold;//聲明傳感器閾值結(jié)構(gòu)體變量
enum{display_page =1,settingsPage,timeSettingsPage
}MenuPages;
/** * @brief 顯示主頁(yè)面固定內(nèi)容 * @param 無(wú) * @retval 無(wú) */voidOLED_Menu(void){//顯示“Time:”O(jiān)LED_ShowString(1,1,"Time");OLED_ShowChar(1,5,':');
//顯示“溫度:”O(jiān)LED_ShowChinese(2,1,0);OLED_ShowChinese(2,2,1);OLED_ShowChar(2,5,':');//顯示“濕度:”O(jiān)LED_ShowChinese(2,5,2);OLED_ShowChinese(2,6,1);OLED_ShowChar(2,13,':');
//顯示“光強(qiáng):”O(jiān)LED_ShowChinese(3,1,4);OLED_ShowChinese(3,2,5);OLED_ShowChar(3,5,':');//顯示“距離:”O(jiān)LED_ShowChinese(3,5,17);OLED_ShowChinese(3,6,18);OLED_ShowChar(3,13,':');
//顯示“亮度:”O(jiān)LED_ShowChinese(4,1,6);OLED_ShowChinese(4,2,1);OLED_ShowChar(4,5,':');}
/** * @brief 顯示主頁(yè)面的傳感器數(shù)據(jù)等信息 * @param 無(wú) * @retval 無(wú) */voidOLED_Menu_SensorData(void){//顯示時(shí)間數(shù)據(jù)OLED_ShowNum(1,6,MyRTC_Time[3],2);OLED_ShowChar(1,8,':');OLED_ShowNum(1,9,MyRTC_Time[4],2);OLED_ShowChar(1,11,':');OLED_ShowNum(1,12,MyRTC_Time[5],2);
//顯示溫度數(shù)據(jù)OLED_ShowNum(2,6, sensorData.temp,2);OLED_ShowChar(2,8,'C');
//顯示濕度數(shù)據(jù)OLED_ShowNum(2,14, sensorData.humi,2);OLED_ShowChar(2,16,'%');
//顯示光強(qiáng)數(shù)據(jù)OLED_ShowNum(3,6, sensorData.lux,3);
//顯示距離數(shù)據(jù)OLED_ShowNum(3,14, sensorData.distance,3);
//顯示亮度等級(jí)OLED_ShowNum(4,6, ledDutyRatio,3);OLED_ShowChar(4,9,'%');
//顯示是否有人if(sensorData.people){OLED_ShowChinese(1,8,19);}else{OLED_ShowString(1,15," ");}
//顯示系統(tǒng)當(dāng)前模式 手動(dòng)模式 or 自動(dòng)模式if(systemModel){//顯示“自動(dòng)”O(jiān)LED_ShowChinese(4,7,9);OLED_ShowChinese(4,8,10);}else{//顯示“手動(dòng)”O(jiān)LED_ShowChinese(4,7,11);OLED_ShowChinese(4,8,12);}}
/** * @brief 顯示系統(tǒng)設(shè)置界面 * @param 無(wú) * @retval 無(wú) */voidOLED_SetInterfacevoid(void){//顯示“系統(tǒng)設(shè)置界面”O(jiān)LED_ShowChinese(1,2,20);OLED_ShowChinese(1,3,21);OLED_ShowChinese(1,4,22);OLED_ShowChinese(1,5,23);OLED_ShowChinese(1,6,24);OLED_ShowChinese(1,7,25);
//顯示“系統(tǒng)時(shí)間”O(jiān)LED_ShowChinese(2,2,20);OLED_ShowChinese(2,3,21);OLED_ShowChinese(2,4,28);OLED_ShowChinese(2,5,29);OLED_ShowChar(2,11,':');OLED_ShowString(2,13,"xxx");
//顯示“光照閾值”O(jiān)LED_ShowChinese(3,2,4);OLED_ShowChinese(3,3,5);OLED_ShowChinese(3,4,26);OLED_ShowChinese(3,5,27);OLED_ShowChar(3,11,':');
//顯示”距離閾值“OLED_ShowChinese(4,2,17);OLED_ShowChinese(4,3,18);OLED_ShowChinese(4,4,26);OLED_ShowChinese(4,5,27);OLED_ShowChar(4,11,':');
//顯示光照閾值數(shù)值OLED_ShowNum(3,13, Sensorthreshold.Illumination_threshold,3);
//顯示距離閾值數(shù)值OLED_ShowNum(4,14, Sensorthreshold.Distance_threshold,2);}
/** * @brief 記錄閾值界面下按KEY1的次數(shù) * @param 無(wú) * @retval 返回次數(shù) */uint8_tSetSelection(void){staticuint8_tcount =1;if(KeyNum == KEY_1){KeyNum =0;count++;if(count >=4){count =1;}}returncount;}
/** * @brief 顯示閾值界面的選擇符號(hào) * @param num 為顯示的位置 * @retval 無(wú) */voidOLED_Option(uint8_tnum){switch(num){case1:OLED_ShowChar(1,1,' ');OLED_ShowChar(2,1,'>');OLED_ShowChar(3,1,' ');OLED_ShowChar(4,1,' ');break;case2:OLED_ShowChar(1,1,' ');OLED_ShowChar(2,1,' ');OLED_ShowChar(3,1,'>');OLED_ShowChar(4,1,' ');break;case3:OLED_ShowChar(1,1,' ');OLED_ShowChar(2,1,' ');OLED_ShowChar(3,1,' ');OLED_ShowChar(4,1,'>');break;default:break;}}
/** * @brief 顯示時(shí)間調(diào)節(jié)界面的選擇符號(hào) * @param num 為顯示的位置 * @retval 無(wú) */voidOLED_Time_Option(u8 num){switch(num){case1:
OLED_ShowChar(2,6,'v');OLED_ShowChar(2,9,' ');OLED_ShowChar(2,12,' ');break;case2:OLED_ShowChar(2,6,' ');OLED_ShowChar(2,9,'v');OLED_ShowChar(2,12,' ');break;case3:OLED_ShowChar(2,6,' ');OLED_ShowChar(2,9,' ');OLED_ShowChar(2,12,'v');break;default:break;}}
/** * @brief 顯示時(shí)間調(diào)節(jié)界面的內(nèi)容 * @param 無(wú) * @retval 無(wú) */voidOLED_ThresholdTime(void){//系統(tǒng)時(shí)間:OLED_ShowChinese(1,3,20);OLED_ShowChinese(1,4,21);OLED_ShowChinese(1,5,28);OLED_ShowChinese(1,6,29);OLED_ShowChar(1,13,':');
OLED_ShowNum(3,5,hour,2);OLED_ShowChar(3,7,':');OLED_ShowNum(3,8,minute,2);OLED_ShowChar(3,10,':');OLED_ShowNum(3,11,second,2);}
/** * @brief 對(duì)閾值界面的傳感器閾值進(jìn)行修改 * @param num 為當(dāng)前用戶需要更改的傳感器閾值位置 * @retval 無(wú) */voidThresholdModification(uint8_tnum){switch(num){case1:if(KeyNum == KEY_3){KeyNum =0;OLED_Clear();menu = timeSettingsPage;
hour = MyRTC_Time[3];minute = MyRTC_Time[4];second = MyRTC_Time[5];}elseif(KeyNum == KEY_4){KeyNum =0;OLED_Clear();menu = timeSettingsPage;
hour = MyRTC_Time[3];minute = MyRTC_Time[4];second = MyRTC_Time[5];}break;
case2:if(KeyNum == KEY_3){KeyNum =0;Sensorthreshold.Illumination_threshold +=10;if(Sensorthreshold.Illumination_threshold >999){Sensorthreshold.Illumination_threshold =1;}}elseif(KeyNum == KEY_4){KeyNum =0;Sensorthreshold.Illumination_threshold -=10;if(Sensorthreshold.Illumination_threshold 1){Sensorthreshold.Illumination_threshold =?999;}}break;case?3:if?(KeyNum == KEY_3){KeyNum =?0;Sensorthreshold.Distance_threshold++;if?(Sensorthreshold.Distance_threshold >99){Sensorthreshold.Distance_threshold =1;}}elseif(KeyNum == KEY_4){KeyNum =0;Sensorthreshold.Distance_threshold--;if(Sensorthreshold.Distance_threshold 1){Sensorthreshold.Distance_threshold =?99;}}break;default:?break;}}
/** * @brief 對(duì)系統(tǒng)時(shí)間進(jìn)行修改 * @param num 為當(dāng)前用戶需要更改的時(shí)分秒位置 * @retval 無(wú) */voidTimeModification(uint8_tnum){switch(num){case1:if(KeyNum == KEY_3){KeyNum =0;hour++;if(hour >24){hour =0;}}elseif(KeyNum == KEY_4){KeyNum =0;hour --;if(hour >24){hour =24;}}break;
case2:if(KeyNum == KEY_3){KeyNum =0;minute++;if(minute >60){minute =0;}}elseif(KeyNum == KEY_4){KeyNum =0;minute --;if(minute >60){minute =60;}}break;case3:if(KeyNum == KEY_3){KeyNum =0;second++;if(second >60){second =0;}}elseif(KeyNum == KEY_4){KeyNum =0;second --;if(second >60){second =60;}}break;default:break;}}
/** * @brief 獲取語(yǔ)音模塊數(shù)據(jù) * @param 無(wú) * @retval 無(wú) */voidAsrpro(void){if(Usart3_RxFlag ==1){Usart3_RxFlag =0;switch(Usart3_RxPacket[3]){/*控制開(kāi)關(guān)燈*/case1:if(!systemModel){if(Usart3_RxPacket[4]){ledDutyRatio =100;TIM_SetCompare1(TIM1, ledDutyRatio);}else{ledDutyRatio =0;TIM_SetCompare1(TIM1, ledDutyRatio);}}break;
/*控制燈暗一點(diǎn)或亮一點(diǎn)*/case2:if(!systemModel){if(Usart3_RxPacket[4]){ledDutyRatio +=25;if(ledDutyRatio >100){ledDutyRatio =100;}TIM_SetCompare1(TIM1, ledDutyRatio);}else{ledDutyRatio -=25;if(ledDutyRatio >100){ledDutyRatio =0;}TIM_SetCompare1(TIM1, ledDutyRatio);}}break;
/*控制燈亮度百分比調(diào)節(jié)*/case3:if(!systemModel){switch(Usart3_RxPacket[4]){case0:ledDutyRatio =0;TIM_SetCompare1(TIM1, ledDutyRatio);break;
case1:ledDutyRatio =10;TIM_SetCompare1(TIM1, ledDutyRatio);break;
case2:ledDutyRatio =20;TIM_SetCompare1(TIM1, ledDutyRatio);break;
case3:ledDutyRatio =30;TIM_SetCompare1(TIM1, ledDutyRatio);break;
case4:ledDutyRatio =40;TIM_SetCompare1(TIM1, ledDutyRatio);break;
case5:ledDutyRatio =50;TIM_SetCompare1(TIM1, ledDutyRatio);break;
case6:ledDutyRatio =60;TIM_SetCompare1(TIM1, ledDutyRatio);break;
case7:ledDutyRatio =70;TIM_SetCompare1(TIM1, ledDutyRatio);break;
case8:ledDutyRatio =80;TIM_SetCompare1(TIM1, ledDutyRatio);break;
case9:ledDutyRatio =90;TIM_SetCompare1(TIM1, ledDutyRatio);break;
case16:ledDutyRatio =100;TIM_SetCompare1(TIM1, ledDutyRatio);break;
default:break;}}break;
/*控制系統(tǒng)模式*/case4:if(Usart3_RxPacket[4]){systemModel =1;ledDutyRatio =0;TIM_SetCompare1(TIM1, ledDutyRatio);}else{systemModel =0;ledDutyRatio =0;TIM_SetCompare1(TIM1, ledDutyRatio);}break;
default:break;}}}
/** * @brief 獲取傳感器的數(shù)據(jù) * @param 無(wú) * @retval 無(wú) */voidsensorScan(void){DHT11_Read_Data(&sensorData.humi, &sensorData.temp);HC_SR04_Deboanle(&sensorData.distance);LDR_LuxData(&sensorData.lux);HC_SR501_Input(&sensorData.people);}
intmain(void){ADCX_Init();PWM_Init(100-1,720-1);Timer2_Init(9,14398);Uart2_Init(9600);Uart1_Init(115200);IWDG_Init();//初始化看門狗Uart3_Init();
LDR_Init();OLED_Init();DHT11_Init();LED_Init();Key_Init();HC_SR501_Init();HC_SR04_Init();Buzzer_Init();MyRTC_Init();
Sensorthreshold.Illumination_threshold =FLASH_R(FLASH_START_ADDR);//從指定頁(yè)的地址讀FLASHSensorthreshold.Distance_threshold =FLASH_R(FLASH_START_ADDR+2);//從指定頁(yè)的地址讀FLASH
GENERAL_TIM_Init();userInit();//完成機(jī)智云初始賦值gizwitsInit();//開(kāi)辟一個(gè)環(huán)形緩沖區(qū)while(1){do{currentDataPoint.valueIllumination_threshold = Sensorthreshold.Illumination_threshold;currentDataPoint.valueDistance_threshold = Sensorthreshold.Distance_threshold;}while(0);
IWDG_ReloadCounter();//重新加載計(jì)數(shù)值 喂狗sensorScan();//獲取傳感器數(shù)據(jù)Asrpro();//執(zhí)行語(yǔ)音指令
switch(menu){casedisplay_page:
MyRTC_ReadTime();//調(diào)用此函數(shù)后,RTC硬件電路里時(shí)間值將刷新到全局?jǐn)?shù)組OLED_Menu_SensorData();//顯示主頁(yè)面?zhèn)鞲衅鲾?shù)據(jù)、系統(tǒng)模式等內(nèi)容OLED_Menu();//顯示主頁(yè)面的固定內(nèi)容if(!systemModel){LED_PWM_KEY();//按鍵控制LED的PWM}
//切換系統(tǒng)模式if(KeyNum == KEY_1){KeyNum =0;systemModel = ~systemModel;if(systemModel){currentDataPoint.valueModel =1;ledDutyRatio =0;TIM_SetCompare1(TIM1, ledDutyRatio);}else{currentDataPoint.valueModel =0;ledDutyRatio =0;TIM_SetCompare1(TIM1, ledDutyRatio);}}
//判斷是否進(jìn)入閾值設(shè)置界面if(KeyNum == KEY_Long1){KeyNum =0;OLED_Clear();//清屏menu = settingsPage;//跳轉(zhuǎn)到閾值設(shè)置界面}break;casesettingsPage:OLED_SetInterfacevoid();//顯示閾值設(shè)置界面的固定內(nèi)容OLED_Option(SetSelection());//實(shí)現(xiàn)閾值設(shè)置頁(yè)面的選擇功能ThresholdModification(SetSelection());//實(shí)現(xiàn)閾值調(diào)節(jié)功能
//判斷是否退出閾值設(shè)置界面if(KeyNum == KEY_2){KeyNum =0;OLED_Clear();//清屏menu = display_page;//跳轉(zhuǎn)到主界面
//存儲(chǔ)修改的傳感器閾值至flash內(nèi)FLASH_W(FLASH_START_ADDR, Sensorthreshold.Illumination_threshold, Sensorthreshold.Distance_threshold);currentDataPoint.valueIllumination_threshold = Sensorthreshold.Illumination_threshold;currentDataPoint.valueDistance_threshold = Sensorthreshold.Distance_threshold;}break;casetimeSettingsPage:OLED_ThresholdTime();//顯示時(shí)間設(shè)置界面的內(nèi)容OLED_Time_Option(SetSelection());//實(shí)現(xiàn)間設(shè)置界面的選擇功能TimeModification(SetSelection());//實(shí)現(xiàn)時(shí)間調(diào)節(jié)功能
//判斷是否退出時(shí)間設(shè)置界面if(KeyNum == KEY_2){KeyNum =0;//將更改的數(shù)據(jù)賦值回RTC數(shù)組中MyRTC_Time[3] = hour;MyRTC_Time[4] = minute;MyRTC_Time[5] = second;MyRTC_SetTime();//調(diào)用此函數(shù)后,全局?jǐn)?shù)組里時(shí)間值將刷新到RTC硬件電路
OLED_Clear();//清屏menu = settingsPage;//回到閾值設(shè)置界面}break;}//判斷上位機(jī)是否更改閾值,如更改則保存至flash中if(valueFlashflag){valueFlashflag =0;//存儲(chǔ)修改的傳感器閾值至flash內(nèi)FLASH_W(FLASH_START_ADDR, Sensorthreshold.Illumination_threshold, Sensorthreshold.Distance_threshold);}
userHandle();//更新機(jī)智云數(shù)據(jù)點(diǎn)變量存儲(chǔ)的值gizwitsHandle((dataPoint_t *)¤tDataPoint);//數(shù)據(jù)上傳至機(jī)智云}}
05
—
實(shí)驗(yàn)效果
-
STM32
+關(guān)注
關(guān)注
2295文章
11033瀏覽量
365489 -
智能語(yǔ)音
+關(guān)注
關(guān)注
11文章
805瀏覽量
49548 -
機(jī)智云
+關(guān)注
關(guān)注
3文章
618瀏覽量
26878
發(fā)布評(píng)論請(qǐng)先 登錄
【萬(wàn)元大獎(jiǎng)】機(jī)智云智能硬件創(chuàng)新大賽
基于機(jī)智云物聯(lián)網(wǎng)遠(yuǎn)程控制臺(tái)燈
機(jī)智云2016~2017優(yōu)秀項(xiàng)目盤點(diǎn)
【視頻推薦】以智能語(yǔ)音魚(yú)缸為例,講解機(jī)智云代碼
基于STM32芯片和機(jī)智云平臺(tái)的一款智能臺(tái)燈
stm32項(xiàng)目搭建基礎(chǔ)
STM32項(xiàng)目分享:智能臺(tái)燈系統(tǒng)

STM32項(xiàng)目分享:機(jī)智云智慧農(nóng)業(yè)系統(tǒng)

STM32項(xiàng)目分享:智能臺(tái)燈(機(jī)智云)系統(tǒng)

STM32項(xiàng)目分享:STM32智能語(yǔ)音臺(tái)燈

基于機(jī)智云的智能臺(tái)燈原型系統(tǒng)設(shè)計(jì)

STM32項(xiàng)目分享:智能家居(機(jī)智云)升級(jí)版

評(píng)論