博客專欄

EEPW首頁 > 博客 > 程序員為女友DIY一款紅外線遙控器,感動哭了

程序員為女友DIY一款紅外線遙控器,感動哭了

發(fā)布人:智能物聯(lián)研習(xí)社 時間:2021-01-09 來源:工程師 發(fā)布文章

身為一位資深電子發(fā)燒友,他經(jīng)常自己動手將家中傳統(tǒng)電器改造成智能電器。此次,該同學(xué)基于涂鴉 IoT 開發(fā)工具,使用涂鴉 WBR1D 云模組、紅外遙控器外殼等器材,借助涂鴉智能紅外遙控開源硬件開發(fā)資料,將家中空調(diào)改造成智能空調(diào),可通過手機(jī) App 輕松控制。

以下內(nèi)容為涂鴉開發(fā)者“李勇”創(chuàng)作,經(jīng)其授權(quán)編輯發(fā)布:


參加此次涂鴉智能&立創(chuàng)EDA實戰(zhàn)訓(xùn)練營,要求做物聯(lián)網(wǎng)相關(guān)項目,使用涂鴉的云模組。一提到云,我最先想到的是智能家居,自己平時工作之余,也做了不少與物聯(lián)網(wǎng)相關(guān)的項目,做的大大小小的項目不少,家里電器差不多都自己動手改造成智能的。

正好最近有做紅外遙控空調(diào)的想法。冬天來了,早上起床太早都不敢掀被子(太冷),一直想改造成智能的,用手機(jī)控制,支持定時開啟/關(guān)閉,智能場景聯(lián)動。加上工作原因,有涂鴉智能的云開發(fā)需求,所以參加此次訓(xùn)練營。

功能設(shè)計

要實現(xiàn)空調(diào)控制,就是要發(fā)送紅外信號,所以要有紅外發(fā)送功能。市面上空調(diào)種類繁多,肯定要適用多種品牌和機(jī)型,所以要有紅外學(xué)習(xí)功能。要支持場景聯(lián)動,就要有環(huán)境感知傳感器。要支持手機(jī)控制,就要有云端和模組。

綜上,設(shè)計功能有:

1、紅外發(fā)送(紅外****管);

2、紅外學(xué)習(xí)(一體化接收頭);

3、室內(nèi)溫度檢測(DHT11);

4、手機(jī)控制(通過涂鴉云模組實現(xiàn))。

成品效果

在實際場景中,空調(diào)的安裝位置一般都不固定,所以,紅外控制器不能近距離控制。參考其他大品牌紅外控制器設(shè)計,采用壁掛式設(shè)計,可以掛在天花板或墻壁上。

控制板全部用立創(chuàng)EDA繪制,自己手工貼片,涂鴉云模組上面的文字是被清洗劑洗掉了,操作時大意了。


使用的公模外殼,安裝效果如下。


硬件設(shè)計

1.電源

電源部分采用Micro USB接口,直接提供5V電源,經(jīng)過內(nèi)部分壓得到3.3V電壓,為MCU、涂鴉云模組和外圍電路供電。降壓采用TI的TLV62569DBVR電源芯片,外圍器件少,功率大,紋波小。


2.云模組

采用涂鴉智能提供的WBR1D-IPEX云模組,WBR1D是雙頻雙模模組,支持WI-FI和藍(lán)牙,采用MCU接入方案,通過串口與MCU連接。


3.MCU

MCU采用ST的STM32F103C8T6,64K的Flash。

4.紅外****

紅外****采用紅外管,因為是壁掛式安裝方式,所以對控制范圍有要求,本設(shè)計中采用8顆紅外****管并聯(lián),每科管子由一顆大功率三極管驅(qū)動,所有三極管由一個控制端驅(qū)動。以提高****功率,提高****功率后,紅外控制范圍會明顯擴(kuò)大。(多顆紅外管最好并聯(lián)控制,不要為畫PCB方便或者節(jié)省器件而選擇串聯(lián),串聯(lián)的管子都不會正常工作,****功率會大幅度下降。)


5.紅外接收

紅外接收比較簡單,直接采用一體化接收頭。


6.附加電路

按鍵

按鍵用于配網(wǎng)使用,但是在實際調(diào)試時,模組會自動配網(wǎng),所以按鍵改為清除紅外預(yù)存的數(shù)據(jù)。

LED

LED用于指示配網(wǎng)狀態(tài)和進(jìn)入紅外學(xué)習(xí)模式,以及故障閃爍。

DHT11

