找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8176|回復: 19
打印 上一主題 下一主題
收起左側

DIY單片機聲控小夜燈+PWM四檔亮度調節(jié) 原理圖PCB和程序全套資料

  [復制鏈接]
跳轉到指定樓層
樓主
ID:702386 發(fā)表于 2022-1-27 09:42 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 zsw3721 于 2022-2-18 23:28 編輯

2022年2月18日本次更新:

截至目前使用了半個多月,可以說是非常好用和方便的。電池很耐用,睡前使用一會再設置為聲控觸發(fā)模式,晚上帶娃要經(jīng)常點亮燈,充一次電基本上可以使用一個星期。這段時間進行了多處優(yōu)化,程序升級為V1.6版。
1. 調整為5檔PWM亮度調節(jié),分別為20%、40%、60%、80%、100%亮度
2. 增加聲控觸發(fā)過濾,在1秒內(nèi)需要3次及以上的外部中斷才能觸發(fā)亮燈(不會影響正常聲控觸發(fā),因為一個聲音比如一聲咳嗽實際會有非常多個中斷產(chǎn)生),消除了單個偶發(fā)的雜波干擾導致可能的意外亮燈或反復觸發(fā)無法熄燈

3. 聲控觸發(fā)亮燈后60秒后才允許聲控再觸發(fā),即每次聲控亮燈3分鐘的后兩分鐘完全平靜即可自動熄燈
4. 聲控觸發(fā)亮燈后,距自動熄燈剩余10秒時亮度自動降低(至10%亮度)
5. 長按亮度調節(jié)按鍵2秒以上,亮度調整為10%亮度
6. 定時器T0(定時1mS)初值糾正為12MHz 1T的配置(之前程序為11.0592MHz下的配置)。程序下載時應選擇12MHz時鐘頻率。
7. 增加MCU進掉電模式以降低功耗:聲控亮燈3分鐘自動熄燈后即控制MCU進入掉電模式,當有外部中斷(即聲音信號)時MCU喚醒并正常觸發(fā)亮燈。


程序 V1.6 增加聲控待觸發(fā)狀態(tài)下進掉電模式以降低功耗.rar (45.88 KB, 下載次數(shù): 73)



2022年1月28日更新一次:
試用了幾天后,優(yōu)化了兩處地方,程序升級為V1.4版。
1. 聲控觸發(fā)亮燈后延時3分鐘自動熄燈,修改為自動熄燈前如果又檢測到聲音,重新計時3分鐘
2. 按鍵從常亮模式切換到聲控待觸發(fā)模式,默認熄燈,但是按鍵的聲音會導致切到聲控待觸發(fā)模式后直接觸發(fā)亮燈,現(xiàn)修改為按鍵切到聲控待觸發(fā)模式后等待1秒鐘才允許被觸發(fā)亮燈

以下為2022年1月27日原始帖:
最近,老婆大人提了一個需求,要一個聲控的小夜燈。在某寶搜索一番無果,于是自己動手設計。
老規(guī)矩,先上最終完工的實物圖。使用三天的效果:非常好,誰用誰知道。



下面簡單介紹一下制作過程。

首先是理清需求。

1. 需要有內(nèi)置電池供電,使用時可隨意擺放位置
2. 有常亮模式和聲控亮燈模式
3. 聲控亮燈模式使用時,小聲音不能觸發(fā),要一定強度的聲音才能觸發(fā)亮燈
4. 聲控亮燈觸發(fā)后,延時3分鐘自動熄滅,熄滅前最后10秒亮度自動調至最低

5. 支持多檔亮度調節(jié),燈光無閃爍感

然后是硬件設計。
1. 電池好解決,以前網(wǎng)上購買的5V升壓鋰電池就很好用
2. 聲音檢測模塊可以購買現(xiàn)成的,靈敏度可調節(jié)
3. 使用MCU外部中斷處理聲音檢測模塊的信號
4. 使用軟件PWM方式進行亮度調節(jié),PWM頻率100Hz就足夠了

5. 兩個按鍵,分別控制亮燈模式和亮度調節(jié)
6. 一共只需要4個IO口,用我熟悉的STC15F104W綽綽有余
7. LED燈可以購買現(xiàn)成的USB LED燈,設計一個PMOS電路用于控制LED的供電

下面是設計好的原理圖。


設計好的PCB。



嘉立創(chuàng)免費打樣,焊好并準備好材料。


下面這個是購買的聲控模塊,有聲音時輸出低電平。直接焊在我的控制板上。以后如果有機會做升級版,會把這個聲控模塊畫到我的電路中。



