RC5 IR Protocol Receiver 16F183463 MCU SOLVED LOOK LAST REPLY

General discussion on mikroC PRO for PIC.
Post Reply
Author
Message
leo73
Posts: 252
Joined: 09 Jan 2014 15:45

RC5 IR Protocol Receiver 16F183463 MCU SOLVED LOOK LAST REPLY

#1 Post by leo73 » 25 Jan 2023 17:50

Hello to Every one,
This time i'm made and adjust timeing for RC5 Decoder (Receiver) Function.

When RA2 pin of Receiver Pic receive firts logic level (0), enter Interrupt function, it call IR_Receiver() function and start RC5 decoder in two Variables (address and comando).

The most big problem is understand right timing for a right decoding !!!!
So i inserted a test trigger signal << LATC7_bit = 1; Delay_us(1); LATC7_bit = 0;>> to synchronize it across the length of the word. (address and command)
MY QUESTIONS:
1) At 21.53 on 25.Jan.23 I used 2° Method to understand how set timing, but is impossible or hard find right alignment between the trigger test signal and the rising and falling edges of the protocol. (look Signal analyzer)
How should the trigger peaks be aligned with the protocol looking at the logical analyzer?
Thank you in advance.
Leo.

related topic:
viewtopic.php?f=88&t=79758
https://techdocs.altium.com/display/FPG ... n+Protocol
interrupt()

Code: Select all

// GLOBAL VARIABLES:
bit RC5_Flag;
unsigned short i, Comando, Address;

void interrupt()
{
// INTERRUPT ON RA2
  if (PIR0.INTF == 1)
  {
    IR_Receiver();
    PIR0.INTF = 0;
  }
}
IR_Receiver(): 2° Method SIGNAL TRIGGER: LATC7_bit = 1; Delay_us(1); LATC7_bit = 0;

Code: Select all

void IR_Receiver(){
   RC5_Flag=0;
   i=0;
  // Check if the received signal is RC5 protocol
  if(~PORTA.B2) { Delay_us(889); }
  else return;

  Delay_us(30);  // Delay for Adjust time.

  if(PORTA.B2) {Delay_us(889); }
  else return;
  
  // while wait last start and toggle signal
  if(~PORTA.B2) { while(~PORTA.B2);/*Delay_us(1778);*/ }//1778
  else return;

  Delay_us(2650);  // Delay for Adjust time. 2600(03) Move Signal trigger test on left or right
  
  while (i < 12) {
         LATC7_bit = 1;  Delay_us(1);  LATC7_bit = 0;	// SIGNAL TRIGGER TEST
         if(i < 6) {                 // READ ADDRESS BIT  was 6
            if(PORTA.B2){
              Address &=  !(1 << (5-i)); //CLEAR BIT 5-i
              }
            else {
              Address |= (1 << (5-i)); //SET BIT 5-i
              }
            }

         else {                          //READ COMMAND BIT
            if(PORTA.B2){
              Comando &= !(1 << (11-i)); //CLEAR BIT 11-i
              }
            else {
              Comando |= (1 << (11-i)); //SET BIT 11-i
              }
            }
         Delay_us(1580);	// instead 1778 impossible because instructions take some us
         i++;
      }  // end while
  RC5_Flag = 1;

}  // END FUNCTION
Attachments
IR-Decoder-LogicState.jpg
IR-Decoder-LogicState.jpg (128.98 KiB) Viewed 880 times
IR-Decoder-FlowChart.jpg
IR-Decoder-FlowChart.jpg (32.53 KiB) Viewed 883 times
Last edited by leo73 on 01 Feb 2023 09:41, edited 5 times in total.

leo73
Posts: 252
Joined: 09 Jan 2014 15:45

Re: RC5 IR Protocol Receiver 16F183463 MCU SOLVED look last post

#2 Post by leo73 » 27 Jan 2023 14:56

Hello to every one,
The alignment of the RC5 protocol (in Receive) via trigger test signal seems to be synchronized (in my 1°Timing Test); in fact, in the picture of the logical states, extreme numbers were sent, Respectively:
Address: 1F and Command: 3F (5bit) - (6bit)
Address: 00 and Command: 00 (5bit) - (6bit)

