roboforum.ru

Технический форум по робототехнике.

Универсальный алгоритм декодирования пультов ДУ

Универсальный алгоритм декодирования пультов ДУ

Faster » 04 янв 2008, 18:13

Всемогущий алл , убил день и не как не нашол хоть както универсального алгоритма декодирования команд пультов ДУ,
всё делов том что RC-5/6/4 я нашол , они в принципе похожи и их можно универсально декодировать
но взяв в руки пулт оттелевизора я увидел вообще увидел непонятную картину , если RC можно просто подлинне декодировать, опираясь надлительность первого бита, то во многих случаях это не прокатывает , например от телекиа LG первый импульс имеет длинну в среднем 1/6 от всех остальных ... а вот с второго и далее всё вроде как похоже ...

Но мне то както надо ориентироваться ? может кто решал такую задачу, я несколько раз натыкался на какойто алгоритм сквозного анализа но увы не разу не нашол описания или хотя бы его реализации ...

Помогите кто чем может ...
уже голову сломал , но надо чтобы можно было распозновать большую часть пультов ....
если есть исходники ... то кидайте ...

Re: Универсальный алгоритм декодирования пультов ДУ

Faster » 06 янв 2008, 10:59

И так нарыл код в нете , правда для другого МК "скользящий алгоритм", пробую перевести для AVR вроде всё сделал поправил где нужно регистры и прочее ... но не задача не работает , причём не могу взять в толк почему один из эффектов перезапуск МК
вот кодчто вышел в тоге :
Код: Выделить всёРазвернуть
/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.7a Professional
Automatic Program Generator
© Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date    : 06.01.2008
Author  : Faster                         
Company : FastSoft                       
Comments:


Chip type           : ATmega8
Program type        : Application
Clock frequency     : 12,000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*****************************************************/
#include <mega8.h>       
#include <stdio.h>
#include <delay.h>
#include <stdlib.h>
#include <string.h>