然后開始寫程序。功能比較簡單,兩百多行代碼就搞定。用了一個定時器,定時1mS,然后中斷里每10mS掃一次按鍵;PWM功能也在定時器中實現(xiàn)。
下面是代碼。附件有整套資料,如果你想做一個,按我的資料放心去做保證成功。如果你做出來了,歡迎貼個圖分享。

后注:以下為原始程序,比V1.4版更早。

  1. /*********************************************************************
  2. 《聲控小夜燈》
  3. 設計:zsw3721 @51黑
  4. 日期:2022/1/26
  5. MCU型號:STC15F104W
  6. 系統(tǒng)時鐘:12MHz

  7. 功能簡介:
  8. 1.支持常亮與聲控點亮;
  9. 2.聲控點亮后延時3分鐘自動熄滅,熄滅前最后10秒鐘亮度自動調至最低;
  10. 3.支持四檔PWM亮度調節(jié):10%、40%、70%、100%亮度;PWM頻率100Hz無閃爍感;
  11. **********************************************************************/

  12. #include "STC15.H"
  13. #include "intrins.h"

  14. #define LED_ON   P32=1;     //LED點亮,P3.2口高電平輸出驅動三極管和PMOS導通點亮LED
  15. #define LED_OFF  P32=0;     //LED熄滅

  16. sbit Key1 = P3^4;                    //按鍵1,短按常亮與聲控模式切換,長按功能未定義
  17. sbit Key2 = P3^5;                    //按鍵2,短按PWM四檔亮度調節(jié),長按功能未定義

  18. bit ShortTouchFlag1=0;      //按鍵1短按按鍵有效標志
  19. bit LongTouchFlag1=0;       //按鍵1長按按鍵有效標志
  20. bit LongTouchRelease1=1;    //按鍵1長按釋放過的標志
  21. bit ShortTouchFlag2=0;      //按鍵2短按按鍵有效標志
  22. bit LongTouchFlag2=0;       //按鍵2長按按鍵有效標志
  23. bit LongTouchRelease2=1;    //按鍵2長按釋放過的標志
  24. bit Flag_1s=1;              //秒任務標志位

  25. unsigned int uiKeyTimeCnt1; //按鍵1計數(shù)
  26. unsigned int uiKeyTimeCnt2; //按鍵2計數(shù)

  27. unsigned char MODE=0;                //工作模式0,1,2分別表示LED常亮模式、聲控待觸發(fā)模式、聲控已觸發(fā)模式
  28. unsigned int Count_1S=0;    //1000mS計數(shù)器
  29. unsigned char Count_10mS=0; //10ms計數(shù)器
  30. unsigned char Count_180S;   //時間計數(shù)器,聲控觸發(fā)后延時180S關燈
  31. unsigned char PWM_COUNT;    //PWM計數(shù)器
  32. unsigned char LED_Brightness=10;   //LED亮度設定值,0~10表示0~100%亮度,開機默認最大亮度
  33. unsigned char PWM_SET;      //PWM占空比設置,可取值0~10,對應占空比0~100%;



  34. /********************************************
  35. 函數(shù)說明:初始化IO口、定時器、外部中斷等
  36. ********************************************/
  37. void Init(void)
  38. {   
  39.     P3M1 &= ~(1<<2);        //將LED驅動腳P3.2設置為推挽輸出
  40.         P3M0 |= (1<<2);

  41.         LED_ON;                        //開機后默認開燈
  42.     PWM_SET = LED_Brightness;   //配置PWM初始占空比   

  43.         AUXR |= 0x80;                //定時器T0 時鐘1T模式
  44.         TMOD &= 0xF0;                //設置定時器模式為16位自動重裝
  45.         TL0 = 0xCD;                    //設置定時初值
  46.         TH0 = 0xD4;                    //設置定時初值
  47.         TF0 = 0;                    //清除TF0標志
  48.         TR0 = 1;                    //定時器0開始計時
  49.         ET0 = 1;                        //允許T0中斷
  50.    
  51.     P33 = 1;            //設置外部中斷IO口高電平
  52.     IT1 = 1;            //設置INT1的中斷類型為下降沿觸發(fā) (1:僅下降沿 0:上升沿和下降沿)
  53.     EX1 = 1;            //使能INT1中斷

  54.     EA = 1;             //使能全局中斷
  55. }


  56. /******************************
  57. 函數(shù)說明:按鍵短按長按檢測
  58. ******************************/
  59. void Key_scan(void)                 //在定時器T0中斷里每10mS調用一次檢查按鍵狀態(tài)
  60. {
  61.         if(Key1==0)                     //如果按鍵1按下
  62.         {
  63.             uiKeyTimeCnt1++;            //累加按鍵計時
  64.         }
  65.         if(uiKeyTimeCnt1>200 && LongTouchRelease1==1)   //當按鍵超過2秒且此前釋放過一次時
  66.         {
  67.                 LongTouchFlag1 = 1;         //長按標志位置1,用于長按2秒后立即處理長按動作
  68.                 LongTouchRelease1 = 0;      //長按釋放標志置0,表示長按未釋放
  69.         }
  70.         if(Key1==1)                     //當按鍵松開(也可能是抖動彈開)
  71.         {
  72.                 if(uiKeyTimeCnt1>2 && uiKeyTimeCnt1<=200)   //只有大于20mS,且小于2秒,才判為短按
  73.                 {
  74.                         uiKeyTimeCnt1 = 0;      //清零按鍵計時
  75.                         ShortTouchFlag1 = 1;        //短按標志位置1
  76.                         LongTouchFlag1 = 0;     //長按標志位置0        
  77.                 }
  78.                 if(uiKeyTimeCnt1>200)       //如果松開按鍵時按鍵超過2秒,則為長按釋放
  79.                 {
  80.                         uiKeyTimeCnt1 = 0;      //清零按鍵計時
  81.                         LongTouchRelease1 = 1;  //長按釋放標志位置1,表示長按已釋放
  82.                 }        
  83.         }

  84.         if(Key2==0)                     //如果按鍵2按下
  85.         {
  86.             uiKeyTimeCnt2++;            //累加按鍵計時
  87.         }
  88.         if(uiKeyTimeCnt2>200 && LongTouchRelease2==1)   //當按鍵超過2秒且此前釋放過一次時                          
  89.         {
  90.                 LongTouchFlag2 = 1;         //長按標志位置1,用于長按2秒后立即處理長按動作
  91.                 LongTouchRelease2 = 0;      //長按釋放標志置0,表示長按未釋放
  92.         }
  93.         if(Key2==1)                     //當按鍵松開(也可能是抖動彈開)
  94.         {
  95.                 if(uiKeyTimeCnt2>=2 && uiKeyTimeCnt2<=200)  //只有大于等于20mS,且小于2秒,才判為短按
  96.                 {
  97.                         uiKeyTimeCnt2 = 0;      //清零按鍵計時
  98.                         ShortTouchFlag2 = 1;    //短按標志位置1
  99.                         LongTouchFlag2 = 0;     //長按標志位置0        
  100.                 }
  101.                 if(uiKeyTimeCnt2>200)       //如果松開按鍵時按鍵超過2秒,則為長按釋放
  102.                 {
  103.                         uiKeyTimeCnt2 = 0;      //清零按鍵計時
  104.                         LongTouchRelease2 = 1;  //長按釋放標志位置1,表示長按已釋放
  105.                 }        
  106.         }
  107. }


  108. /******************************
  109. 函數(shù)說明:按鍵處理
  110. ******************************/
  111. void Key_process(void)
  112. {
  113.         if(ShortTouchFlag1==1)          //當按鍵1短按標志位為1時進行按鍵1短按處理
  114.         {
  115.                 ShortTouchFlag1 = 0;        //清除短按標志位
  116.         if(MODE==0)                 //常亮模式下按Key1進入聲控模式
  117.         {
  118.             MODE = 1;               //聲控模式
  119.             LED_OFF;                //進入聲控模式后默認先不亮燈
  120.             PWM_SET = 0;
  121.             PWM_COUNT = 0;
  122.             Count_180S = 0;
  123.         }
  124.         else if(MODE==1 || MODE==2) //MODE=1為聲控待觸發(fā)模式,MODE2為聲控已觸發(fā)模式
  125.         {
  126.             MODE = 0;               //進入常亮模式并亮燈
  127.             PWM_SET = LED_Brightness;   //PWM占空比因子調整為亮度設置值
  128.             Count_180S = 0;
  129.         }
  130.         }
  131.         if(LongTouchFlag1==1)           //按鍵1長按處理
  132.         {
  133.                 LongTouchFlag1 = 0;         //清除長按標志位
  134.         //此處可執(zhí)行Key1長按動作
  135.         }        
  136.         if(ShortTouchFlag2==1)          //按鍵2短按處理,功能為亮度設置
  137.         {
  138.                 ShortTouchFlag2 = 0;        //清除短按標志位
  139.         LongTouchFlag2 = 0;         
  140.         LED_Brightness += 3;        //四檔PWM亮度調節(jié),LED_Brightness可取值1、4、7、10分別對10%、40%、70%、100%亮度
  141.         if(LED_Brightness>10)       //亮度達到最大后再按Key2,亮度從1重新開始調整
  142.         {
  143.             LED_Brightness = 1;
  144.         }
  145.         PWM_SET = LED_Brightness;   //PWM占空比因子調整為亮度設置值
  146.         }
  147.         if(LongTouchFlag2==1)           //按鍵2長按處理
  148.         {
  149.                 LongTouchFlag2 = 0;                //清除長按標志位
  150.         //此處可執(zhí)行Key2長按動作
  151.         }
  152. }

  153. /******************************
  154. 函數(shù)說明:主函數(shù)
  155. ******************************/
  156. void main(void)
  157. {
  158.         Init();                         //系統(tǒng)初始化   
  159.         while(1)
  160.         {
  161.                 Key_process();              //調用按鍵處理函數(shù)
  162.         
  163.         if(Flag_1s==1 && MODE==2)   //聲控已觸發(fā)模式觸發(fā)后進行計時并延時3分鐘關燈
  164.         {
  165.             Flag_1s = 0;            //清秒標志位
  166.             Count_180S++;           //秒計數(shù)器加1
  167.             if(Count_180S==170 && PWM_SET>1)
  168.             {
  169.                 PWM_SET = 1;        //離關燈剩余10秒時亮度調至最低即10%
  170.             }
  171.             if(Count_180S>=180)     //聲控點亮3分鐘后自動熄燈
  172.             {
  173.                 Count_180S = 0;
  174.                 PWM_SET = 0;        //亮度調至0%即熄燈
  175.                 MODE = 1;           //重新進入聲控待觸發(fā)模式
  176.             }            
  177.         }      
  178.         }
  179. }


  180. void time0(void) interrupt 1        //T0中斷服務函數(shù),每1ms進入一次
  181. {
  182.     PWM_COUNT++;                    //PWM每1mS為調節(jié)步長,一個周期10mS共10步
  183.    
  184.         if(++Count_10mS>=10)            //每10ms掃描一次按鍵狀態(tài)
  185.     {
  186.         Count_10mS = 0;
  187.         Key_scan();
  188.     }

  189.         if(++Count_1S>=1000)            //每1秒設置一次秒標志位
  190.         {
  191.                 Count_1S = 0;
  192.                 Flag_1s = 1;
  193.         }
  194.    
  195.     if(PWM_COUNT<=PWM_SET)          //控制PWM輸出占空比
  196.     {
  197.         LED_ON;
  198.     }
  199.     else
  200.     {
  201.         LED_OFF;
  202.     }

  203.     if(PWM_COUNT>=10)               //控制PWM周期為10mS,即頻率100Hz
  204.     {
  205.         PWM_COUNT = 0;
  206.     }
  207. }


  208. void exint1() interrupt 2           //INT1外部中斷入口
  209. {
  210.     if(MODE==1)                     //聲控待觸發(fā)模式才執(zhí)行以下動作
  211.     {
  212.         MODE = 2;                   //進入聲控已觸發(fā)模式
  213.         PWM_SET = LED_Brightness;   //亮燈
  214.         PWM_COUNT = 0;
  215.         Count_1S = 0;
  216.         Flag_1s = 0;
  217.     }
  218. }
