Log in

View Full Version : Trying to build an IR project



financecatalyst
- 6th November 2009, 18:26
Hi, I am trying to build an IR based transmitter and receiver. I have few questions I would like to ask:
1) Can it be done using any PIC? I have a good stock of 12f635
2) Is data transmitted by simply flashing led at 38-40kHz and controlling the time between each burst?
3) Is 0 & 1 are the only type we can send - like for eg 38kHz for 12mS=0 & 38kHz for 30mS=1 or more data can be incorporated

By knowing this I can atleast know how to proceed about it
Thanks

dhouston
- 6th November 2009, 18:44
1. Any PIC that can generate 38-40kHz should work.

2. You can control the duration of both the bursts and the idle time between bursts.

3. There are several methods used. You should Google for NEC, Sony, & Philips IR protocols. This will give you a good introduction to the most common protocols. If you want to get a bit more sophisticated, you can have multiple durations for both bursts and idle spaces. With 5 possibilities for each you can encode an enormous amount of data. For example, if you let ABCDE represent 5 burst times and abcde represent 5 idle times, you have a 10 letter alphabet to play with. However, the more complex the message, the more horsepower you need at the receiver.

EDIT: Here's a website with many of the most used protocols. http://www.sbprojects.com/knowledge/ir/ir.htm

Byte_Butcher
- 6th November 2009, 18:49
I found this article to be helpful:

http://www.picbasic.co.uk/support/Article.pdf



steve

mackrackit
- 6th November 2009, 19:25
Go here for good info.
http://www.rentron.com/remote.htm

Macgman2000
- 6th November 2009, 19:32
I have used a couple of methods for the transmitter, all work equally well.

1). Bit bang. Togggle a pin for a duration of 1ms or whatever cadence your receive module allows for logic "1" output. Most RX module output is inverted due to a pullup resistor on the data out line. Look at the data sheet pulse width and duration diagrams. So in your code you shift a bit and test for 1 or 0 then either pause for a zero or toggle at 38Khz for a duration of 1ms (or whatever your receive module wants to see) and do it until all 8 bits have been sent out.

Advantage: you use only 1 TX pin.
Disadvantage: you are stuck in the main loop while transmitting.

2). Hardware PWM. Configure either a 16F88, 16F877A..etc with hardware PWM to output a 38Khz pulse train. Use a 2nd I/O to output your data using serout and put your IR LED between the PWM out port and data out port. The LED will flash at 38Khz encoding your data being transmitted.

Advantage: no bit banging, you can use the built in serout to transmit serially.
Disadvantage: 2 pins

Nick

financecatalyst
- 6th November 2009, 20:10
I found this article to be helpful:

http://www.picbasic.co.uk/support/Article.pdf



steve

Hi, Very useful document. I may be wrong but I want to confirm if it is a mistake in the document or my understanding. In listing 9 of the document, it says :

If IR_Dec<>0 then goto again
Should it not be 1 instead of zero as in the same document towards the top it says television Device id is 1?

1) By the way have you got any resourse like this which can explain the transmitting part as well?
2) Does it means that all Sony TVs can be controlled with same remote controll?

financecatalyst
- 6th November 2009, 21:50
I have used a couple of methods for the transmitter, all work equally well.

1). Bit bang. Togggle a pin for a duration of 1ms or whatever cadence your receive module allows for logic "1" output. Most RX module output is inverted due to a pullup resistor on the data out line. Look at the data sheet pulse width and duration diagrams. So in your code you shift a bit and test for 1 or 0 then either pause for a zero or toggle at 38Khz for a duration of 1ms (or whatever your receive module wants to see) and do it until all 8 bits have been sent out.

Advantage: you use only 1 TX pin.
Disadvantage: you are stuck in the main loop while transmitting.


One thing to begin with, I never know which PIC has HPWM, is it normally written in the datasheet?

I have 12F635 - is it capable to follow the above method? Is it possible you can write few lines of the code mainly to get 38kHz, I can try to manage the rest of the code. Thanks a lot

Byte_Butcher
- 7th November 2009, 02:29
Hi, Very useful document. I may be wrong but I want to confirm if it is a mistake in the document or my understanding. In listing 9 of the document, it says :