DHT11用于檢測室內(nèi)溫濕度,在本設(shè)計中,紅外遙控器作為單品使用,DHT11可以向云端上報室內(nèi)溫度、濕度,可實現(xiàn)智能場景聯(lián)動。

7.PCB設(shè)計

PCB設(shè)計時,因為是壁掛式,所以選了一個公模外殼。在設(shè)計時器件布局和PCB外形要符合外殼尺寸。

外殼:


PCB:初版PCB有幾個錯誤,按鍵位置與LED位置反了,絲印錯誤,已經(jīng)更新。


軟件設(shè)計

1.紅外接收實現(xiàn)

紅外接收比較簡單,如果是易于解析的NEC格式編碼,直接用定時器捕獲外部輸入電平時間長度即可,對于不易解析的編碼(廠家自定義的編碼)采用外部中斷和定時器方式測電平時間長度。對于NEC格式編碼,按照NEC編碼格式的規(guī)范,先判斷低電平時間,通過長度區(qū)分起始碼、數(shù)據(jù)碼和結(jié)束碼。網(wǎng)上例程比較多,這里就不贅述了,要注意的是:有的廠家空調(diào)雖然是NEC編碼,但是他們的編碼中高低電平長度一般都不同,所以在中斷中判斷電平長度時,要注意設(shè)置范圍。

2.紅外****實現(xiàn)

紅外****是紅外管完成,注意:紅外管不****紅外在接收端輸出1,****紅外在接收端輸出是0,這里要注意區(qū)分。

實現(xiàn)方式用定時器輸出一個38K的方波,控制方波輸出的時間長度即可實現(xiàn)發(fā)送不同的數(shù)據(jù)和編碼。本項目采用兩個定時器來實現(xiàn)發(fā)送紅外,TIM1輸出38K載波,TIM3定時,由TIM3計時,控制TIM1輸出/關(guān)閉PWM,這樣可以實現(xiàn)任意時間長度發(fā)送。但是這樣比較耗費MCU資源,對于STM32來說,影響不大,對于小型MCU就要考慮資源了。

下面是實現(xiàn)紅外發(fā)送的關(guān)鍵代碼:

發(fā)送一組完整紅外編碼Inf_RX_NECcoding()

void Inf_RX_NECcoding(uint8_t *pbuff,uint8_t Length,uint8_t quantity){    uint8_t i;
    TIM_CtrlPWMOutputs(TIM1,ENABLE);  //開輸出
    TIM_Cmd(TIM3,ENABLE);  //開定時器
    TIM_Cmd(TIM1,ENABLE);    
  while(Inf_RX_StartCode()); //起始碼
    
    if(Length>InfraredDataLength)  //數(shù)據(jù)有效長度限制
        Length = InfraredDataLength;  
    
    for(i=0;i<Length;i++)    //發(fā)送數(shù)據(jù)
      Inf_RX_Data(pbuff[i],Right); 
    
    while(Inf_RX_Stop());  //結(jié)束碼
    
    while(Inf_RX_Interval()); //間隔碼
    
    while(Inf_RX_StartCode());  
    
    if(Length>InfraredDataLength)
        Length = InfraredDataLength; 
    
    for(i=0;i<Length;i++)
      Inf_RX_Data(pbuff[i],Right); 
    
    while(Inf_RX_Stop());  
    
    for(i=0;i<quantity;i++)  //重復(fù)發(fā)送
    while(Inf_SendRepeatedly());
    
    TIM_CtrlPWMOutputs(TIM1,DISABLE);  //關(guān)輸出    
    TIM_Cmd(TIM3,DISABLE);  //關(guān)定時器
    TIM_Cmd(TIM1,DISABLE);
}

數(shù)據(jù)發(fā)送(1個8位)