復制代碼

全部資料51hei下載地址:
聲控小夜燈原理圖PCB和程序全套資料.rar (11.34 MB, 下載次數(shù): 139)



評分

參與人數(shù) 1黑幣 +100 收起 理由
admin + 100 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏17 分享淘帖 頂1 踩
回復

使用道具 舉報

來自 2#
ID:702386 發(fā)表于 2022-1-28 20:20 | 只看該作者
試用了幾天后,優(yōu)化了兩處地方,程序升級為V1.4版。
1. 聲控觸發(fā)亮燈后延時3分鐘自動熄燈,修改為自動熄燈前如果又檢測到聲音,重新計時3分鐘
2. 按鍵從常亮模式切換到聲控待觸發(fā)模式,默認熄燈,但是按鍵的聲音會導致切到聲控待觸發(fā)模式后直接觸發(fā)亮燈,現(xiàn)修改為按鍵切到聲控待觸發(fā)模式后等待1秒鐘才允許被觸發(fā)亮燈

程序 V1.4.rar

43.53 KB, 下載次數(shù): 61, 下載積分: 黑幣 -5

升級程序

回復

使用道具 舉報

板凳
ID:577622 發(fā)表于 2022-1-28 11:37 | 只看該作者
自己動手豐衣足食,DIY精神永垂不朽!
回復

