iOS耳機紅外線遙控器

前言

目前家裏很多家用電器都是使用紅外線遙控的,如果知道這些遙控器的紅外編碼,就可以使用手機利用手機的耳機口輸出紅外信號,從而把手機變成紅外遙控器。目前輸出紅外信號可以通過一個紅外發光二極管來實現。這個紅外發光二極管可以自己手動做
這裏寫圖片描述
(網上找的,侵刪)
也可以在淘寶上買一個
這裏寫圖片描述
硬件原理可以參考這篇文章
http://www.icpcw.com/Smartphone/Android/Skill/3234/323495_all.htm

原理

任何紅外線的信號都是可以由一串二進制編碼翻譯表達出來的,手機通過外設或內部遙控模塊電壓信號都可以傳遞出一串含有二進制編碼信息,轉化爲紅外遙控器的紅外線發射出來。在消費類電子紅外遙控系統中,紅外信號的載波頻率一般都是38KHz的正弦波。在發送載波之前,首先要確定正弦波的頻率,產生音頻的採樣率,採樣點的位數等信息。一般手機耳機音頻口輸出的音頻頻率應該在19kHz左右,根據採樣定律

在進行模擬/數字信號的轉換過程中,當採樣頻率fs.max大於信號中最高頻率fmax的2倍時(fs.max>2fmax),採樣之後的數字信號完整地保留了原始信號中的信息,一般實際應用中保證採樣頻率爲信號最高頻率的2.56~4倍;採樣定理又稱奈奎斯特定理。

信號調試方式,有脈衝寬度調製(PWM)和脈衝位置調製(PPM)等方法,大多的家用電器使用PPM調製方式。
即發送脈衝信號和不發送脈衝信號分別表示0和1,當然也可能相反。

如果發送載波的頻率是19kHz,那麼採樣率至少應該是44100.採樣點數位數是16位。做法就是通過通過紅外碼算出載波的值,然後添加一個WAV頭,通過耳機孔發出去。

紅外波形碼的獲得

紅外碼的獲得一個方法是可以通過是將「遙控精靈」輸出的音頻錄音下來。硬件連接是使用一個公公的耳機插頭將「遙控精靈」輸出的按鍵波形錄製下來,可以通過軟件Audacity錄下來,計算波形的時間間隔。
網上也有專門的公司出售遙控器的紅外碼,這個比較方便。下面就是海信電視的開關功能的紅外波形碼(這個紅外碼是時間碼)

[8985,4481,578,555,578,555,578,555,578,555,578,555,578,555,578,555,578,555,578,1688,578,1688,578,1688,578,1688,578,1688,578,1688,578,555,578,1688,578,1688,578,555,578,1688,578,1688,578,555,578,555,578,556,578,555,578,555,578,1688,578,555,578,555,578,1688,578,1688,578,1688,578,1688,578,40734,8985,2242,578,96165]

軟件實現

下面就以實現遙控器的開關功能來看一下iOS如何實現遙控功能

#define kNum 0.0441  //1微妙採樣的點數
#define KAmplitude 32767
#define kFrequency 19000
#define KSampleRate 44100 //採樣率

由於每個採樣點16個bit來保存,所以正弦波的振幅最高就是32767.由於採樣率是44100,那麼一個微妙採樣點的就是0.0441,那麼每個時間碼之內的點數就是時間0.0441.例如上面這個開關碼的第一個時間碼是8985微妙,那麼這個時間內的採樣點數8985*0.0441= 396個點。
而正弦波產生就是利用正弦曲線函數

y=Asin(ωx+φ)+k

在這裏A是 32767,ω的值爲2π/19000, φ爲0. x的值爲j/44100,j爲採樣的序號。而爲了產生一個直流分量驅動發光二極管進行發光,sin(ωx+φ)值需要進行調製,這個值也不是確定的,調整下來爲0.3。那麼產生正弦曲線計算公式爲

 double dVal = 0.3+(double)(0.3*sin(2*M_PI*((double)kFrequency)*((double)j/44100)));
 short val = (short)(dVal*KAmplitude);

由於是通過左右聲道連接來導通二極管發光,所以要給一個聲道正值,一個聲道負值。整個產生正弦曲線函數的代碼如下

NSMutableData *pcmData = [[NSMutableData alloc] init];

    for(int i=0; i<num;i++){
        if (i%2 == 0) {//如果是偶數,產生正弦波
            int allNum = plus[i]*kNum;
            for (int j=0; j<allNum; j++) {
                double dVal = 0.5+(double)(0.5*sin(2*M_PI*((double)kFrequency)*((double)j/44100)));
                short val = (short)(dVal*KAmplitude);
                NSData *data = [NSData dataWithBytes:&val length:sizeof(short)];
                [pcmData appendData:data];
                short valMin = (short)(-val);
                NSData *data1 = [NSData dataWithBytes:&valMin length:sizeof(short)];
                [pcmData appendData:data1];

            }
        }else{//如果是奇數,填0
            int allNum = plus[i]*kNum;
            for (int j=0; j<allNum; j++) {
                double dVal = 0.0;
                short shortData = (short)(dVal);
                NSData *data = [NSData dataWithBytes:&shortData length:sizeof(short)];
                [pcmData appendData:data];
                short shortData1 = (short)(-dVal);
                NSData *data1 = [NSData dataWithBytes:&shortData1 length:sizeof(short)];
                [pcmData appendData:data1];
            }

        }
    }

其中num爲紅外時間碼的個數,plus[]爲保存時間碼的數組。

把產生的數據添加一個WAV頭,就可以生成wav聲音文件,通過AVAudioPlayer給播出

 //給音頻數據添加wav頭
    NSMutableData *wavData = [[NSMutableData alloc] init];
    [self addWavHead:wavData FrameSize:pcmData.length];
    [wavData appendData:pcmData];

 //播放音頻數據
    NSError *error;
    _audioPlayer = [[AVAudioPlayer alloc] initWithData:wavData error:&error];
    if (error) {
        NSLog(@"error log is %@",error.localizedDescription);
    }else{
        [_audioPlayer play];
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章