日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

【STM32 .Net MF开发板学习-14】红外遥控器编码识别

發布時間:2025/4/16 asp.net 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【STM32 .Net MF开发板学习-14】红外遥控器编码识别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一年前我寫過一篇博文《自制電腦紅外遙控接收器(PC軟解碼)》,文中介紹借助幾個簡單的器件通過PC串口,來獲取紅外遙控器的按鍵信息?,F在我們已經學會了如何用PWM技術驅動智能小車(參見《用PWM驅動智能小車),正好缺少一個遙控機制,所以本篇文章先介紹一下,.NET Micro Framework開發板如何獲取紅外遙控信息,下一篇文章將介紹用遙控器驅動智能小車相關實現細節。

??? 這次我們紅外接收的硬件電路更為簡單,僅需紅外接收頭、兩個電阻,一個電容即可,其原理圖如下:???

??

???? 我所選取的具體器件型號如下:

?1100歐電阻

218K歐電阻

3、電容1040.1uF

4、HS0038A紅外接收頭

??? 5、電壓接入3.3v

??? 實際的器件連接圖如下:???

????? ??

?? ??以上是紅外接收部分,至于紅外發送,我想每個家庭基本上都會有電視遙控器(此外還有機頂盒遙控器,DVD遙控器、空調遙控器等等),我的想法是紅外接收設備可以接收任何紅外遙控器發出的按鍵信息,這樣用戶就不需要再采購相關的遙控器設備了。???

?

?但是非常困難的是,電視遙控器廠家不同,型號各異,其紅外遙控編碼更是千差萬別,如果一一對其解碼,不僅工作量巨大,并且實際操作上不甚可能,因為短時間內也無法獲取這些遙控器進行解碼測試。

遙控器所發送的功能指令碼一般采用多位二進制串行碼,其編碼規律為:頭脈沖、系統碼、資料碼、資料反碼和結束位。頭脈沖用做一幀命令的起始位;系統碼用于區別不同類的電器;資料碼用于完成命令功能。不過這僅僅是一般規律,對有些遙控器適用,對另一類就不適用。

所以綜上,我還是借鑒了我一年前所寫的那篇文章中的思想,采集紅外遙控器的按鍵特征(高低電平持續時間的集合)來識別紅外遙控器按鍵,這樣就繞過了對紅外遙控器進行解碼的難點,程序只需要比對按鍵特征就可以識別紅外按鍵(需要預先采集并存儲按鍵特征)。

紅外信號采集的底層代碼如下:

void IR_GPIO_ISR( GPIO_PIN Pin, BOOL PinState, void* Param )

{

???? if(!IR_RunFlag)

???? {

??????? IR_RunFlag = TRUE;

???????? ???IR_Count = 0;

???????? ???IR_DataCount=0;

???????? ???IR_Index = 0;

???????? ???IR_Time[IR_Index]=0;

???????? ???IR_PinState = CPU_GPIO_GetPinState(IR_Pin);????? ?

???????? ???CPU_TIMER_Start(IR_Timer);

???? }

}

void IR_TIMER_ISR(void* param)

{

?if(++IR_Time[IR_Index]>100 || IR_Index>250)

?{

??? CPU_TIMER_Stop(IR_Timer); ??

???????? IR_RunFlag=FALSE;?

???????? IR_Count = IR_Index;

???????? if(IR_DataCount==0)

??? {

?????? memcpy(IR_TimeData,IR_Time,IR_Count);

???????? ?? //GenerateEvent(0xF1,IR_Count);?//產生事件

???????? ?? IR_DataCount=IR_Count;

??? }

???????? return;

?}???

?if(IR_PinState != CPU_GPIO_GetPinState(IR_Pin))

?{

????? IR_PinState=!IR_PinState;

????? IR_Time[++IR_Index]=0;

?}

}

INT8 IRController::Initialize( UINT8 param0, INT32 param1, HRESULT &hr )

{

??? if(param0>7 || IR_Pin<0) return -1;

??? IR_Timer = param0;

??? IR_Pin = (GPIO_PIN)param1;?

??? CPU_GPIO_EnableInputPin(IR_Pin, TRUE, IR_GPIO_ISR, GPIO_INT_EDGE_LOW, RESISTOR_PULLUP);

??? //36M 100us

??? CPU_TIMER_Initialize(IR_Timer,360,9,IR_TIMER_ISR,NULL);??????

??? return 0;

}