For a moment Toggle bit value in lock at same value.

27.Jan.23 19.00 RESULTS:
-GOOD DECODE VALUES BUT ONLY FOR EXTREME OF IT !!! (1° Timing is the first good step for a moment)

Some One can Help Me to verify if the Synchronization of protocol is Right please? or do you have an alternative idea?
I hope it explained myself well! Thank you in advance for your help. ☺️

Codage_Manchester and Philips RC5:
https://it.frwiki.wiki/wiki/Codage_Manchester
https://techdocs.altium.com/display/FPG ... n+Protocol

I show you below the entire citation code:
INTERRUPT:

Code: Select all

#define TAB 9
// GLOBAL VARIABLES
bit RC5_Flag;
unsigned short Comando,Address;
unsigned short i;
// PROTOTIPE DECLARATION
void IR_Receiver(void);

void interrupt()
{
if (PIR0.INTF == 1)   // && INTE_bit
  {
    IR_Receiver();
    PIR0.INTF = 0;
  }
 }
SET CLOCK FUNCTION:

Code: Select all

void SetClock1(){
//OSCILLATOR_Initialize
// NOSC HFINTOSC; NDIV 4;

OSCCON1 = 0x62;

// CSWHOLD may proceed; SOSCPWR Low power; SOSCBE crystal oscillator;

OSCCON3 = 0x00;

// LFOEN disabled; ADOEN disabled; SOSCEN disabled; EXTOEN disabled; HFOEN disabled;

OSCEN = 0x00;

// HFFRQ 32_MHz;

OSCFRQ = 0x07;

// HFTUN 0;

OSCTUNE = 0x00;
}
MAIN:

Code: Select all

void main() {
unsigned char CRam1[3];
// PORT SET
TRISA=0b00000100;  //SET RA2 AS INPUT OTHER OUTPUT
TRISB=0b00000000;
TRISC=0b00000000;  //0=output, 1=input
PORTA=0; PORTB=0; PORTC=0;

// Disable comparators
  C1ON_bit = 0;
  C2ON_bit = 0;
  CM1CON0=0;
  CM2CON0=0;
  ANSELA = 0x00;  // configure all PORTA pins as digital
  ANSELB = 0x00;  // configure all PORTB pins as digital
  ANSELC = 0b00001111;//select PORTC ch:0,1,2,3 Acquairing Vu-Meter and Spectrum

  SetClock1();

  UART1_Remappable_Init(9600);
  RC5PPS = 0x14;// 00010100 PIN Rxy OUTPUT SOURCE SELECTION REGISTER source is TX/CK(1)                                                           // UART Tx output RC5
  RXPPS = 0x14; // 00010100 PERIPHERAL xxx INPUT SELECTION input is RC4 RX                                                          // UART RX input RC4
  Delay_ms(100);                                                              // UART settle time
  //arm_interrupt_timer0();
  INTPPS = 0x02; //INTPPS = 0b00000010;  //RA2 > INT 0x0002
  Delay_ms(100);
  INTCON.INTEDG = 0;  //Interrupt on falling edge of INT pin (fronte di discesa)
  //PEIE_bit = 1;
  PIE0.INTE = 1;
  INTCON.GIE = 1;
  IR_flag = 0;
    
  UART1_Write_Text (" Test : \r\n");
    
    while(1){
        if(RC5_Flag) {IR_flag=0; UART1_Write_Text("Interrupt on RA2 OK!!\r\n");
        ByteToHex(Address,CRam1); UART1_Write_Text(CRam1);
        UART1_Write_Text(TAB);
        ByteToHex(Comando, CRam1); UART1_Write_Text(CRam1);
        UART1_Write_Text("\r\n");
        }
        RC5_Flag = 0;
    }
}

RECEIVER FUNCTION:

Code: Select all

