logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

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

nowy_me 02 Paź 2009 19:21 5145 18
  • #1 7083417
    nowy_me
    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:
    #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
  • #2 7083628
    michalko12
    Specjalista - Mikrokontrolery
    Jaki częstotliwośc taktowania procesora?
  • #4 7085424
    michalko12
    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.
  • #5 7085505
    kwesoly
    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.
  • #6 7086052
    marek_04
    Poziom 10  
    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?
  • #7 7086084
    Konto nie istnieje
    Konto nie istnieje  
  • #8 7172958
    paradox91
    Poziom 11  
    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ł.
  • #9 7194246
    Konto nie istnieje
    Konto nie istnieje  
  • #10 7194977
    paradox91
    Poziom 11  
    Dzięki bardzo jesteś wielki.
  • #11 7405166
    wladziu22
    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ć?
    
    #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.
  • #12 7406825
    Konto nie istnieje
    Konto nie istnieje  
  • #14 7411473
    Konto nie istnieje
    Konto nie istnieje  
  • #15 7411604
    wladziu22
    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.
  • #16 7413234
    kwesoly
    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.
  • #17 7477064
    wladziu22
    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:
    
    //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):
    
    #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ę.
  • #18 7478418
    kwesoly
    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:
    if (command & (1 << i)) 

    na coś w stylu:
    
    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?
  • #19 7478928
    wladziu22
    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.
REKLAMA