If IR_Dec<>0 then goto again
Should it not be 1 instead of zero as in the same document towards the top it says television Device id is 1?

Yes, the Sony TV device code is 1, so that bit of code is probably wrong.



1) By the way have you got any resourse like this which can explain the transmitting part as well?


I don't have any URL's handy for transmitting but I ran across lots of that info during my brief research on receiving and decoding Sony protocol. I'm sure Google is your friend though. :)



2) Does it means that all Sony TVs can be controlled with same remote controll?


No. There's at least 3 different Sony protocols that I found in my brief search. Sony12, Sony15, and Sony20.
They are similar, but the number of transmitted bits varies. (12, 15, 20). The extra bits allows addressing more devices and commands.
For my purpose the simplest one, sony12 was adequate, so that's what I used.

FWIW, here's a site with a lot of good Sony IR info:
http://www.hifi-remote.com/sony/


If you are going to play with IR remotes, I'd like to recommend one of Tommy Tylers "USB IR Widgets". (Infrared signal recorder)
It plugs into a USB port and receives signals from your remote. The software that you download for it gives a great visual representation of the signal, gives duration times for the bits and spaces, operating frequency of the remote, what button was pressed, and what protocol it speaks (if the software recognizes it.) and more. For about $30 it's a handy (and fun) learning tool. If you are building your own PIC based IR transmitter,it should be a great diagnostic tool.
You can read out about the USB IR widget, and download it's software and operating instructions here. (About 1/2 way down the page):
http://www.hifi-remote.com/forums/viewtopic.php?t=9405

I have NO affiliation with Tommy or his store, but I bought a widget and like it, and it shipped fast after I ordered it. No complaints here.


Good luck!


steve

dhouston
- 7th November 2009, 02:34
For about $30 it's a handy (and fun) learning tool. If you are building your own PIC based IR transmitter,it should be a great diagnostic tool.Or you can capture the pulsetrain with a soundcard and IR receiver for about $1.50 http://davehouston.org/learn.htm

Byte_Butcher
- 7th November 2009, 04:08
Or you can capture the pulsetrain with a soundcard and IR receiver for about $1.50 http://davehouston.org/learn.htm

Absolutely! Many different tools to suit your tastes and budget....

I started with a IR receiver (about $1.50) and my old Hitachi scope.