uint8_t Inf_RX_StartCode(void)
{    if(!retemp)
    {
        retemp=1;
        TimerOclk=0;
        TIM_SetCompare1(TIM1,1100); //設(shè)置占空比為50%         
    }    if(TimerOclk==441) //低電平時間到
        TIM_SetCompare1(TIM1,0); //設(shè)置占空比為0
    if(TimerOclk==881) //高電平時間到
    {
        retemp=0;
        TimerOclk=0; 
    }    return retemp; //狀態(tài)返回   }

3.紅外學(xué)習(xí)功能

本項目中只實現(xiàn)NEC編碼紅外學(xué)習(xí),當(dāng)按下手機(jī)端空間時,如果沒有指令,會自動進(jìn)入學(xué)習(xí)狀態(tài),等待發(fā)送紅外指令。紅外指令接收到以后,會自動保存。

4.云功能實現(xiàn)

因為使用涂鴉的MCU接入方案,云端只做功能和APP界面的配置,并下載MCU的SDK,將SDK移植到代碼中即可

云端功能配置:


APP界面配置:


5.防跑飛

在實際測試過程中遇到了,設(shè)備掉線和控制無反應(yīng)問題,起初以為是網(wǎng)絡(luò)問題,更換網(wǎng)絡(luò)以后,問題依舊存在。

拆下板子發(fā)現(xiàn)整個PCB發(fā)燙,測量MCU供電只有接近2V左右,照理說可以正常工作。拔掉電源,重插,MCU供電恢復(fù)。

等待問題再次出現(xiàn)時,測得紅外管驅(qū)動三極管控制端一直是低電平,問題發(fā)現(xiàn)了:8顆紅外****管的****功率比較大,在關(guān)閉輸出時可能是被中斷打斷,導(dǎo)致關(guān)斷不成功,紅外管一直處于發(fā)送狀態(tài),時間一長,8顆紅外管總電流增大,提供給MCU的電流減小,出現(xiàn)假死現(xiàn)象。

為了解決這個問題,增加了三道防線,一是每次發(fā)送完成后將輸出和定時器一起關(guān)閉,這樣可以減少中斷沖突的機(jī)率。二是增加STM32內(nèi)部測溫,一旦檢測到溫度超過允許值,再關(guān)定時器和PWM輸出1次,如果超過警報值,直接復(fù)位MCU。三是增加看門狗,定時喂狗,防止假死和程序跑飛。

加上這三道防線后,實測問題不再發(fā)生。

關(guān)鍵點分析

1.MCU_SDK 移植

涂鴉提供配套的MCU SDK,具體使用方式涂鴉也提供很多的文檔,b站也有很多案例。我們只需要移植到MCU中即可,通過串口通訊,實現(xiàn)MCU接入。注意接涂鴉模組串口的波特率,一般默認(rèn)是9600,也可以修改為115200,具體在云端控制臺的硬件開發(fā)->模組固件中修改。在移植時有以下幾個地方要注意:

**mcu_api.c**

1)串口接收函數(shù)uart_receive_input(),要用中斷法接收,防止數(shù)據(jù)丟包

涂鴉提供串口數(shù)據(jù)接收緩存和數(shù)據(jù)處理方法,我們不需要再單獨去做處理,只需要在串口接收中斷里面調(diào)用uart_receive_input()函數(shù)即可。

//USART2中斷服務(wù)函數(shù)void USART2_IRQHandler(void)                {
  uint8_t value ;  if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中斷
    {   value = USART_ReceiveData(USART2);   //讀取接收數(shù)據(jù)        
     uart_receive_input(value); //數(shù)據(jù)存入涂鴉緩沖器
    }       
}

2)數(shù)據(jù)輪詢函數(shù)wifi_uart_service(),要輪詢這個函數(shù),不然模組下發(fā)的數(shù)據(jù)MCU接收不到。放在主循環(huán)里面就行。

while (1)
{       
    wifi_uart_service(); //輪詢涂鴉數(shù)據(jù)
    /*
      用戶其他函數(shù)
    */}

3)協(xié)議初始化函數(shù)wifi_protocol_init(),這是為涂鴉串口數(shù)據(jù)提供一個緩存空間,在初始化中調(diào)用,初始化后不需要再調(diào)用。

int main(void){   
    wifi_protocol_init(); //涂鴉模組協(xié)議初始化
    /*
      用戶其他初始化函數(shù)
    */
    while(1)
    {
       wifi_uart_service(); //輪詢涂鴉數(shù)據(jù)
    /*
      用戶其他函數(shù)
    */          
    }
}

**protocl.c**

1)串口發(fā)送函數(shù)uart_transmit_output(),用調(diào)用法發(fā)送,也可以用中斷。

涂鴉提供串口發(fā)送數(shù)據(jù)處理方法,我們也不需要再單獨去做處理,只需要將串口發(fā)送語句放在uart_transmit_output()函數(shù)里即可。

void uart_transmit_output(unsigned char value){ 
  while((USART2->SR &(1<<7))==0);  
    USART2->DR = value;
}

2)所有數(shù)據(jù)上報函數(shù)all_data_update()