void IR_Receiver(){
   RC5_Flag=0;
   i=1; Comando=0x00; Address=0x00;
  // Check if the received signal is RC5 protocol
  if(~PORTA.B2) { Delay_us(889); }
  else return;

  Delay_us(30);  // Delay for Adjust time.

  if(PORTA.B2) {Delay_us(889); }
  else return;
  
  // while wait last start and toggle signal
  if(~PORTA.B2) {Delay_us(1778); }//1778 while(~PORTA.B2);
  else return;

  Delay_us(2040);  // Delay for Adjust time. 2600(03) 2663 1910 1990 2000 2040

  while (i < 12) {
       
         if(i < 6) {                 // READ ADDRESS BIT  was 6
            if(PORTA.B2){
              LATC7_bit = 1;  Delay_us(1);  LATC7_bit = 0;	// SIGNAL TRIGGER TEST
              Address &=  ~(1 << (5-i)); //CLEAR BIT 5-i
              }
            else {
              LATC7_bit = 1;  Delay_us(1);  LATC7_bit = 0;	// SIGNAL TRIGGER TEST
              Address |= (1 << (5-i)); //SET BIT 5-i
              }
            Delay_us(1730);
            }
        
         else {                          //READ COMMAND BIT
            if(PORTA.B2){
              LATC7_bit = 1;  Delay_us(1);  LATC7_bit = 0;	// SIGNAL TRIGGER TEST
              Comando &= ~(1 << (11-i)); //CLEAR BIT 11-i
              }
            else {
              LATC7_bit = 1;  Delay_us(1);  LATC7_bit = 0;	// SIGNAL TRIGGER TEST
              Comando |= (1 << (11-i)); //SET BIT 11-i
              }
            Delay_us(1800);
            }
         i++;
      }  // end while
  RC5_Flag = 1;
}  // END FUNCTION
Attachments
1° TIMING ADJUST HALF TIME BETWEEN 1 AND HALF TIME BETWEEN 0 LOGIC ; SO PIC MCU PIN CAN READ BOTH LOGIC LEVELS.<br />THIS TIMING MADE SOME RESULTS.
1° TIMING ADJUST HALF TIME BETWEEN 1 AND HALF TIME BETWEEN 0 LOGIC ; SO PIC MCU PIN CAN READ BOTH LOGIC LEVELS.
THIS TIMING MADE SOME RESULTS.
ExtemeValuesDebug_1.jpg (353.37 KiB) Viewed 825 times
2° TIMING ADJUST ON THE FALLING EDGE. AT 0 LOGIC LEVEL. BUT IS IMPOSSIBLE STAY EXATLY ON THE FALLIN EDGE OF 0 !!!! HOW WANT MANCHESTER CODE SPECIFICS.<br />THIS TIMING NO MADE ANY RESULTS IN THIS CONDITION. (if I understood this guide ! )
2° TIMING ADJUST ON THE FALLING EDGE. AT 0 LOGIC LEVEL. BUT IS IMPOSSIBLE STAY EXATLY ON THE FALLIN EDGE OF 0 !!!! HOW WANT MANCHESTER CODE SPECIFICS.
THIS TIMING NO MADE ANY RESULTS IN THIS CONDITION. (if I understood this guide ! )
IR_considerations_1.jpg (396.36 KiB) Viewed 850 times
Last edited by leo73 on 01 Feb 2023 09:41, edited 3 times in total.

leo73
Posts: 252
Joined: 09 Jan 2014 15:45

Re: RC5 IR Protocol Receiver 16F183463 MCU SOLVED

#3 Post by leo73 » 28 Jan 2023 12:27

Hello to Every One,

Theory is different from practice!!!
Dozens of codes (more or less complex using Timers too) have been written on the RC5 coding but no one clarifies, this is simplest code.

The RC5 decoding didn't work well because I confused the NOT " ! " operator with this " ~ " in follow block:
28.Jan.23 at 16.24 Decode now work fine and releiable, receives at 6 meters by powering the transmitter at 4.5V
PS:It is mandatory to have a logic analyzer. This is because, although the interrupt routine has absolute priority over the other routines, there is always a need for minor timing tweaks when inserting RC5 code into different projects.
http://www.qdkingst.com/en/products

Code: Select all