//****************************************************
unsigned char l;
unsigned char *str[6];
// Êîä êîìàíäû, ïåðåäàííîé âûáðàííûì ïóëüòîì 
unsigned char RM_COM;
// Âõîäíîé ìàññèâ ôàçîâûõ áèòîâ, ðàçìåð êîòîðîãî äîëæåí
// áûòü áîëüøå, ÷åì ìàêñèìàëüíîå ÷èñëî áàéòîâ ÈÊ ïîñûëêè,
// óìíîæåííîå íà ÷èñëî áèòîâ (8) è óìíîæåííîå íà ÷èñëî ôàç 
// (2).  íàøåì ñëó÷àå 5 áàéò * 8 * 2 = 80 
unsigned char RMB[80];
// Âõîäíîé ìàññèâ áèòîâ ïîñëåäîâàòåëüíîñòè = 5* 8
unsigned char RMS[40];   
// Âõîäíîé áàéòîâûé ìàññèâ 5+1
unsigned char RM_Byte[6];   
// Ôëàã ãîòîâíîñòè
unsigned char RM_Ready;
//*****************************************************
// Ïîäïðîãðàììà èíèöèàëèçàöèè ïåðåìåííûõ
void RM_Init (void)
{
   RM_Ready=0;
   RM_COM=0;
   memset (RMB,0,80);
   memset (RM_Byte,0,6);
}
//*****************************************************
unsigned char RM_GetBit (int i)
{
   while (!PIND.2)  // Ïîêà íà âõîäå 0 
   { 
      RMB[i+0]++;  // Óâåëè÷èòü ñ÷åò÷èê ïîëóáèòà i
      //delay_ms(32);  // Çàäåðæêà ~ 32 ìêñ
      if (RMB[i+0]>250)return 0; // Åñëè áîëüøå 250  Âåðíóòü îøèáêó
   }
   while (PIND.2)     // Ïîêà íà âõîäå 1
   {
      RMB[i+1]++;  // Óâåëè÷èòü ñ÷åò÷èê ïîëóáèòà i+1
      //delay_ms(32);  // Çàäåðæêà ~ 32 ìêñ
      if (RMB[i+1]>250) return 0; //Åñëè áîëüøå 250 Âåðíóòü îøèáêó
   }
   return 1; // Íîðìàëüíîå çàâåðøåíèå


//*****************************************************
// Ïîäïðîãðàììà âîññòàíàâëèâàåò çíà÷åíèå áàéòà  èç áèòîâ
unsigned char RM_GetB (int NUM)
{
   unsigned char i;
   unsigned char ch=0;

   for (i=0;i<8;i++)
   {
      if (RMS[NUM*8+i])ch |= 0x80>>i;
   }
   return ch;

//*****************************************************

interrupt [EXT_INT0] void ext_int0_isr(void)
{
   unsigned char i;  // Óíèâåðñàëüíûé óêàçàòåëü
   unsigned char ii=1;   
   unsigned char OPTR; // Óêàçàòåëü «ðåàëüíûõ» áèòîâ
   static bit LAST;  // Áèò ïðåäûäóùåãî ñîñòîÿíèÿ
   static unsigned char MID; // Ïîðîãîâîå çíà÷åíèå ñ÷åò÷èêà ôàçû
   static unsigned char MIN; // Ìèíèìàëüíîå çíà÷åíèå ñ÷åò÷èê ôàçû

   //***** ÈÇÌÅÐÈÒÅËÜÍÀß ×ÀÑÒÜ *****//
   // Â ìîìåíò ïîñòóïëåíèÿ ïåðâîãî íóëåâîãî èìïóëüñà çàïðåòèòü
   // âñå ïðåðûâàíèÿ, ÷òîáû íå íàðóøàòü ïðàâèëüíûé ïîäñ÷åò
   // âõîäíûõ èìïóëüñîâ
   #asm("cli")   
   // Îæèäàòü çàâåðøåíèÿ ïåðâîãî îòðèöàòåëüíîãî (íóëåâîãî)
   // èìïóëüñà, ñîáñòâåííî è âûçâàâøåãî ïðåðûâàíèå
    while(!PIND.2);   
   // Îæèäàòü çàâåðøåíèÿ ïîëîæèòåëüíîãî (åäèíè÷íîãî) èìïóëüñà,
   // ñëåäóþùåãî çà îòðèöàòåëüíûì
    while(PIND.2);
   // Âûçâàòü ïîäïðîãðàììó ïîäñ÷åòà äëèòåëüíîñòè êàæäîãî èç
   // ôàçîâûõ ïîëóáèòîâ ñ îáùèì êîëè÷åñòâîì, ðàâíûì 5*8*2
   // Óñëîâíàÿ äëèòåëüíîñòü êàæäîãî èç ôàçîâûõ ïîëóáèòîâ ïîñ-
   // ëåäîâàòåëüíî çàïèñûâàåòñÿ â êàæäûé áàéò ìàññèâà RMB
   PORTC=1;
   for (i=0;i<80;i+=2)
   {
      if (RM_GetBit(i)==0) break;
   }
   PORTC=0;
   //IE0=0; // Ñáðîñèòü ôëàã ïðåðûâàíèÿ

   //***** ÎÏÐÅÄÅËÅÍÈÅ ÏÎÐÎÃÀ ÐÀÑÏÎÇÍÀÂÀÍÈß *****//
   //  ýòîé ÷àñòè ïîäïðîãðàììû îïðåäåëÿåòñÿ ìèíèìàëüíîå 
   // çíà÷åíèå ñ÷åò÷èêà i-îé ôàçû ïîëóáèòà, íåîáõîäèìîå äëÿ
   // äàëüíåéøèõ ïðåîáðàçîâàíèé

   // Óñòàíîâèòü ìàêñèìàëüíîå çíà÷åíèå ïîðîãà
   MIN=255;
   // Ïåðåáðàòü âåñü âõîäíîé ìàññèâ ôàçîâûõ ïîëóáèòîâ
   for (i=0;i<80;i++)
   {
      // Åñëè çíà÷åíèå ñ÷åò÷èêà òåêóùåãî ïîëóáèòà ìåíüøå âåëè÷èíû 
      // MIN è íå ðàâåí 0, ïðèñâîèòü âåëè÷èíå MIN çíà÷åíèå ñ÷åò÷èêà
      // òåêóùåãî ïîëóáèòà
      if ((RMB[i]<MIN)& (RMB[i]!=0))  MIN= RMB[i];   
   }
     
   // Îïðåäåëÿåì ñðåäíåå çíà÷åíèå ïîðîãà äëÿ ñðàâíåíèÿ
   MID=MIN+MIN/2; 

   //***** ÎÏÐÅÄÅËÅÍÈÅ ÏÎÐÎÃÀ ÐÀÑÏÎÇÍÀÂÀÍÈß *****//
   //  äàííîì ôðàãìåíòå ìû îïðåäåëÿåì, êàêîìó êîëè÷åñòâó ïîëó-
   // áèò ñîîòâåòñòâóåò ïîëó÷åííàÿ óñëîâíàÿ äëèòåëüíîñòü, çàïè-
   // ñàííàÿ â êàæäîì èç áàéòîâ âõîäíîãî ìàññèâà RMB. Äëÿ 
   // ñðàâíåíèÿ óñëîâíîé äëèòåëüíîñòè èñïîëüçóåì ïîëó÷åííîå
   // ñðåäíåå çíà÷åíèå óñëîâíîé äëèòåëüíîñòè MID

   // Ïåðåáðàòü âåñü âõîäíîé ìàññèâ ôàçîâûõ ïîëóáèòîâ
   for (i=0;i<80;i++)
   {
      // Åñëè çíà÷åíèå ðàâíî íóëþ – ïðîäîëæèòü ñðàâíåíèå
      if (!RMB[i]) continue;
      // Åñëè óñëîâíàÿ äëèòåëüíîñòü áîëüøå ñðåäíåé, çàïèñàòü
      // â ýòîò æå áàéò çíà÷åíèå 2, èíà÷å 1.
      RMB[i]=(RMB[i]>MID) ? 2 : 1;
   }
   
   // Â ðåçóëüòàòå ýòîé îïåðàöèè âõîäíîé ìàññèâ, ñîäåðæàùèé
   // èçìåðåííûå çíà÷åíèÿ óñëîâíûõ äëèòåëüíîñòåé ôàçîâûõ 
   // ïîëóáèòîâ ìû ïðåîáðàçîâàëè â ìàññèâ, ñîäåðæàùèé çíà÷åíèÿ
   // ÷åðåäóþùèõñÿ ïîëóáèòîâ (1 èëè 2 èëè 0)


   //***** ÏÐÅÎÁÐÀÇÎÂÀÍÈÅ ÌÀÑÑÈÂÀ ÏÎËÓÁÈÒÎÂ Â ÌÀÑÑÈÂ ÈÑÕÎÄÍÛÕ ÁÈÒÎÂ *****//
   // Âíèìàòåëüíî ðàññìîòðåâ ðèñ.4 ìîæíî çàìåòèòü âïîëíå ÷åòêóþ 
   // çàêîíîìåðíîñòü âîññòàíîâëåíèÿ èñõîäíûõ ïåðåäàííûõ áèòîâ 
   // èç ïîëó÷åííîãî âûøå ìàññèâà ÷åðåäóþùèõñÿ ïîëóáèòîâ, 
   // çíà÷åíèÿ êîòîðîãî óêàçàíû öèôðàìè ïîä íóëåâîé ëèíèåé INPUT

   memset (RMS,0,40);  // Îáíóëèì ìàññèâ áèòîâ

   OPTR=0; // Îáíóëèì óêàçàòåëü áèòîâ
   i=0;  // Îáíóëèì óêàçàòåëü ïîëóáèòîâ
   LAST=0; // Îáíóëèì çíà÷åíèå âîññòàíàâëèâàåìîãî áèòà

   // Âûïîëíÿòü äî âîññòàíîâëåíèÿ 40 áèòîâ = 5 áàéòàì
   while (OPTR<40)
   {
      // Åñëè òåêóùèé ëîãè÷åñêèé óðîâåíü èìåë äâîéíóþ äëèòåëüíîñòü
      // Íåîáõîäèìî ïðîèíâåðòèðîâàòü âîññòàíàâëèâàåìûé  èñõîäíûé áèò
      // Ñìîòðè ïðåäïîñëåäíèé ðÿä íàäïèñåé íà ðèñ.4 òèïà õõ=0(1), ãäå
      // ïåðâàÿ öèôðà – òåêóùèé ôàçîâûé ïîëóáèò;  âòîðàÿ öèôðà – 
      // ñëåäóþùèé ôàçîâûé ïîëóáèò;  0 èëè 1 ïîñëå çíàêà ðàâåíñòâà 
      // îçíà÷àåò çíà÷åíèå âîññòàíàâëèâàåìîãî èñõîäíîãî áèòà.
   
      if (RMB[i]==2)  LAST=~LAST;
      // Çàïèñàòü áèò â ìàññèâ áèòîâ è óâåëè÷èòü óêàçàòåëü áèòîâ
      RMS[OPTR++]=LAST;
      // Ïðåðâàòü, åñëè î÷åðåäíîå çíà÷åíèå ôàçîâîãî ïîëóáèòà - íóëåâîå
      ii=i+1;
      if (!RMB[ii]) break;
      // Åñëè ñëåäóþùèé ïîëóáèò äâîéíîé, ñäâèíóòü óêàçàòåëü íà 1, 
      // èíà÷å ñäâèíóòü óêàçàòåëü íà 2
      if (RMB[ii]==2) i+=1;
         else  i+=2;   
   }   
   
   //***** ÏÐÅÎÁÐÀÇÎÂÀÍÈÅ ÌÀÑÑÈÂÀ ÈÑÕÎÄÍÛÕ ÁÈÒΠ  ÁÀÉÒÎÂÛÉ ÌÀÑÑÈ *****//
   for (i=0;i<5;i++)
   {
      RM_Byte[i]=RM_GetB (i);
   }
   // Óñòàíîâèòü ôëàã ãîòîâíîñòè ïðèíÿòîé ïîñëåäîâàòåëüíîñòè
   // Ôëàã äîëæåí îáíóëÿòüñÿ, ïîäïðîãðàììíîé, âûïîëíÿþùåé 
   // ïðèíÿòûå êîìàíäû ïîñëå çàâåðøåíèÿ âûïîëíåíèÿ
   RM_Ready=1;
   // Ðàçðåøèòü âñå ïðåðûâàíèÿ, ïîñêîëüêó êðèòè÷íàÿ ê âðåìåíè
   // ÷àñòü çàâåðøåíà
   #asm("sei")
}

#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART Receiver buffer
#define RX_BUFFER_SIZE 8
char rx_buffer[RX_BUFFER_SIZE];

#if RX_BUFFER_SIZE<256
unsigned char rx_wr_index,rx_rd_index,rx_counter;
#else
unsigned int rx_wr_index,rx_rd_index,rx_counter;
#endif

// This flag is set on USART Receiver buffer overflow
bit rx_buffer_overflow;

// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
   {
   rx_buffer[rx_wr_index]=data;
   if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
   if (++rx_counter == RX_BUFFER_SIZE)
      {
      rx_counter=0;
      rx_buffer_overflow=1;
      };
   };
}

#ifndef _DEBUG_TERMINAL_IO_
// Get a character from the USART Receiver buffer
#define _ALTERNATE_GETCHAR_
#pragma used+
char getchar(void)
{
char data;
while (rx_counter==0);
data=rx_buffer[rx_rd_index];
if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
#asm("cli")
--rx_counter;
#asm("sei")
return data;
}
#pragma used-
#endif

// Standard Input/Output functions


// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State6=T State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTC=0x00;
DDRC=0x3F;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 11,719 kHz
TCCR0=0x05;
TCNT0=0x8F;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Low level
// INT1: Off
GICR|=0x40;
MCUCR=0x00;
GIFR=0x40;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 19200
UCSRA=0x00;
UCSRB=0x98;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x26;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
   #asm("sei")
   RM_Init();
   printf("Starting\r\n");
   while (1)
   {
      // Place your code here
      while (!RM_Ready);
      printf("RX:");
      for(l=0;l<6;l++)
      {
         itoa(RM_Byte[l],str);
         puts(str);
         printf("\r\n");
      }
      RM_Ready=0;
   };
}


