interfacing IR remote using NEC protocol - mikroc for PIC

Status
Not open for further replies.

venthan

Junior Member level 3
Joined
Jul 23, 2018
Messages
27
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
272
Hello,

I am trying to interface IR remote control(NEC Protocol) using 16f887 pic microcontroller. Coding objective is to read the IR signal and has to be display the equalant HEX value of command and address. While testing in hardware IR signal is not detecting but got random output. Tried a lot to solve the issue but failed. Here I have attached the coding kindly help me out. Thanks in advance.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
sbit LCD_RS at Rd1_bit;
sbit LCD_EN at Rd2_bit;
sbit LCD_D4 at Rd4_bit;
sbit LCD_D5 at Rd5_bit;
sbit LCD_D6 at Rd6_bit;
sbit LCD_D7 at Rd7_bit;
sbit LCD_RS_Direction at TRISd1_bit;
sbit LCD_EN_Direction at TRISd2_bit;
sbit LCD_D4_Direction at TRISd4_bit;
sbit LCD_D5_Direction at TRISd5_bit;
sbit LCD_D6_Direction at TRISd6_bit;
sbit LCD_D7_Direction at TRISd7_bit;
// End LCD module connections
 
bit nec_ok;
char text[5];
unsigned short nec_state, command, inv_command, i;
unsigned int address, timer_value;
unsigned long nec_code;
 
void Interrupt() {
  if (RBIF_bit && RBIE_bit){         // PORTB change ISR
    RBIF_bit = 0;
    if(nec_state != 0){
      timer_value = (TMR1H << 8) + TMR1L;           // Store Timer1 value
      TMR1H = 0;                                    // Reset Timer1
      TMR1L = 0;
    }
    switch(nec_state){
     case 0 :                                       // Start receiving IR data (we're at the beginning of 9ms pulse)
       TMR1H = 0;                                   // Reset Timer1
       TMR1L = 0;
       TMR1ON_bit = 1;                              // Enable Timer1
       nec_state = 1;                               // Next state: end of 9ms pulse (start of 4.5ms space)
       i = 0;
       break;
     case 1 :                                       // End of 9ms pulse
       if((timer_value > 9500) || (timer_value < 8500)){         // Invalid interval ==> stop decoding and reset
         nec_state = 0;                             // Reset decoding process
         TMR1ON_bit = 0;                            // Disable Timer1
       }
       else
         nec_state = 2;                             // Next state: end of 4.5ms space (start of 562µs pulse)
       break;
     case 2 :                                       // End of 4.5ms space
       if((timer_value > 5000) || (timer_value < 4000)){
         nec_state = 0;                             // Reset decoding process
         TMR1ON_bit = 0;                            // Disable Timer1
       }
       else
         nec_state = 3;                             // Next state: end of 562µs pulse (start of 562µs or 1687µs space)
       return;
     case 3 :                                       // End of 562µs pulse
       if((timer_value > 700) || (timer_value < 400)){           // Invalid interval ==> stop decoding and reset
         TMR1ON_bit = 0;                            // Disable Timer1
         nec_state = 0;                             // Reset decoding process
       }
       else
         nec_state = 4;                             // Next state: end of 562µs or 1687µs space
       return;
     case 4 :                                       // End of 562µs or 1687µs space
       if((timer_value > 1800) || (timer_value < 400)){           // Time interval invalid ==> stop decoding
         TMR1ON_bit = 0;                            // Disable Timer1
         nec_state = 0;                             // Reset decoding process
         return;
       }
       if( timer_value > 1000)                           // If space width > 1ms (short space)
         nec_code = 1 << (31 - i);       // Write 1 to bit (31 - i)
       else                                              // If space width < 1ms (long space)
         nec_code = 0 << (31 - i);    // Write 0 to bit (31 - i)
       i++;
       if(i > 31){                                  // If all bits are received
         nec_ok = 1;                                // Decoding process OK
         RBIE_bit = 0;                              // Disable PORTB change interrupt
         return;
       }
       nec_state = 3;                               // Next state: end of 562µs pulse (start of 562µs or 1687µs space)
    }
  }
  if (TMR1IF_bit){                 // Timer1 ISR
    TMR1IF_bit = 0;                // Clear Timer1 overflow flag bit
    nec_state = 0;                 // Reset decoding process
    TMR1ON_bit = 0;                // Disable Timer1
  }
}
 