while (i < 12) {

         if(i < 6) {                 // READ ADDRESS BIT  was 6
            if(PORTA.B2){
               //Test signal trigger.
             //LATC7_bit = 1;  Delay_us(1);  LATC7_bit = 0;.  // Test signal trigger 
              Address &=  ~(1 << (5-i)); //CLEAR BIT 5-i		// for number you must use " ~ " and not " |"
              }
            else {
              //Test signal trigger.
              //LATC7_bit = 1;  Delay_us(1);  LATC7_bit = 0;.  // Test signal trigger .  
              Address |= (1 << (5-i)); //SET BIT 5-i
              }
            Delay_us(1742);  // 1735
            }
         else {                          //READ COMMAND BIT
            if(PORTA.B2){
              //LATC7_bit = 1;  Delay_us(1);  LATC7_bit = 0;.  // Test signal trigger  //Test signal trigger.
              Comando &= ~(1 << (11-i)); //CLEAR BIT 11-i	// for number you must use " ~ " and not " |"
              }
            else {
              //LATC7_bit = 1;  Delay_us(1);  LATC7_bit = 0;.  // Test signal trigger 
              Comando |= (1 << (11-i)); //SET BIT 11-i
              }
            Delay_us(1800);
            }
         i++;
      }  // end while
Now i'll repost the IR_Receice Function, main code and interrupt code copy previous post:

Code: Select all

// Original code by Bencherouda Okba
void IR_Receiver(){
   RC5_Flag=0;
   i = 1; Comando=0x00; Address=0x00;
  // Check if the received signal is RC5 protocol
  if(~PORTA.B2) {Delay_us(889); }
  else return;

  Delay_us(300);  // Delay for Adjust time.

  if(PORTA.B2) {Delay_us(889);  }
  else return;

  Delay_us(800);
  
  // while wait last start and toggle signal
  if(~PORTA.B2) {Delay_us(1778); }//1778
  else return;

  Delay_us(700); //Delay for Adjust time. 2575  was2028

  while (i < 12) {

         if(i < 6) {                 // READ ADDRESS BIT  was 6
            if(PORTA.B2){
              Address &=  ~(1 << (5-i)); //CLEAR BIT 5-i
              }
            else {
              Address |= (1 << (5-i)); //SET BIT 5-i
              }
            Delay_us(1742);  // 1735  was1700
            }
         else {                          //READ COMMAND BIT
            if(PORTA.B2){
              Comando &= ~(1 << (11-i)); //CLEAR BIT 11-i
              }
            else {
              Comando |= (1 << (11-i)); //SET BIT 11-i
              }
            Delay_us(1800); //was 1778
            }
         i++;
      }  // end while
  RC5_Flag = 1;
}  // END FUNCTION
related topic:
viewtopic.php?f=88&t=79758
do you have any suggestions please? 8)
In attachements TEST RECEIVED CODE ON UART, and full project():
Attachments
Update 28.Jan.23 at 16.17
Update 28.Jan.23 at 16.17
LogicState_2.jpg (110.47 KiB) Viewed 757 times
Update 28.Jan.23 at 16.17
Update 28.Jan.23 at 16.17
Debug-Full_1.jpg (216.67 KiB) Viewed 757 times
TestInterruptRA2-IR-Uart16F18346-V3.2.zip
28.Jan.23 at 16.06
Improved the timing on the 2 start bit and toggle bits, now the transmission goes beyond 5 meters (powered 4.5v the Trasmitter) and is no longer wrong to read the received values.
(53.88 KiB) Downloaded 30 times
Last edited by leo73 on 01 Feb 2023 09:41, edited 2 times in total.

leo73
Posts: 252
Joined: 09 Jan 2014 15:45

Re: RC5 IR Protocol Receiver 16F183463 MCU SOLVED LOOK LAST REPLY

#4 Post by leo73 » 30 Jan 2023 13:53

Hello to Every one,

31.Jan.2023
Last Step was write RC5 code using Toggle bit recognizzation + 2° stop bit recognizzation, below code and timing test.
NOTE: Internal clock 32mhz

Code: Select all