но бага в том что надпись Starting которая была сделана для того чтобы в терминали отличать запуски стала вылитать при долгом удержании кнопки пульт а... , в чём бага не понятно ? всё то дело работает на кварце 12мгц , так как от внутрненего генератора пришлось отказаться ещё в прошлых эксперементах ... чтото он на 8 мгц не стабильно пахал ...

так же иногда МК виснет ...
народ помогите разобраться код до придела простой ... но увы не работает где я пролител ... уже пол дня голову ломаю .. взгляд наверно замутнел так что прошу помощми ...

Re: Универсальный алгоритм декодирования пультов ДУ

Vooon » 06 янв 2008, 18:11

  1. код примника лучше вынести отдельным модулем
  2. исходники не стоит постить целиком в пост, лучше прицепить атачем.
  3. возможно включен WDT(?) и не сбрасывается
  4. приведите источник, с чего вы портировали

* красным отмечено замечание модератора

Re: Универсальный алгоритм декодирования пультов ДУ

Faster » 06 янв 2008, 18:55

Да не включен WDT не зачем ...
атачем , дачтото не заметил вложений тут ... хотя уже нашол ...

Отдельным кодом .. да смысла нет ... там коду то , просто уже вазюкаюсь месяц с авэркой ивсё получалось , тут задача на 10 минут ине ка кне могу найтирешения ...

вроде нарыл .. оно вешается ...

причём интересно , так я уже подумал можетнаводки на сброс идут ? рядом провода идут с PD2 зацепил туда резюк 3,9к на +5v всё таже лажа ...
контроллер менял на двухтестил ...
просто интересно в каком куске кода может быть вылет ???
тамкода то нет ... :( вот сижуи думаю что за ... :P
Вложения
Stat_091.pdf
оригинал
(261.9 КиБ) Скачиваний: 74


Rambler\'s Top100 Mail.ru counter