Infrared decoder

Tips, Tricks and methods for programming, learn ways of making your programming life easier, and share your knowledge with others.

Moderators: Benj, Mods

Post Reply
jose
Flowcode V4 User
Posts: 26
Joined: Sat Nov 01, 2008 12:11 am
Has thanked: 7 times
Been thanked: 10 times
Contact:

Infrared decoder

Post by jose »

This program uses a micro controller PIC16F877 running at 4MHz to decode infra red signals from a remote control using Philips RC5 protocol. It can be used to test any remote controls and to switch 8 devices using an RC5 remote control. The address and command decimal values are show on a 16x4 LCD display. Keys 1 to 8 of remote control are used to control individually 8 bits of PORTD, switching on/off any AC or DC devices using e.g. an 8 relay board. The Standby key is used to switch on/off all 8 outputs. There are also 8 push to make switches to toggle manually the state of any output. By pressing switch 1 and 2 at the same time, will switch on/off all outputs. The state of outputs is show on the LCD display. Bit 6 and 7 of PORTB are used to select the address mode to the output control; 00=TV, 01=VCR, 10=SAT, 11=Hi-Fi.
The main flowchart set the LCD display on PORTA, initializes ports, read the state of bit 6 and 7 to variable “mode”, enable RB0/INT interrupt and starts a loop.
A transition of 1 to 0 on RB0/INT pin, will call “start” macro, just used to set a variable and call “ir_dec” macro. Inside “ir_dec” macro, some delays to read RB0 near the end of S1 bit, beginning and second half of S2 bit. If they are “010”, the signal comes from a valid RC5 remote control. More delays to skip toggle bit, not used here, and start to read the 5 bits address and 6 bits command to “adr” and “cmd” variables. Along “ir_dec” macro, 14 pulses of about 300us each are generated on RE0 pin to show on a oscilloscope the reading points of initial bits, and each address/command bits - always on second half. After a successful IR decoding, “ir_dec” macro calls the “output” macro. Inside “output” macro the display shows address and command values in decimal, compares “adr” and “mode” variables to validate the device mode used, and send “cmd” variable value to PORTD, displaying the output state in binary.
A blinking LED on RE1 pin show the activity of all non RC5 remote controls.
The main loop also calls “sw_key” macro to read PORTC switches to control manually PORTD outputs.

an exemple how to build ir receiver e-block:
Attachments
an exemple how to build ir receiver e-block
an exemple how to build ir receiver e-block
ir eblock.jpg (94.41 KiB) Viewed 16362 times
an exemple how to build ir receiver e-block
an exemple how to build ir receiver e-block
IReblock_pict.jpg (35.95 KiB) Viewed 16377 times
ir_test_cmd.fcf
Flowchart
(48 KiB) Downloaded 1630 times
Last edited by jose on Sat Jan 17, 2009 11:53 am, edited 2 times in total.

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: Infra red decoder

Post by Benj »

Great article thanks Jose.

jadiflow
Flowcode v5 User
Posts: 273
Joined: Thu Apr 17, 2008 9:59 am
Has thanked: 19 times
Been thanked: 16 times
Contact:

Re: Infra red decoder

Post by jadiflow »

Jose,

Thanks for that! Just something I needed!

Jan Didden

jose
Flowcode V4 User
Posts: 26
Joined: Sat Nov 01, 2008 12:11 am
Has thanked: 7 times
Been thanked: 10 times
Contact:

Re: Infra red decoder

Post by jose »

Hi Ben, Jan and all forum users
I'm glad you can find it useful
Thanks Matrix team

Regards,
JosΓ©

jadiflow
Flowcode v5 User
Posts: 273
Joined: Thu Apr 17, 2008 9:59 am
Has thanked: 19 times
Been thanked: 16 times
Contact:

Re: Infra red decoder

Post by jadiflow »

Hello JosΓ©,