void main() {
 OSCCON = 0X70;
  trisd = 0x00;
  trisb0_bit = 1;
  ansel = 0x00;
  nec_ok = 0;
  nec_state = 0;
  ANSELH = 0;                      // Configure all PORTB pins as digital
  Lcd_Init();                      // Initialize LCD module
  Lcd_Cmd(_LCD_CURSOR_OFF);        // cursor off
  Lcd_Cmd(_LCD_CLEAR);             // clear LCD
  TMR1IF_bit = 0;                  // Clear Timer1 overflow interrupt flag bit
  TMR1IE_bit = 1;                  // Enable Timer1 overflow interrupt
  T1CON = 0x10;                    // Set Timer1 clock source to internal with 1:2 prescaler (Timer1 clock = 1MHz)
  INTCON = 0x90;
  INTF_bit = 0;
  INTE_bit = 1;
  IOCB0_bit = 1;
  OPTION_REG = 0XC0;
  Lcd_out(1,5,"welcome");
  Lcd_out(2,2, "dear");
  delay_ms(1000);
  Lcd_cmd(_lcd_clear);
  Lcd_Out(1, 1, "Address:0x0000");
  Lcd_Out(2, 1, "Com:0x00 In:0x00");
  delay_ms(1000);
  while(1) {
    while(nec_ok)                // Wait until NEC code receiver
    nec_ok = 0;                    // Reset decoding process
    nec_state = 0;
    TMR1ON_bit = 0;                // Disable Timer1
    address = nec_code >> 16;
    command = nec_code >> 8;
    inv_command = ~command ;
    IntToHex(address, text);       // Save address in string text with hex format
    Lcd_Out(1, 11, text);          // Display address
    ByteToHex(command, text);      // Save command in string text with hex format
    Lcd_Out(2, 7, text);           // Display command
    ByteToHex(inv_command, text);  // Save inverted command in string text with hex format
    Lcd_Out(2, 15, text);          // Display inverted command
    RBIE_bit = 1;                  // Enable PORTB change interrupt
  }
}

 

Will try that and update you for the same.
 

The project will still not work.

You have failed to enable RBIE before the while(1) loop.

What CPU clock frequency are you using?
 

* Yes sir, as you said output is not coming after changing the while condition. Not even random output is received.
* Mu cpu clock frequency is 1.8 GHz.
* IF I enable RBIE before loop, lcd is simply remains blank. nothing works.

Help me out..
 

Wow! That's a fast PIC!

I think hexreader was referring to the PIC clock frequency not your PC.

Brian.
 

Wow! That's a fast PIC!

I think hexreader was referring to the PIC clock frequency not your PC.

Brian.

I was thinking the same brain, My MCU frequency is 8 MHz.
 

Your code seems hopelessly confused.

You enable RB0 external interrupt and PORTB interrupt on change, yet you handle only interrupt on change.

Why are you using both sorts of interrupt?

Where is the code for changing from falling edge detection to rising edge detection?

Did you write this code, or did you find it on the internet?
 
hexreader,

I got this code from internet. While trying to execute in hardware I got this sort of problems. I already wrote a code for simple interrupt and executed successfully. But this seems bit of complication, so decided to take code from web. But still I can fix the issues if you guide me...
 

You should have left that code where it was. It is complete garbage.

I am close to a fixed version, but it currently works for one IR remote that I own, but not a second TV remote.

Not sure if this forum allows zip file to be attached, but I will try....
 

Attachments

  • IRnec.zip
    45 KB · Views: 319
Hexreader,

Many Thanks for sharing the code. I will test and update you for the same.
 

Hi hexreader,

It is working but most of the times it gets strucked, after few button press. Then we have to restart it again to accept signal. What could be the issue. I'm attaching my hardware image kindly suggest the suitable solution. Thanks in advance.
 

Yes, I have exactly the same problem. It is a software problem, not a hardware problem

Still working on it....

May take a long time, as I do not fully understand how the original code was supposed to work and it is all a bit of a mess.
 
Hexreader,

Thanks for your assistance. I will try the same from my side and update to you with progress.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…