INT8 IRController::Uninitialize( UINT8 param0, INT32 param1, HRESULT &hr )

{

???? CPU_TIMER_Stop(IR_Timer);???????

???? CPU_GPIO_DisablePin(IR_Pin,RESISTOR_DISABLED,FALSE,GPIO_ALT_MODE_0);

??? return 0;

}

INT32 IRController::GetData( CLR_RT_TypedArray_UINT8 param0, INT32 param1, HRESULT &hr )

{

??? if(param1>250 || param1>param0.GetSize()) return -1;

??? for(int i=0;i<param1;i++)

??? {

?????? param0.SetValue(i,IR_TimeData[i]);

??? }

???????? IR_DataCount = 0;

??? return 0;

}

INT32 IRController::GetCount( HRESULT &hr )

{

??? return IR_DataCount;

}

其托管代碼封裝接口如下:

??? public sealed class IRController

??? {

??????? public IRController(byte timer, int pin);

??????? public event IRController.IREventHandler IREvent;

??????? public delegate void IREventHandler(byte[] buff, DateTime time);

}

其接口非常簡單,聲明類時填入的參數,第一個是timer,定時器號(0~7),第二個就是紅外接收頭輸出管腳所接的開發板主芯片Pin腳。

此外就是一個接收事件,一旦接收到紅外數據,則通過這個事件輸送給用戶程序。

為了便于識別相關按鍵,我在用戶程序中提供了一個鍵識別類,用戶只需要填入相關按鍵的識別碼(也就是IREvent事件所提供的紅外數據),既可以判斷出按鍵名稱。需要注意的是,有些遙控器奇數次和偶數次按鍵其輸出的編碼不同。

public class IRData

??? {

??????? //按鍵數據

??????? static byte[] bytForward0 = new byte[] { 18, 18, 18, 17, 37, 16, 18, 18, 18, 17, 18, 18, 17, 36, 36, 17, 18, 17, 19, 17, 18, 17, 19 };

??????? static byte[] bytForward1 = new byte[] { 18, 18, 36, 17, 18, 17, 18, 18, 17, 18, 18, 18, 17, 36, 35, 18, 18, 17, 18, 18, 18, 17, 18 };

??????? static byte[] bytLeft0 = new byte[] { 18, 18, 17, 18, 37, 16, 19, 17, 18, 17, 19, 17, 18, 17, 18, 36, 36, 16, 19, 17, 18, 36, 17 };

??????? static byte[] bytLeft1 = new byte[] { 19, 17, 36, 17, 18, 17, 19, 17, 18, 17, 19, 17, 18, 17, 18, 35, 37, 16, 19, 17, 18, 35, 18 };

??????? static byte[] bytRight0 = new byte[] { 18, 18, 17, 18, 37, 16, 18, 18, 18, 17, 18, 18, 17, 18, 18, 36, 36, 16, 19, 17, 17, 18, 18 };

??????? static byte[] bytRight1 = new byte[] { 18, 18, 36, 17, 18, 17, 18, 18, 18, 17, 18, 18, 17, 18, 18, 36, 36, 16, 18, 18, 18, 17, 18 };

??????? static byte[] bytStop0 = new byte[] { 18, 18, 17, 18, 37, 16, 18, 18, 18, 17, 18, 18, 17, 18, 18, 18, 18, 35, 17, 18, 37, 34, 18 };

??????? static byte[] bytStop1 = new byte[] { 18, 18, 36, 17, 18, 17, 18, 18, 17, 18, 18, 18, 17, 18, 18, 18, 17, 36, 17, 18, 37, 34, 18 };

??????? static byte[] bytBack0 = new byte[] { 18, 18, 18, 17, 37, 16, 19, 17, 18, 17, 19, 17, 18, 35, 36, 17, 18, 17, 19, 17, 18, 35, 18 };

??????? static byte[] bytBack1 = new byte[] { 18, 18, 36, 17, 18, 17, 19, 17, 18, 17, 18, 18, 18, 35, 36, 17, 18, 17, 19, 17, 18, 35, 18 };

??????? public enum Key

??????? {

??????????? None = 0,

??????????? Forward,

??????????? Left,

??????????? Right,

??????????? Back,

??????????? Stop,

??????? };

??????? //檢測按鍵數據

??????? private static bool CheckData(byte[] data, byte[] flag, int count)

??????? {

??????????? if (data.Length != flag.Length || data.Length != count) return false;

??????????? for (int i = 0; i < count; i++)

??????????? {

??????????????? if (System.Math.Abs(data[i] - flag[i]) > 3) return false;

??????????? }

??????????? return true;

??????? }

??????? //檢測遙控器按鍵

??????? public static Key GetKey(byte[] buff)

??????? {

??????????? if (CheckData(buff, bytForward0, bytForward0.Length)) return Key.Forward;

??????????? if (CheckData(buff, bytForward1, bytForward1.Length)) return Key.Forward;

??????????? if (CheckData(buff, bytLeft0, bytLeft0.Length)) return Key.Left;

??????????? if (CheckData(buff, bytLeft1, bytLeft1.Length)) return Key.Left;

??????????? if (CheckData(buff, bytRight0, bytRight0.Length)) return Key.Right;

??????????? if (CheckData(buff, bytRight1, bytRight1.Length)) return Key.Right;

??????????? if (CheckData(buff, bytBack0, bytBack0.Length)) return Key.Back;

??????????? if (CheckData(buff, bytBack1, bytBack1.Length)) return Key.Back;

??????????? if (CheckData(buff, bytStop0, bytStop0.Length)) return Key.Stop;

??????????? if (CheckData(buff, bytStop1, bytStop1.Length)) return Key.Stop;

??????????? return Key.None;

??????? }

?}