我們要在all_data_update函數(shù)中實現(xiàn)設(shè)備數(shù)據(jù)的傳入,涂鴉模組或向MCU申請返回設(shè)備全部數(shù)據(jù),設(shè)備數(shù)據(jù)通過all_data_update函數(shù)發(fā)送,所以要把設(shè)備的數(shù)據(jù)項傳入到對應(yīng)的函數(shù)中。注意:這個函數(shù)根據(jù)自己云端定義的功能對應(yīng),不能直接添加。

void all_data_update(void)
{   
    //此代碼為平臺自動生成,請按照實際數(shù)據(jù)修改每個可下發(fā)可上報函數(shù)和只上報函數(shù)  
    mcu_dp_bool_update(DPID_SWITCH,AirControlStructure.AirPowerControl); //BOOL型數(shù)據(jù)上報; //當(dāng)前開關(guān)
    mcu_dp_value_update(DPID_TEMP_SET,AirControlStructure.AirRunTemper); //VALUE型數(shù)據(jù)上報;  //當(dāng)前溫度設(shè)置    //    mcu_dp_value_update(DPID_TEMP_CURRENT,AirControlStructure.AirRunTemper); //VALUE型數(shù)據(jù)上報;  //當(dāng)前當(dāng)前溫度  
    mcu_dp_enum_update(DPID_MODE,AirControlStructure.AirRunMode); //枚舉型數(shù)據(jù)上報; //當(dāng)前工作模式   
    mcu_dp_enum_update(DPID_FAN_SPEED_ENUM,AirControlStructure.AirRunFan); //枚舉型數(shù)據(jù)上報; //當(dāng)前風(fēng)速    //    mcu_dp_enum_update(DPID_STATUS,AirControlStructure.AirRunFlag); //枚舉型數(shù)據(jù)上報;  //當(dāng)前狀態(tài)    
    mcu_dp_bool_update(DPID_AUTO,AirControlStructure.AirForceful); //BOOL型數(shù)據(jù)上報; //當(dāng)前自動模式    
    mcu_dp_bool_update(DPID_HEAT,AirControlStructure.AirHeat); //BOOL型數(shù)據(jù)上報;  //當(dāng)前輔熱  }

3)單個數(shù)據(jù)下發(fā)處理函數(shù),在protocl.c中涂鴉定義了與功能對應(yīng)的處理函數(shù),我們要在對應(yīng)函數(shù)中實現(xiàn)控制代碼。示例

static unsigned char dp_download_switch_handle(const unsigned char value[], unsigned short length)    //開關(guān){    //示例:當(dāng)前DP類型為BOOL
    unsigned char ret;    //0:關(guān)/1:開
    unsigned char switch_1;
    
    switch_1 = mcu_get_dp_download_bool(value,length);    if(switch_1 == 0) {
        AirControlStructure.AirPowerControl=OFF;//關(guān)
        AirControlStructure.AirHeat = OFF;       //輔熱關(guān)
        AirControlStructure.AirForceful = OFF;   //強(qiáng)勁關(guān)
    }else {
        AirControlStructure.AirPowerControl=ON; //開         
    }       
    AirControlInfRX(); //發(fā)送紅外代碼
  
    //處理完DP數(shù)據(jù)后應(yīng)有反饋
    ret = mcu_dp_bool_update(DPID_SWITCH,switch_1);    if(ret == SUCCESS)        return SUCCESS;    else
        return ERROR;
}

其實MCU接入方案,就是串口通訊。涂鴉提供有SDK,在云端定義好功能,配置好固件和APP面板,下載SDK包,移植到MCU代碼中就可以用,不要單獨做函數(shù)設(shè)置配網(wǎng),上云等繁瑣的工序。這對產(chǎn)品研發(fā)者來講,不管是測試,還是研發(fā),都是非常友好的。

2.空調(diào)控制

以上工作完成后,重點來了,代碼寫得再漂亮,電路設(shè)計再完美,控制不了空調(diào)都等于0。大家都知道空調(diào)是紅外遙控控制,所以本項目就是****空調(diào)遙控器****的紅外編碼,代替遙控器控制空調(diào)。這里的難點在于如何獲得空調(diào)的紅外編碼,目前市面上銷售的空調(diào),紅外編碼都是廠家自定義的。售后或者說明書里面也不會提供具體的編碼協(xié)議,所以只能自己去解析。下面簡述解析過程,解析篇幅較多,詳細(xì)內(nèi)容請移步“閱讀原文”。

首先要獲得紅外的編碼,我的方式是用邏輯分析儀和紅外接收頭,按遙控器的一個鍵,查看分析儀捕獲的波形,通過波形解析出數(shù)據(jù),這個過程不難,但是很繁瑣。


