Attiny13Aを使用したIPTVセットトップボックスのリモートボリュームコントロール

Rostelecomから電話があり、IPTVへの接続を申し出たことがあります。さて、私は妻と息子に寝室で漫画を見てもらうことに決め、同意しました。そして、彼らは私に切望された箱を持ってきました。なぜなら別のテレビセットを持っていないので、HDMI-VGAアダプターを介して古いモニターに接続することにしました。音に関しては、古いコンピュータースピーカーを持っていました。決定-完了。セットトップボックスに付属のリモコンからは、音量を調整することができません。どうですか?正直なところ、こんなことは一度もありません。理由はよくわかりませんでしたが、Rostelecomのリモコンがテレビに登録されているようで、セットトップボックスの出力ではなく、テレビ自体の音量がリモコンから変化します。便利ですか?もちろん、セットトップボックスを最新のテレビに接続すれば。しかし、ベッドから出て、音量を変更する必要があるたびにスピーカーのスピーカーを回すのは不便です。この問題に対処します。リモートコントロールからの信号に応じてスピーカーの音量を調整する別のデバイスを組み立てます。



まず、「音量大」、「音量小」、「ミュート」ボタンを押したときに、リモートがどのような信号を生成するかを見てみましょう。リモートコントロールからの信号の受信機としてVS1838Bを使用しました。



これは便利なレシーバーです。すでにリモートからの38kHzの赤外線信号をデモジュレートしています。



上記のボタンは2種類の信号を交互に生成することがわかりました。最初の1つのオプション、次に別のオプションを押します。この図は、「ミュート」ボタンを押したときの信号オプションの1つを示しています。信号は、ロジックアナライザーを使用して読み取られました。



ロジックアナライザー信号グラフ



100 . 24- . ( ) 900 , ( , ) 1800 . , , :



1. .



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0
2 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0
1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0
2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0
Mute 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0
Mute 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0


. , 50. .. , , — . "" . X9C103P. 10 . , , , 10 . .



VS1838B. . , , , . , , , . Attiny13A. : , . : 1 64 SRAM. (Atmega 328) 32 2 SRAM.



, , - . , :



const unsigned long UP1_DATA[] =   {860, 900, 1750, 900, 860, 900, 860, 900, 860, 900, 860, 900, 860, 900, 860, 1750, 1750, 900, 860, 900, 860, 900, 860};


, attiny . . — , .. . : , 6- 15-, 19- 20- — . . — . . 8 ( 2).



2 — 1



1 2 3 4 5 6 7 8
1 1 0 0 1 1 0 0 0
2 0 0 1 1 1 0 0 0
1 0 0 1 1 1 0 0 1
2 1 0 0 1 1 0 0 1
Mute 1 0 0 1 0 0 1 1 1
Mute 2 1 0 0 0 0 1 1 1


:



#define UP1_DATA      0b00011001
#define UP2_DATA      0b00011100
#define DOWN1_DATA    0b10011100
#define DOWN2_DATA    0b10011001
#define MUTE_ON_DATA   0b11100100
#define MUTE_OFF_DATA   0b11100001


. , ( ) . . , .



. _timer:



volatile unsigned long _timer = 0;

ISR(TIM0_OVF_vect)
{
    _timer++;
}


Attiny13A 9,6 . 256 , 37500 . 900 33 , 1800 67 . , 9,6 , .



getExpectedTime, ,
#define SHORT_TIME 33UL
#define LONG_TIME 67UL

uint8_t _counter = 0;

unsigned long getExpectedTime(uint8_t data)
{
    uint8_t index;
    if (_counter >= 2 && _counter <= 4)
    {
        index = _counter - 2;
    }
    else if (_counter >= 15 && _counter <= 17)
    {
        index = _counter - 12;
    }
    else if (_counter >= 20 && _counter <= 21)
    {
        index = _counter - 14;
    }
    else
    {
        return SHORT_TIME;
    }
    if (data & (1 << index)) return LONG_TIME;
    return SHORT_TIME;
}




_counter — . data — 6 : UP1_DATA, UP2_DATA, DOWN1_DATA, DOWN2_DATA, MUTE_1_DATA, MUTE_2_DATA.


.. , , ( ) getExpectedTime . — .





volatile bool _hasPulse = false;
volatile unsigned long _RXPreviousTime = 0;
volatile unsigned long _pulseDuration = 0;

ISR(INT0_vect)
{
    _pulseDuration = _timer - _RXPreviousTime;
    _RXPreviousTime = _timer;
    _hasPulse = true;
    _rxPinStatus = !!(PINB & (1 << RX_PIN)); // digitalRead  .
}


,



incrementCounter,
#define SIZE_OF_PATTERNS 6
#define PAUSE_TIME 375UL //10000 
#define HAS_PATTERN_START 0b00111111
#define ERROR_VALUE 19UL
#define SIZE_OF_DATA 23

#define UP1_BT 0
#define UP2_BT 1
#define DOWN1_BT 2
#define DOWN2_BT 3
#define MUTE_ON_BT 4
#define MUTE_OFF_BT 5

//         : UP1_BT, UP2_BT, DOWN1_DATA, DOWN2_DATA, MUTE_ON_BT, MUTE_OFF_BT
const uint8_t PATTERNS[] = {UP1_DATA, UP2_DATA, DOWN1_DATA, DOWN2_DATA, MUTE_ON_DATA, MUTE_OFF_DATA};
uint8_t _hasPattern = HAS_PATTERN_START;

//   ,       PATTERNS.
uint8_t incrementCounter() //   ,       PATTERNS.
{
    if (_pulseDuration > PAUSE_TIME)
    {
        _counter = 0;
        _hasPattern = HAS_PATTERN_START;
        return 255;
    }
    if (_hasPattern)
    {
        unsigned long eTime;
        for (uint8_t i = 0; i < SIZE_OF_PATTERNS; i++)
        {
            if (_hasPattern & (1 << i)) //   .
            {
                eTime = getExpectedTime(PATTERNS[i]);
                if (!((_rxPinStatus ^ !!(_counter % 2)) && _pulseDuration >= eTime - ERROR_VALUE && _pulseDuration <= eTime + ERROR_VALUE)) //  .
                {
                    _hasPattern &= ~(1 << i);
                }
            }
        }
        _counter++;
        if (_counter == SIZE_OF_DATA)
        {
            if (_hasPattern) //-  
            {

                switch (_hasPattern)
                {
                    case 1: return UP1_BT;
                    case 2: return UP2_BT;
                    case 4: return DOWN1_BT;
                    case 8: return DOWN2_BT;
                    case 16: return MUTE_ON_BT;
                    case 32: return MUTE_OFF_BT;
                    default: return 255;
                }
            }
            else
            {
                return 255;
            }
        }
        else
        {
            return 255; //    
        }
    }
    else
    {
        return 255; //   
    }
}


_hasPattern — , . 1. -, , 0. , - . PATTERNS.



, X9C103P.



1020 1024 , , (-Os). GitHub. UNO, .. , Attiny13A. UNO , - . .



( ), .



プリント回路基板



9 , , 78L05.



8 : 3 , 3 . UTP , 8 . , .



コラムボード



:



上から見る



底面図



, , , -. , GND , . . , smd 100 , .



, .



:






All Articles