void IR_Receiver() {
i = 1; Comando=0x00; Address=0x00;
  // 1° Start Bit Check if the received signal is RC5 protocol
  if(~PORTA.B2) {
     _asm nop;    // Use it if you commented Trigger signal it take 100ns
     //LATC7_bit = 1; LATC7_bit = 0;    //this trigger take 100ns
     Delay_us(889); }
  else return;

  Delay_us(400);  // Delay for Adjust time.

  if(PORTA.B2) {
     _asm nop;  // Use it if you commented Trigger signal it take 100ns
     //LATC7_bit = 1;  LATC7_bit = 0;    //this trigger take 100ns
     Delay_us(889);
     }
  else return;

  // 2° start Bit
   if(~PORTA.B2) {
     _asm nop;    // Use it if you commented Trigger signal it take 100ns
     //LATC7_bit = 1; LATC7_bit = 0;    //this trigger take 100ns
     Delay_us(889);}
   else return;

  // while wait toggle signal
  if(~PORTA.B2) {   // toggle = 1
        _asm nop;   // Use it if you commented Trigger signal it take 100ns
        //LATC7_bit = 1; LATC7_bit = 0;   //this trigger take 100ns
        Delay_us(1878);
        toggle = 0;
        }
  else {
        _asm nop;   // Use it if you commented Trigger signal it take 100ns
        //LATC7_bit = 1; LATC7_bit = 0;   //this trigger take 100ns
        toggle = 1; Delay_us(2000);}

  //Delay for Adjust time.
  if(toggle) Delay_us(600);
  else Delay_us(650);

  while (i < 12) {

         if(i < 6) {                 // READ ADDRESS BIT  was 6
            if(PORTA.B2){
              _asm nop;  // Use it if you commented Trigger signal it take 100ns
              //LATC7_bit = 1; LATC7_bit = 0;   //this trigger take 100ns
              Address &=  ~(1 << (5-i)); //CLEAR BIT 5-i
              }
            else {
              _asm nop;  // Use it if you commented Trigger signal it take 100ns
              //LATC7_bit = 1;  LATC7_bit = 0;   //this trigger take 100ns
              Address |= (1 << (5-i)); //SET BIT 5-i
              }
            Delay_us(1720); //widen or narrow reading range
            }
         else {                          //READ COMMAND BIT
            if(PORTA.B2){
              _asm nop;  // Use it if you commented Trigger signal it take 100ns
              //LATC7_bit = 1;  LATC7_bit = 0;  //this trigger take 100ns
              Comando &= ~(1 << (11-i)); //CLEAR BIT 11-i
              }
            else {
              _asm nop;  // Use it if you commented Trigger signal it take 100ns
              //LATC7_bit = 1;  LATC7_bit = 0;  //this trigger take 100ns
              Comando |= (1 << (11-i)); //SET BIT 11-i
              }
            Delay_us(1720); //widen or narrow reading range
            }
         i++;
      }  // end while
  RC5_Flag = 1;
}
Togglebit is used for not repeat command if you you keep the button pressed, the toggle causes the same command to be received only once, here the Toggle manage: (paste it in the main)

Code: Select all

void main(){
// VARIABLES DEFINITION
bit toggle_appo;
.
.
// INIT YOUR CODE (PINS SETTING, CLOCK, I2C, UART, ETC...)
.
.
.
 while {
    // HERE ALL YOUR CODE
    .
    .
    .
    .
    .
    if(RC5_Flag) {
   	if( (Address==0x01 & Comando==0x01)&(toggle_appo == ~toggle) ){
     		// HERE YOUR CODE....SET VARIABLES, ETC       toggle_appo=toggle; }
   	if( (Address==0x1D & Comando==0x0D)&(toggle_appo == ~toggle) ){
     		// HERE YOUR CODE....SET VARIABLES, ETC    toggle_appo=toggle;}
    RC5_Flag = 0;
  } END WHILE
} //END MAIN
Attachments
TestInterruptRA2-IR-Uart16F18346-V3.1&V1.0ToggleBit-2StopBit.zip
01.Jan.23 22.50 Ver.3,2 Improved.
Improved timing. Code WORK fine.
IMPORTANT: Function interrupt must be shortest as possible (it's is a little special part of memory) so you need enclose IRC5 code in one separate function and call it in Interrupt function.
This because you can have problems assembly all tougether I2C library for example, or other library.
(152.17 KiB) Downloaded 17 times
RC5-WITH-TOGGLE-Timing_1.jpg
RC5-WITH-TOGGLE-Timing_1.jpg (554.76 KiB) Viewed 726 times

Post Reply

Return to “mikroC PRO for PIC General”