Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[AVR][C][ATtiny13]problem z RC5

02 Paź 2009 19:21 4932 18
  • Poziom 2  
    chciałem zrobić program do zmiany kanału na 4 w telewizorze marki PHILIPS, wyciągnąłem diodę ze starego popsutego pilota, napisałem program, dioda miga(sprawdzam przez kamerę cyfrową) ale kanał się nie zmienia
    o to program:
    Code:
    #include <avr/io.h>
    
    #include <util/delay.h>

    void niski(void);
    void wysoki(void);
    void zero(void);
    void jeden(void);

    int main(void)
    {   
      DDRB|=0x01;
       PORTB|=0x02;
       
       while(1)
       {
          while(!(PINB&0x02))
          {
            jeden();
             jeden();
             zero();

             zero();
             zero();
             zero();
             zero();
             jeden();
             
             zero();
             zero();
             zero();
             jeden();
             zero();
             zero();
             
            _delay_ms(88.889);
          }
       }
    }

    void niski(void)
    {
      uint8_t i;
       for(i=0;i<128;i++)
       {
         PORTB&=~0x01;
         _delay_us(6.944);
       }
    }

    void wysoki(void)
    {
      uint8_t i;
       for(i=0;i<128;i++)
       {
         if((i%4)==0)
            PORTB|=0x01;
          else
            PORTB&=~0x01;
         _delay_us(6.944);
       }
    }

    void zero(void)
    {
      wysoki();
       niski();
    }

    void jeden(void)
    {
      niski();
       wysoki();
    }

    tu linki z których korzystałem:
    http://www.sbprojects.com/knowledge/ir/rc5.htm
    http://website.lineone.net/~dezellis/rc5.htm

    co do układu do dioda jest podpięta do PB0, a przycisk to PB1, zasilanie 3x1.5V z baterii
    jakiś pomysł czemu nie działa
  • Specjalista - Mikrokontrolery
    Jaki częstotliwośc taktowania procesora?
  • Specjalista - Mikrokontrolery
    kwesoly napisał:
    Sprawdziles na:
    http://lirc.sourceforge.net/remotes/

    czy ten twój telewizor to na pewno RC5? Philips tez się rozwija.


    Nawet jakby to był tv z rc5 to i tak ten kod nie będzie działał,
    Powstawiał opóźnienia, ale chyba nie wziął pod uwagę że reszta
    kodu też zajmuje trochę czasu.
  • Poziom 15  
    michalko12 napisał:
    kwesoly napisał:
    Sprawdziles na:
    http://lirc.sourceforge.net/remotes/

    czy ten twój telewizor to na pewno RC5? Philips tez się rozwija.


    Nawet jakby to był tv z rc5 to i tak ten kod nie będzie działał,
    Powstawiał opóźnienia, ale chyba nie wziął pod uwagę że reszta
    kodu też zajmuje trochę czasu.


    A jaką tolerancje czasów ma telewizor? I ile zajmuje "reszta" kodu? Po prostu zwracam uwagę, że coraz częściej problemy z RC5 wynikają z tego że pilot/TV nie nadają w tym standardzie. Ale tutaj rzeczywiście problemem mogą być 'timingi', co nie zmienia faktu, że można raz dwa sprawdzić czy pilot który próbujemy zastąpić działał w RC5.
  • Poziom 9  
    więc tak:
    częstotliwość procesora 1MHz z wewnętrznego oscylatora
    co do telewizora to jest to stary model i sprawdziłem na pewno rc5
    mi też się wydaje że coś jest nie tak z opóźnieniami, ale rozumiem że kod jeśli chodzi o zasadę jest dobry?
  • Użytkownik usunął konto  
  • Poziom 10  
    kazaaski czy mógłbyś mi pokazać podobny program tylko dla attiny13. Bo nie umie sobie z tym poradzić i nie bardzo rozymiem zasady działania. Ewentualnie jakimś linkiem przydatnym też bym się ucieszył.
  • Użytkownik usunął konto  
  • Poziom 10  
    Dzięki bardzo jesteś wielki.
  • Poziom 17  
    Tak się przyglądam temu co napisałeś kazaaski i próbuje u siebie to odpalić, tyle ze ja mam wewnętrzne 8MHz i ATtiny26.
    Niestety nie wiem jakie wartości (OCR1C, OCR1B )należny wpisać by osiągnąć zamierzone 38kHz :( Jak to wyliczyć?
    Code:

    #define JEDEN TCCR1A  &= ~(_BV(COM1B1)|_BV(COM1B0)); _delay_us(889); TCCR1A  |= _BV(COM1B1)|_BV(COM1B0); _delay_us(889);
    #define ZERO TCCR1A  |= _BV(COM1B1)|_BV(COM1B0); _delay_us(889); TCCR1A  &= ~(_BV(COM1B1)|_BV(COM1B0));  _delay_us(889);
    #define GAP TCCR1A  &= ~(_BV(COM1B1)|_BV(COM1B0)); _delay_ms(89);
    ...
    ...
    void PWMinit(void)
    {
    DDRB = _BV(PB3);   //PB3 jako wyjście
    PORTA &= ~_BV(PB3);  //stan niski   


    TCCR1A = _BV(COM1B1)|_BV(COM1B0)|_BV(PWM1B); //ustawienie wyjścia OC1B, wybranie PWM kanal B
    TCCR1B = _BV(CTC1)|_BV(CS11);                // wyzerowanie timera po zrównaniu się z wartością OCR1C, preskaler: fosc/2
    OCR1B =    ???                                  //początkowa wartość do porównania
    OCR1C =    ???                                 // górną wartość do której zamicza timer T1
    }


    Proszę o pomoc.

    Dodano po 4 [godziny] 30 [minuty]:

    znalazłem wzór Fpwm = Ftck/ (OCR1C+1). Po zastosowaniu tego wzoru i preskalera 8MHz/2 otrzymuje OCR1C = 104. Nie wiem czy to dobrze :/ A co do OCR1B przyjąłem = 0; tu również nie jestem pewien czy dobrze zrobiłem.
    Czy ktoś wie? Proszę o pomoc i wyjaśnienie.
  • Użytkownik usunął konto  
  • Użytkownik usunął konto  
  • Poziom 17  
    w sumie to wyczytałem gdzieś ze nawet odbiornikiem 36kHz mogę odebrać nośna 38kHz i powinno zadziałać....To dopiero odchyłka ;-)
    Narazie chyba mam problem prawdopodobnie z tranzystorem (tak mi kolega mirekk36 podpowiedział). Tak wiec .. kurka .. nei przetestuje działania :/ Dioda IR podłączona pomiędzy E a GND ciągle świeci po włączeniu programu, a powinna pomrugać i zgasnąć. W poniedziałek zmienię tranzystor i zobaczę ponownie.
  • Poziom 15  
    Datasheety scalonych odbiorników podczerwieni mają z reguły wykres czułości w funkcji częstotliwości. Zmiana 38kHz na 36kHz co najwyżej zmniejszy zasięg o kilkanaście/kilkadziesiąt procent.
  • Poziom 17  
    Witam.

    W końcu znalazłem chwile wolnego czasu po świętach by kontynuować mojego pseudo pilota.
    Z początku nie bylem pewny czy zlutowany układ diody IR działa. Na wzór powyższych przykładów odpaliłem standardowy RC5:
    Code:

    //Attiny26
    #define F_CPU 8000000
    #include <avr/io.h>
    #include <util/delay.h>
    //===================================================
    void sendData_IR(unsigned int command);
    void init_IR(void);
    void sendGap_IR(void);
    //----------------------------------------------------------
    //   inicjowanie portu dla IR nadajnika
    //----------------------------------------------------------
    void init_IR(void)
    {
      DDRB |= _BV(PB1);  // OC1A jako wyjście
      TCCR1B |= _BV(CS10); // bez preskalera
      TCCR1B |= _BV(CTC1);  // tryb CTC1
      OCR1C = 111;  // 36 kHz
    }

    //----------------------------------------------------------
    //   wyslij addres | command do IR
    //----------------------------------------------------------
    void sendData_IR(unsigned int command)
    {
      for (int i = 13; i >= 0; i--)
      {
        if (command & (1 << i))
        {
          TCCR1A &= ~(1 << COM1A0);
          _delay_us(889);
          TCCR1A |= (1 << COM1A0);
          _delay_us(819);
        }
        else
        {
           TCCR1A |= (1 << COM1A0);
          _delay_us(889);
          TCCR1A &= ~(1 << COM1A0);
          _delay_us(819);
        }
      }
     
      _delay_us(70);
      TCCR1A &= ~(1 << COM1A0);
      _delay_ms(89);
    }

    //===========================================================
    //  funkcja glowna
    //===========================================================
    int main(void)
    {
      init_IR();
      //wysylany kod 2xbit startu + togle + 5addres + 6command (MSB->LSB)

      sendData_IR(0b11100000010000);//glosnosc +
      sendData_IR(0b11100000010000);
      sendData_IR(0b11100000010000);

      while(1);
      return 0;
    }

    Głośność TV zwiększyła się i tym samym wiem, ze układ mam poprawny.

    Przerobiłem więc program na specyficzną dla JVC transmisje (bo taki obrałem cel):
    Code:
    
    
    #define F_CPU 8000000
    #include <avr/io.h>
    #include <util/delay.h>
    //===================================================
    void sendData_IR(unsigned int command);
    void header_IR(void);
    void initIR(void);

    //------------JVC address-------------------
    #define _IR_address 0xF1
    //------------JVC command-------------------
    #define VolPlus 0x21
    #define VolMinus 0xA1


    //----------------------------------------------------------
    //   inicjowanie portu dla IR nadajnika
    //----------------------------------------------------------
    void init_IR(void)
    {
      DDRB |= _BV(PB1);    // OC1A jako wyjście
      TCCR1B |= _BV(CS10); // bez preskalera
      TCCR1B |= _BV(CTC1);  // tryb CTC1
      OCR1C = 105;          // 38 kHz
    }
    //----------------------------------------------------------
    //   bit startu
    //----------------------------------------------------------
    void header_IR(void)
    {
      TCCR1A |= _BV(COM1A0);
      _delay_ms(8);                   //8.4ms
      _delay_us(600);
      TCCR1A &= ~_BV(COM1A0);
      _delay_ms(4);                    //4.2ms
      _delay_us(200);
    }
    //----------------------------------------------------------
    //   wyslij addres | command do IR
    //----------------------------------------------------------
    void sendData_IR(unsigned int command)
    {
      for (int i = 0; i <= 7; i++)
      {
        if (_IR_address & (1 << i))
        { //'1'
         TCCR1A |= _BV(COM1A0);
         _delay_us(560);
         TCCR1A &= ~_BV(COM1A0);
         _delay_ms(1);                    //1.6ms
         _delay_us(540);
        }
        else//'0'
        {
         TCCR1A |= _BV(COM1A0);
         _delay_us(560);
         TCCR1A &= ~_BV(COM1A0);
         _delay_us(520);
        }
      }
     
      for (int i = 0; i <= 7; i++)
      {
        if (command & (1 << i))
        {//'1'
         TCCR1A |= _BV(COM1A0);
         _delay_us(560);
         TCCR1A &= ~_BV(COM1A0);
         _delay_ms(1);                    //1.6ms
         _delay_us(540);
        }
        else
        {//'0'
         TCCR1A |= _BV(COM1A0);
         _delay_us(560);
         TCCR1A &= ~_BV(COM1A0);
         _delay_us(520);
        }
      }
     
      _delay_us(70);
      TCCR1A &= ~_BV(COM1A0);
      _delay_ms(19);
    }

    //===========================================================
    //  funkcja glowna
    //===========================================================
    int main(void)
    {
      init_IR();
      header_IR();
      sendData_IR(VolPlus);
      sendData_IR(VolPlus);
      sendData_IR(VolPlus);
      sendData_IR(VolPlus);
      sendData_IR(VolPlus);
      sendData_IR(VolPlus);

      while(1);
      return 0;
    }

    jednak efektów poprawnego działania nie widać. Aktualne czasy pobrałem przy uzyciu oscyloskopu. Probowalem również z czasami pobranymi z:Link Również brak reakcji ze strony odbiornika.
    Stad też zwracam się z prośba do Was...moze macie jakiś pomyśł co mógłbym jeszcze sprawdzić ewentualnie poprawić?
    Z gory dziekuję.
  • Poziom 15  
    Próbowałeś obejrzeć wyjście z twojego AVR na oscyloskopie (jak rozumiem masz taki do dyspozycji?).

    Z opisu na lircu wynika, że każdy kod zaczyna się od dośc znacznej liczby zer (której w Twoim kodzie nie widać), dlatego warto byłoby na oscyloskopie porównać wyjścia z AVR z wyjściem pilota.

    Poza tym zamieniłbym:
    Code:
    if (command & (1 << i)) 

    na coś w stylu:
    Code:

    if(command & 1)
    {
    ....
    }
    command=command<<1;


    twój kod przesuwa bitowo w lewo o dynamiczną ilość miejsc, więc jeśli kompilator nie jest na tyle bystry żeby to obejść generuje się dość dużo zbędnego kodu.

    Nie jestem też pewien, czy świadomie wysyłasz dane do JVC w kolejności od najmłodszego bitu do najstarszego?
  • Poziom 17  
    Miałem dostęp do oscyloskopu ale przed świętami i to tylko na kilka minut (podłączałem do diody oryginalnego pilota).

    Cytat:
    Nie jestem też pewien, czy świadomie wysyłasz dane do JVC w kolejności od najmłodszego bitu do najstarszego?

    Tak świadomie wysyłam od LSB do MSB....ale (czytaj dalej)

    W zasadzie już sobie poradziłem.... Jeszcze raz sprawdziłem to co zanotowałem sobie na kartce gdy przerysowywałem przebieg....Miałem jak byk narysowane ze bity lecą od MSB do LSB a nie na odwrót jak to na kilku stronach www jest przedstawione :/ A głownie korzystałem z STRONA1 lub STRONA2
    A ten kod który wyżej wkleiłem pewnie będzie działał na jakiś starszych modelach JVC.

    Dziękuje za zainteresowanie.