使用道具 舉報

地板
ID:267707 發(fā)表于 2022-1-28 13:02 | 只看該作者

自己動手豐衣足食,DIY精神永垂不朽!
回復

使用道具 舉報

5#
ID:59830 發(fā)表于 2022-1-30 10:22 | 只看該作者
看了一下,資料不錯.值得參考一下.
回復

使用道具 舉報

6#
ID:687881 發(fā)表于 2022-2-16 11:07 | 只看該作者
電池供電的話,STC一直工作著,電流也有5-10MA,一天下來耗電也不少,用上掉電中斷模式就能省不少電了。
回復

使用道具 舉報

7#
ID:702386 發(fā)表于 2022-2-17 08:46 | 只看該作者
kindzhon 發(fā)表于 2022-2-16 11:07
電池供電的話,STC一直工作著,電流也有5-10MA,一天下來耗電也不少,用上掉電中斷模式就能省不少電了。

謝謝你的建議,我后面想想怎么在低功耗方面再優(yōu)化一下。
目前這個燈已經(jīng)試用了一段時間,發(fā)現(xiàn)偶爾出現(xiàn)整夜不能自動關燈的情況,懷疑是有雜波干擾到聲音檢測模塊,現(xiàn)已升級了一版程序,增加了聲控觸發(fā)的過濾機制,要求在1秒內(nèi)有3個以上的中斷脈沖才允許觸發(fā)亮燈,測試幾天后未再發(fā)現(xiàn)不能自動關燈的情況。后面我完善后會分享新版程序。
回復