以開機(jī)為例,按下開機(jī)鍵,遙控器發(fā)送一組紅外編碼,邏輯分析儀捕獲到波形,如圖


重復(fù)按下開機(jī)鍵,每次分析儀捕獲的波形都相同,將波形放大后打印,如圖:


這就是完整的一組紅外波形,我只要發(fā)送與這組波形一樣的編碼即可控制空調(diào)開機(jī)。但是現(xiàn)在只是知道了電平變換時間,具體變換的時間長度代表什么還不知道。但是通過這組完整的波形可以看出,它是符合NEC編碼格式(不了解NEC紅外編碼格式的,請先查查相關(guān)資料),只是電平變換時間長度略有不同而已,所以先嘗試用NEC編碼接收程序試一下。通過NEC編碼紅外接收程序測試,發(fā)現(xiàn)能夠接收到數(shù)據(jù):


那么現(xiàn)在直接發(fā)送這組紅外數(shù)據(jù),就能控制空調(diào)開機(jī)。但是實測沒有辦法控制,空調(diào)無反應(yīng)。反過來查看邏輯分析儀捕獲的波形,這個波形與標(biāo)準(zhǔn)NEC編碼的****波形除了高低電平變換時間長度不同,總長度也不同。細(xì)看這個開機(jī)波形,它的前半部分和后半部分是相同,按照NEC格式截取前后半個部分波形,

前半部分:


后半部分:


驚奇發(fā)現(xiàn)它們的起始碼、數(shù)據(jù)碼是相同的,結(jié)束碼略有不同,由此可以看出,這個紅外編碼是由兩幀構(gòu)成,兩幀之間有一個中間碼,是連接以及第一幀和第二幀用的。將第一幀波形、第二幀波形和完整波形,得到中間碼的波形。


通過邏輯分析儀得出,中間的電平變化時間關(guān)系:



由此,解析出起始碼、數(shù)據(jù)碼、中間碼和結(jié)束碼的電平變化時間間隔,按照解析的接收重新定義紅外發(fā)送函數(shù),測試能正常開機(jī)。

3.App功能配置

App界面除了默認(rèn)功能外,加了部分功能,因為使用的公版APP界面,所以界面UI和功能自定義的范圍有限,后期會改成面板SDK開發(fā),現(xiàn)階段時間不多,做不了開發(fā)。

以強(qiáng)勁功能為例,本項目設(shè)計時,沒有添加強(qiáng)勁功能?,F(xiàn)在要添加,首先進(jìn)入涂鴉IoT開發(fā)平臺,找到項目,進(jìn)入APP面板配置頁面,在頁面點擊“編輯”,


進(jìn)入編輯頁面,先選擇按鈕添加的位置,這里添加到更多頁面


配置好屬性和關(guān)聯(lián)功能以后,點擊發(fā)布,涂鴉會自動打包,打包好了以后,會提供測試二維碼,掃二維碼可以測試這個面板,如果測試通過點正式發(fā)布,發(fā)布以后,手機(jī)端退出“涂鴉智能”APP,重新進(jìn)入,添加的功能就生效。

總結(jié)

這次使用涂鴉智能,不管是整體開發(fā)流程,還是技術(shù)服務(wù),涂鴉做得非常好。

涂鴉模組提供MCU SDK,用戶只需要移植到MCU OS中,即可完成上云操作,節(jié)省研發(fā)和調(diào)試周期。

涂鴉提供的穩(wěn)定MCU接入模組SDK,減少用戶程序邏輯架構(gòu)不嚴(yán)謹(jǐn)造成的錯誤,減輕用戶底層代碼量。

涂鴉技術(shù)支持服務(wù)也非常周到,不定期詢問開發(fā)者是否有問題需要解決,這點比某科模組做的好。

如果想自己親自動手DIY的,可以戳:

https://auth.tuya.com/?_source=7c8653b7bd61bf9239a1a6c12e52124d


還在等什么!為女友DIY創(chuàng)造一個溫暖舒適的家居生活,低成本改造自家空調(diào)可真是真香系列~撒花~建議:涂鴉能開放模組的二次服務(wù),為開發(fā)者和物聯(lián)網(wǎng)設(shè)備廠商提供更多的自定義服務(wù)和功能,相信會受到更多開發(fā)者和物聯(lián)網(wǎng)愛好者的青睞。


*博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。



關(guān)鍵詞: 嵌入式 工程師

相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