Have been looking at your RC5 decoding routine. I have been using something else that I wrote in assembler until now. This used TMR0 to count the usecs between RC5 pulses, and from that determines whether the received bit is a 1 or 0, or, if the timer runs out, decide it was not a valid message. You get the idea.

In your routine, you don't use a timer (which is good, as I need it for something else!), but you have delays to wait a specific time from a received pulse and from that you can decide whether you received a 1 or 0. So far so good.

What I'm a bit confused about is that at initialisation you enable the interrupt (RB0) but you never disable/re-enable it. When you are in your decoding routine, doing the delays for the next value, you jump to the interrupt service routine to set a flag and back all the time, right? I'm not saying it doesn't work (it does), just trying to understand it.

Jan Didden

jose
Flowcode V4 User
Posts: 26
Joined: Sat Nov 01, 2008 12:11 am
Has thanked: 7 times
Been thanked: 10 times
Contact:

Re: Infra red decoder

Post by jose »

Hello Jan,

I first start to enable RB0/INT inside main loop and then disable it inside ir_dec routine. It works almost the same but it had some little problems: I think it has with non rc5 remote control.
The way I understand it, the interrupt is enabled just once and is used only for the first 1 to 0 transition on rb0, then it calls ir_dec routine and stays there polling rb0 14 times. The interrupt will be used again when the program returns from ir_dec macro or others.
I used rb0/int interrupt for more accuracy detecting the first pulse. The program will work if you replace the interrupt for one input icon to read rb0 (or other) and one decision icon to call ir_dec macro when it is 0(inside a loop), but you will have some more errors because some times it can read the rb0 pin some time after that it really happen.
You can see in the picture below the signal coming from TSOP1736 (ch1) and the pulse generated by software on RE1 pin to show reading points (ch2).
It is key 0 in TV mode (address and command =0)

Regards,
jose
oscilloscope screen shot
oscilloscope screen shot
scope.gif (6.56 KiB) Viewed 16137 times

jadiflow
Flowcode v5 User
Posts: 273
Joined: Thu Apr 17, 2008 9:59 am
Has thanked: 19 times
Been thanked: 16 times
Contact:

Re: Infra red decoder

Post by jadiflow »

Neat. I can see it works very well and I agree that it is best to detect the initial puls with an interrupt. What I did in my assembly routine was to do *all* pulse detections by interrupt. Iow, at each pulse I disable interrupts, look at the elapsed time since the last pulse and decide whether it was a 1 or 0 bit, store the bit, then re-enable the interrupt and the clock and returned to the caller. My idea was that spending all that time in ir_dec until the last pulse takes too much time. But, since a complete command is only 25mS or so, it is probably a moot point anyway.
I like the way you enable external check of the routine with that pulse generator; something I can use in other projects!

regards,

Jan Didden

jose
Flowcode V4 User
Posts: 26
Joined: Sat Nov 01, 2008 12:11 am
Has thanked: 7 times
Been thanked: 10 times
Contact:

Re: Infra red decoder

Post by jose »

Hi Jan,
The interrupt process that you used to detect pulses is precise and better.
I tried to use the same process, but I wasn’t sure how to do it. It's something I still like to do…
If you or someone have any ideas how to do it with Flowcode, please let me know.
Regards
Jose

jose
Flowcode V4 User
Posts: 26
Joined: Sat Nov 01, 2008 12:11 am
Has thanked: 7 times
Been thanked: 10 times
Contact:

Re: Infrared decoder

Post by jose »

Hi,

The IR e-block draw is wrong! It still works but the correct way is to connect 22K resistor to +5V.
Sorry…
Attachments
IReblock2.jpg
IReblock2.jpg (21.06 KiB) Viewed 14883 times

singhdeol
Posts: 30
Joined: Sat Dec 18, 2010 6:07 am
Has thanked: 6 times
Been thanked: 2 times
Contact:

Re: Infrared decoder

Post by singhdeol »

Thank you very much for the article :mrgreen:

Post Reply