示例中所用的遙控器是Philips的一款,其編碼較短,僅23個,而其它遙控器一般都有60多個數據。

IRController的具體使用示例如下:

public static void Main()

??????? {

??????????? IRController IR = new IRController(3, (int)GPIO_NAMES.PB12);

??????????? IR.IREvent += new IRController.IREventHandler(IR_Click);???????????????

??????????? while (true)

??????????? {

??????????????? Thread.Sleep(1000);

??????????? }

??????? }?????

??????? static void IR_Click(byte[] buff, DateTime time)

??????? {

??????????? IRData.Key key = IRData.GetKey(buff);

??????????? if (key != IRData.Key.None)

??????????? {

??????????????? string KeyName = "";

??????????????? switch (key)

??????????????? {

??????????????????? case IRData.Key.Forward:

??????????????????????? KeyName = "Forward";

??????????????????????? break;

??????????????????? case IRData.Key.Left:

??????????????????????? KeyName = "Left";

??? ????????????????????break;

??????????????????? case IRData.Key.Right:

??????????????????????? KeyName = "Right";

??????????????????????? break;

??????????????????? case IRData.Key.Back:

??????????????????????? KeyName = "Back";

??????????????????????? break;

??????????????????? case IRData.Key.Stop:

??????????????????????? KeyName = "Stop";

??????????????????????? break;

??????????????? }????????

??????????????? Debug.Print(KeyName);

??????????? }

??????????? else

??????????? {

??????????????? //打印按鍵數據

??????????????? string Info = "";

??????????????? for (int i = 0; i < buff.Length; i++)

??????????????? {

??????????????????? Info += buff[i].ToString() + ",";

??????????????? }

??????????????? Debug.Print("[" + buff.Length.ToString() + "]" + Info);

??????????? }

?? }

程序編譯部署后,按紅外遙控器按鍵,開發板在超級終端的輸出如下圖所示(已經輸入按鍵標識的按鍵,按鍵后其輸出信息就是按鍵名了):

?

???? 好了,我們已經可以成功接收紅外信號了,并且可以正確識別我們標定的按鍵了,這樣我們就可以驅動智能小車前后左右移動了,相關內容敬請關注下篇博文。

???? 文中相關器件:

http://item.taobao.com/auction/item_detail.htm?item_num_id=7660457192

?? 注:需要紅牛開發板固件在 V1.0.0以上

本文源碼:http://www.sky-walker.com.cn/yefan/MFV40/SourceCode/IRTest.rar

?

MF中文討論組:http://space.cnblogs.com/group/MFSoft/

微軟官方論壇:MSDN微軟中文技術論壇(.NET Micro Framework)

開發板簡明手冊:http://blog.sina.com.cn/s/blog_6b938f630100kh0k.html

【低價開發板】http://item.taobao.com/item.htm?id=7117999726

轉載于:https://blog.51cto.com/yfsoft/397260

總結

以上是生活随笔為你收集整理的【STM32 .Net MF开发板学习-14】红外遥控器编码识别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。