Then I progressed to the IR receiver, stuffed into my soundcard and recorded with Audacity ( http://audacity.sourceforge.net/ ) , which I've used for various signal capture fun for years.

The IR Widget just takes it a step further because the software helps tell you things about a remote that you would otherwise have to calculate or guess at yourself based on recorded scope patterns.

It's just another tool in the box. Use it or not as you please. :)


steve

Macgman2000
- 7th November 2009, 21:11
I am not at the office today so the best I can do (between "honey do" items) is the following for a 12F or 12C series. I think it was posted on rentron.com, this is an example not finished.

Use the inline assembler command in PBP and pop in the code segments that toggle at 38Khz..... you may need to do some massaging though with the code. Use a scope on the data out pin of the IR receiver to make sure your code gives you good solid data output. Do not test RX in close proximity to TX, put your tx out about 10ft or so to make sure even at low signal levels the data makes it through. The analog filters severely reduce signals that are slightly outside of it's center band.

So for every "1" call this in a subroutine with a counter to count 10x through the loop before exiting, for every "0" just pause an equal duration to a "1" for symmetry . If you can... set up your bit duration and start/stop bits so that it is compatible to Serin set for 1200bps on RX side for example....for ease.

Monday I will post 16F code to set the hardware PWM output to 38Khz.



PROCESSOR 12c508
#include "p12c508.inc"
__CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC
#DEFINE PORT B'11111101'
MOVF OSCCAL
MOVLW PORT
TRIS GPIO

BEGIN
BCF GPIO, 1 ;1uS
NOP ;2uS each nop is 1uS long
NOP ;3uS
NOP ;4uS
NOP ;5uS
NOP ;6uS
NOP ;7uS
NOP ;8uS
NOP ;9uS
NOP ;10uS
NOP ;11uS
NOP ;12uS
NOP ;13uS
NOP ;14uS
NOP ;15uS
NOP ;16uS
NOP ;17uS
NOP ;18uS
NOP ;19uS
BSF GPIO, 1 ;1uS Begin HIGH duty cycle
NOP ;2uS
NOP ;3uS
NOP ;4uS
NOP ;5uS
GOTO BEGIN ;2uS (26uS total for 38KHz)
END

financecatalyst
- 10th November 2009, 22:17
Ok then, thanks for all your help upto now. I think I need little more of it.

I have searched the internet and tried to understand the principle behind IR communication. I have made my very first Tx & Rx with that. It's not working as it should do.
It's not a completely dead scenario as I do see voltage fluctuations on the TSOP2438 IR Receiver module output pin when I switch on my transmitter and when I switch my Tx off it goes stable. I also looked into my webcam and could see the IR Tx LED glowing.

I attach my code here to have some feedback on any mistakes I am making. Thanks again.

Macgman2000
- 10th November 2009, 23:18
Do you have an oscilloscope? You have to look at the 38kHz coming out of the TX pin at the pic. You should have 13us high pulse then a 13us low pulse for a period of 26us.

Once you verify the above is happening correctly, then add the code that encodes a "1" bit and a "0" bit. Also IR RX modules do NOT want an IR DC carrier, in other words if you don't modulate at 38Khz with a data burst, shut off the IR LED. So between data transmissions (1 byte or 2 bytes..etc) send data then shut off the IR LED. I have seen many people get stuck on this nasty little characteristic of these devices and waste a lot of time debugging. If you do not the internal capacitive coupled amplifier stages and demodulation stage will charge up with a dc voltage. Within a 1sec to 2 saturate with no more data being demodulated. This is a bad thing.

Make sure that you format your data output based on your transmission speed. If you choose 1200bps then set the bit width (on/off duration) to this spec and don't forget 1 start bit and 1 stop bit for the Debug command at the receiver. It is easy to get caught up in the code and hardware and want to throw all together in one shot. This does not happen until you have done 1or 2 IR projects and discover the pitfalls. My advise, test in pieces.

Below is old TX code using hardware PWM for 16F877A to test IR modules...At the receive side I used Debugin with no other special consideration since the RX module gives me data out. The pause 5 statements need to be tweaked based on your IR module, this delay maybe too short and lead to saturation. I tested this at 40ft no problem very forgiving with the module I used.



INCLUDE "Modedefs.Bas"
@ device HS_OSC, LVP_OFF, WDT_OFF
; @ Device pic16F877A, HS_OSC, BOD_OFF, PWRT_ON, WDT_ON, PROTECT_OFF


DEFINE OSC 20



DEFINE DEBUG_REG PORTC ' point to portB for output
DEFINE DEBUG_BAUD 1200 ' set software TX to 1200 bps
DEFINE DEBUG_BIT 7 ' Set Debug pin bit
DEFINE DEBUG_MODE 0 ' Set Debug mode: 0 = true, 1 = inverted




CCPR1L = 64 ' Set PWM Duty-Cycle to 50%
CCPR2L = 64
PR2 = 128 ' Set PWM for 38.7KHz
CCP1CON = %00001100 ' Mode select = PWM
CCP2CON = %00001100
T2CON = %00000100 ' %00000100 = TMR2 ON 1:1 pre-scale
' %00000101 = TMR2 ON 1:4 pre-scale
' %00000110 = TMR2 ON 1:16 pre-scale



;set ports to output
TRISA = %00000000
TRISB = %00001111
TRISC = %00000000
TRISD = %00000000

; analog portA direction
ADCON1 = 7
CMCON = 7

portc.7=1 ; used to reverse bias LED to shut it off when direct driven (no transistor)


main:


if portb.1 = 0 then
debug 255, 50 ; left
pause 5
portc.7 = 1 ; used to reverse bias LED to shut it off when direct driven (no transistor)
goto main
endif

if portb.2 =0 then
debug 255, 10 ; right
pause 5
portc.7 =1
goto main
endif

if portb.3 = 0 then ; straight
debug 255, 100
pause 5
portc.7 = 1
goto main
endif

; The stop command is sent two times per loop to make sure the RX shuts off

debug 255, 0 ; stop
portc.7 = 1

pause 30


debug 255, 0 ; stop
portc.7 = 1

goto main

financecatalyst
- 10th November 2009, 23:48
Do you have an oscilloscope? You have to look at the 38kHz coming out of the TX pin at the pic. You should have 13us high pulse then a 13us low pulse for a period of 26us.

Once you verify the above is happening correctly, then add the code that encodes a "1" bit and a "0" bit. Also IR RX modules do NOT want an IR DC carrier, in other words if you don't modulate at 38Khz with a data burst, shut off the IR LED. So between data transmissions (1 byte or 2 bytes..etc) send data then shut off the IR LED. I have seen many people get stuck on this nasty little characteristic of these devices and waste a lot of time debugging. If you do not the internal capacitive coupled amplifier stages and demodulation stage will charge up with a dc voltage. Within a 1sec to 2 saturate with no more data being demodulated. This is a bad thing.

Make sure that you format your data output based on your transmission speed. If you choose 1200bps then set the bit width (on/off duration) to this spec and don't forget 1 start bit and 1 stop bit for the Debug command at the receiver. It is easy to get caught up in the code and hardware and want to throw all together in one shot. This does not happen until you have done 1or 2 IR projects and discover the pitfalls. My advise, test in pieces.

Below is old TX code using hardware PWM for 16F877A to test IR modules...At the receive side I used Debugin with no other special consideration since the RX module gives me data out. The pause 5 statements need to be tweaked based on your IR module, this delay maybe too short and lead to saturation. I tested this at 40ft no problem very forgiving with the module I used.



INCLUDE "Modedefs.Bas"
@ device HS_OSC, LVP_OFF, WDT_OFF
; @ Device pic16F877A, HS_OSC, BOD_OFF, PWRT_ON, WDT_ON, PROTECT_OFF


DEFINE OSC 20



DEFINE DEBUG_REG PORTC ' point to portB for output
DEFINE DEBUG_BAUD 1200 ' set software TX to 1200 bps
DEFINE DEBUG_BIT 7 ' Set Debug pin bit
DEFINE DEBUG_MODE 0 ' Set Debug mode: 0 = true, 1 = inverted




CCPR1L = 64 ' Set PWM Duty-Cycle to 50%
CCPR2L = 64
PR2 = 128 ' Set PWM for 38.7KHz
CCP1CON = %00001100 ' Mode select = PWM
CCP2CON = %00001100
T2CON = %00000100 ' %00000100 = TMR2 ON 1:1 pre-scale
' %00000101 = TMR2 ON 1:4 pre-scale
' %00000110 = TMR2 ON 1:16 pre-scale



;set ports to output
TRISA = %00000000
TRISB = %00001111
TRISC = %00000000
TRISD = %00000000

; analog portA direction
ADCON1 = 7
CMCON = 7

portc.7=1 ; used to reverse bias LED to shut it off when direct driven (no transistor)


main:


if portb.1 = 0 then
debug 255, 50 ; left
pause 5
portc.7 = 1 ; used to reverse bias LED to shut it off when direct driven (no transistor)
goto main
endif

if portb.2 =0 then
debug 255, 10 ; right
pause 5
portc.7 =1
goto main
endif

if portb.3 = 0 then ; straight
debug 255, 100
pause 5
portc.7 = 1
goto main
endif

; The stop command is sent two times per loop to make sure the RX shuts off

debug 255, 0 ; stop
portc.7 = 1

pause 30


debug 255, 0 ; stop
portc.7 = 1

goto main


Thanks for the reply. Your code surely is good but I don't have 16F877A and neither I am advance enough to use PWM technique at this stage and also even if I think about doing it that way my 12F635 does not have this feature.

"Do you have an oscilloscope?" - No, don't have access to one either. But the LED flashing part of the code is from a trusted source so 40kHz should not be a problem.

Now, with the code I have attached, can you see any obvious mistakes in it?
I know I am using 38kHz receiver BUT transmitting at 40kHz. It is because firstly, I have seen and read that this combination still works if you don't have access to a 40kHz IR Module and secondly, I don't have any knowledge about Assembly so thanks to Bruce @ Rentron (link: http://www.rentron.com/PicBasic/IR_Chips.htm) where I could get this piece of assembly code and stick it in my code as a module and modify my code for 12F635 and send 16 bits instead of 13.