使用道具 舉報

8#
ID:229641 發(fā)表于 2022-2-23 21:44 來自觸屏版 | 只看該作者
這玩意兒能搞個緩啟動亮度嗎?也就是慢慢的亮起來…
回復

使用道具 舉報

9#
ID:230500 發(fā)表于 2022-3-5 20:35 | 只看該作者
謝謝你的無私分享, 很有學習的意義,
回復

使用道具 舉報

10#
ID:1008454 發(fā)表于 2022-3-6 09:30 | 只看該作者
pcb是關鍵,程序很重要。
回復

使用道具 舉報

11#
ID:702386 發(fā)表于 2022-3-7 08:59 | 只看該作者
auxccc 發(fā)表于 2022-3-6 09:30
pcb是關鍵,程序很重要。

確實PCB很關鍵,我后面再升級的話,會多考慮PCB布局走線的問題,可能還要給聲音檢測部分設計隔離電源或加強濾波,使系統(tǒng)自身尤其是PWM調光部分帶來的干擾影響減小,這樣能進一步提高可靠性和靈敏度。
回復

使用道具 舉報

12#
ID:91721 發(fā)表于 2022-3-9 14:07 | 只看該作者
謝謝你的無私分享,很有愛的一次應用。
回復

使用道具 舉報

13#
ID:430492 發(fā)表于 2022-3-9 14:12 | 只看該作者
pcb可以自己布線,主要是想法很重要。
回復

使用道具 舉報

14#
ID:364201 發(fā)表于 2022-8-25 17:46 | 只看該作者
樓主,這個設計可以改成紅外人體傳感器的方式嗎?
回復

使用道具 舉報

15#
ID:1067504 發(fā)表于 2024-10-27 13:52 來自觸屏版 | 只看該作者
注釋非常詳細,對小白幫助很大,感謝樓主分享!
回復

使用道具 舉報

16#
ID:1133220 發(fā)表于 2024-10-28 15:01 | 只看該作者
感謝樓主分享!借鑒一下。
回復

使用道具 舉報

17#
ID:981787 發(fā)表于 2024-10-30 22:44 | 只看該作者
a399288395 發(fā)表于 2022-3-5 20:35
謝謝你的無私分享, 很有學習的意義,

緩啟動也好弄啊,加個PWM調光
回復

使用道具 舉報

18#
ID:402677 發(fā)表于 2025-5-17 17:26 | 只看該作者
非常實用的作品,謝謝提供的DIY資料,給樓主點贊
回復

使用道具 舉報

19#
ID:1151003 發(fā)表于 2025-5-29 13:13 | 只看該作者
你好,大佬,我是一個小萌新,我看了你的那個led的帖子,想要跟著你復刻一下,但是我有點疑問,我好像不知道從板子的哪里開始燒錄程序,臺燈的底座盒子該怎么設計,才能穩(wěn)定里面的板子和電池
回復

使用道具 舉報

20#
ID:1151003 發(fā)表于 2025-5-29 13:14 | 只看該作者
你好,大佬,我是一個小萌新,我看了你的那個led的帖子,想要跟著你復刻一下,但是我有點疑問,我好像不知道從板子的哪里開始燒錄程序,臺燈的底座盒子該怎么設計,才能穩(wěn)定里面的板子和電池
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表