You should be able to adapt my code. All you need is the details for each protocol of interest. See...
You should be able to adapt my code. All you need is the details for each protocol of interest. See...
That definitely is a start ...
Did you check the PM I sent you by the way ?
As much as I have read the info on the PULSIN command, it still leaves me somewhat confused.
I have seen many references to your code on the forum but I just can't seem to 'catch on' to the method
My blurred pseudo understanding of it is :
1.Wait for a certain pulse of specified duration (discard all other pulses we are not interested in)
2. Once the correct pulse is received then start counting pulses of a certain duration
3. Store each pulse as a bit. 8 pulses = a byte , 32 pulses = 4 bytes
4. Decipher the received/stored bits/bytes into a SYSTEM ID and a DEVICE ID.
So with reference to the diagram and the following quote:
http://www.sbprojects.com/knowledge/ir/rc5train.gif
And with reference to your codeThe first two pulses are the start pulses, and are both logical "1". Please note that half a bit time is elapsed before the receiver will notice the real start of the message.
Extended RC-5 uses only one start bit. Bit S2 is transformed to command bit 6, providing for a total of 7 command bits. The value of S2 must be inverted to get the 7th command bit though!
The 3rd bit is a toggle bit. This bit is inverted every time a key is released and pressed again. This way the receiver can distinguish between a key that remains down, or is pressed repeatedly.
The next 5 bits represent the IR device address, which is sent with MSB first. The address is followed by a 6 bit command, again sent with MSB first.
A message consists of a total of 14 bits, which adds up to a total duration of 25 ms. Sometimes a message may appear to be shorter because the first half of the start bit S1 remains idle. And if the last bit of the message is a logic "0" the last half bit of the message is idle too.
As long as a key remains down the message will be repeated every 114ms. The toggle bit will retain the same logical level during all of these repeated messages. It is up to the receiver software to interpret this auto repeat feature.
PS: I had rather a big error on this page for quite some time. For some mysterious reason the LSB and MSB of the address and command were reversed. I can recall correcting this error before, but somehow an old version of the description must have sneaked its way up to the internet again.
As soon as a pulse is received greater than 760 then INIT but what is the 760 ?Code:If (stx<760) Then init
andThis line is the same asCode:While GPIO.1=1:Wend 'wait space
So in other words keep looping while GPIO.1 is 1Code:While GPIO.1=1 Wend 'wait space
and as soon as it goes to a 0 then continue to the next line(s)
On the next section of code (the pulse count/bit catcher) you REPEAT the same thing until i is > 31 (since 0 to 31 is 32 pulses(1 or 0 bits) right ?
OK for me there is a little confusion in the above stub of the codeCode:Repeat PulsIn GPIO.1, 1, pulse If (pulse>100) Then IR.0(i)=1 'set bit EndIf i=i+1 Until (i>31)
So do we disregard any pulse less than 100 here ?Code:If (pulse>100) Then
and this line
[/code] IR.0(i)=1 [/code]
So the above begins to build the the array IR[4] (it's 4 since we need to catch 4 bytes (32 pulses/bits) not so ?)
The value "i" is the counter which is incremented evertime we loop through this section of code until the UNTIL condition is met (Ie. we have 32 bits or 4 bytes namely IR.0,IR.1IR.2and IR.3)
And finally to send what we have so far (the value of the 4 IR bytes to the PC serial port
I notice you display the HEX value here, is that because if it were decimal you might overflow the WORD var ?Code:For i = 0 To 3 Debug IHEX2 IR[i] Next
I also saw in another posting that there might be a reverse bit order sent through ... is that correct ?
In the meantime I will go through the link you sent and carefully examine the RC5 info and post what I have come up with albeit wrong.
Kind regards
Dennis
I hope you don't mind me asking a tally of questions to get a clearer understanding of the functions.
I have to catch 14 bits as opposed to 32 right ?
would this mean something likeIf that's the case then what about the pulse sizing ?Code:Until (i>13)
I am specifically referring to these lines
andCode:If (stx<760) Then init
I am correct so far then the above part is where the confusion starts and it has to do with the PULSIN command.Code:pulse>100
As i understand it the PULSIN command...
As per the manual
Fantastic , that explains the following (I think!)Measures pulse width on Pin.
If State is zero, the width of a low pulse is measured.
If State is one, the width of a high pulse is measured.
The measured width is placed in Var.
If the pulse edge never happens or the width of the pulse is too great to measure, Var is set to zero
Now here's the cruncher for meCode:While GPIO.1=1 Wend
This is a tad confusing, what about other values of oscillator ?The resolution of PULSIN is dependent upon the oscillator frequency. If a 4MHz oscillator is used, the pulse width is returned in 10us increments.
If a 20MHz oscillator is used, the pulse width will have a 2us resolution.
I am using a 4MHZ internal clock so therefore I would be looking at 10uS increments, but what does this mean exactly ? Does it mean the pulse is returned rounded off to the nearest 10uS ?
Another thing ...
So PULSIN reads ONLY the ACTUAL oscillator (crystal, R/C) so what happens if we were using this on an 18F4520 for example where you could use PLL , something like 8MHz x 4 to total up to 32MHz ..?Defining an OSC value has no effect on PULSIN.
The resolution always changes with the actual oscillator speed.
Is there some trick involved in that instance or do we then need to start looking at HPWM ?
Apologies for the what may appear as "dumb questions" but I am trying to keep them simple in order to explain my confusion.
And looking at the forums and various posts it seems you have so many asking similar thnigs about your code.
Kind regards
Dennis
Dennis,
I am not going to write your code for you. And I've already answered many of your questiions 2 or 3 times either here or in the many PMs you sent before I stopped responding. Here's a thread which includes code for capturing durations of both edges which you will likely need for RC5...
Dave thanks for the link as always.
For the record I have never wanted anyone, nor asked anyone to write code for me! I am not using PIC's nor electronics for any commercial gain ..it is merely a hobby !
I have asked only for code snippets to gain more of an understanding of certain aspects of a particular technology or to move past a struggling block.
So THANK YOU to you and to all the others who still reply no matter how many times they have heard and answered the same questions.
It's fantastic that so many here are happy to share code and experiences with others but please understand that as simple as it may seem for some to read and understand, it may take others lifetimes and that's where a few lines in a reply to a question will advance the learning process.
To err is human ... not so ?
So off I went
Forums,sites,articles, google,the manual, late nights, Dave's suggestions, Bruce's site, and Les Johnson's article oh yes and dome app note from microchip, and many cups of coffee.... I am slowly moving closer to some sort of understanding (or more confusion)....
See, the big problem was trying to grasp the PULSIN command and the resolutions @ given oscillator rates which LES JOHNSON does extremely well in the article "Controlling the world from your armchair" , in the article Les says
Well that certainly did start clearing up the a lot confusion I have had with the PULSIN command for so long, it is still a little confusing for me I must admit ..stupid human that I am !I hope that I’ve succeeded in illustrating
that both, infrared decoding and
PICmicro programming need not be the
exclusive property of the whizz kids or
rocket scientists among us.
Anyway , with enough bashing away and peeking and poking I finally came up with something that seems to work , but only with a certain remote code typed into a universal remote. At the moment there must be at least 12 different remote controls scattered around the workbench.
Here is the code :
The code behaves differently for most remotes and I'm sure only very well for those sending RC5 codes.Code:' Philips RC5 IR decoder for 12F629 @ 4MHZ 'set for samsung TV on universal rae-1000 (or similar??) remote - TV1 -code 189 most buttons work define OSC 4 '4MHz DEFINE OSCCAL_1K 1 ' Set OSCCAL for 1k -HELPS tuning the crystal for more accurate timing CMCON = 7 'TRISIO = %76543210 ' port GPIO 0=output and 1=input TRISIO = %00000010 ' GPIO.1 is an input all the rest are outputs 'OPTION_REG.7 = 0 ' Internal pull-ups = on 'debug defines DEFINE DEBUG_MODE 0 ' Debug sending INVERTED serial data DEFINE DEBUG_REG GPIO ' Debug Port = GPIO DEFINE DEBUG_BIT 2 ' Debug.bit = GPIO.2 DEFINE DEBUG_BAUD 2400 ' Default baud rate = 2400 'end of debug defines 'Variables begin here RC5CODE VAR WORD ' Holds 12-bit RC5 code CYCLEX VAR BYTE ' used to hold the loop count for bit collection IRPIN VAR GPIO.1 ' GPIO.1 input pin reading data 'end of variables main: 'check for a valid header IF IRPIN = 1 THEN main 'Only start when PULSE is a LOW PAUSEUS 100 'Pause for 0.1mS IF IRPIN = 1 THEN main 'Could be junk so try again PAUSEUS 1350 'Pause for 1.350mS 'header check is good so now continue rc5code.0[13] = IRPIN 'Setup array to read each pulse into Bits FOR CYCLEX = 12 to 0 STEP - 1 'read 13 Pulses/bits in reverse order RC5CODE.0[cyclex] = IRPIN 'build the array PAUSEUS 1800 ' PAUSE 1.8mS then start reading next BIT/pulse NEXT cyclex 'go back and do it again IF RC5CODE.LOWBYTE = $FF THEN main 'Check to see if it's junk we received $FF aka 255 'OK now dow some AND-ing/bit-masking to get the codes right RC5CODE = ~RC5CODE & $003F ' Mask upper 10-bits to return 6-bit data ' in lower 6-bits of word result 'Send it to the MAX232 or serial port for display debug "Key Pressed = ",DEC rc5code ' send the code to serial port/MAX @ 2400bps TRUE 'for LCDOUT ALTER THE NEXT LINE 'LCDOUT "kepress is", DEC RC5CODE RC5CODE=0 ' Clear the variable for next keypress PAUSE 500 ' a short DEBOUNCE -If you leave this out then expect duplicates -- ! GOTO main 'start again from main end
Will post the circuit later on ..really simple but it works.
I am busy playing around with Les Johnson's code (what I could make out in the article) and will post that later on too.
Dave .. I will keep bashing away and post progress.
Keep well
Kind regards
Dennis
Hi all
The code in earlier posts works but produces some strange results and I'm sure it has to do with timing and the bit tests I'm doing.
I have been reading up on the RC5 code at this sitehttp://www.sbprojects.com/knowledge/ir/rc5.htm
I'm still not just not getting it right and would really appreciate some guidance from some kind soul here.
Here's how I understand it so far (I have put comments in the code too):
1.RC5 consists of 1.778ms pulses representing a bit
2.Each bit consists of two halves and either half of the time may be filled with a 36Khz burst.
If the burst occurs in the first half then a ZERO is represented.
If the burst occurs in the second half then a ONE is represented.
3.There are TWO(2) Start bits
4.The third bit is a "toggle" bit - which tells us the button is pressed.
Apparently it is up to the receiving device to 'sense' that the button is down/pressed.
So in order to get the received pulses checked and decoded the first step is decide on the method of capture right ?
I have chose to use a 12F629 and TSOP1736 IR receiver is on GPIO.2 for receiving the IR input (IRpin in the code)
The methods I have been seeing in the forums and on the web seem to use either PULSIN or a PIN state test.
I have chose the PIN state test because I still don't understand the PULSIN command (you can only read the manual and examples all over so many times) - the thing I don't get is the timing/numbers. the rising ,falling and duty cycle do make sense.
So I chose to use the state of the PIN method.
The pseudo code is as follows:
1.Monitor a PIN (GPIO.2) and wait for it to go LOW - this means the start of a pulse/bit.
2.We know that if the first half of the pulse/bit is LOW (889uS) then the next half should be HIGH (assuming this is indeed a start bit)
3.So a quick check would help --- the idea is to delay/wait for a duration of under 889uS and then check to see if the pulse/bit is still low)
If it is high then start over and keep waiting and checking for a pulse.
If it is low then wait for a short time and check the next half time already spent +889uS/2
4.if the next half is HIGH then we have the first start bit and it's time to check the second incoming start bit.
So back to square one and do it again for the second start bit.
5.After I have the 2 start bits , it's time to start collecting the rest of the bits into a word variable.
6.Once we have collected the bits, they need to be separated/masked/divided into the a DEVICE/ADDRESS and COMMAND portion
BITS 4 to 8 =ADDRESS code MSB first
BITS 9 to 14 = COMMAND code MSB first.
Well that's the order of things as I have it figured out so far.
Please find my code below (It's not complete yet as I first need to understand the filtering correctly and then will begin (and finally post) the bit grabbing section.
I have it running but the problem is my initial bit tests don't seem to work because when I press a button on any remote (RC5 and others) it activates a message on my screen.I only want to filter RC5 code.
What am I doing wrong ? :-(
Should I rather attempt to use PULSIN (If so, what figures should I be using)
Kind regards
Dennis
Code:' Philips RC5 IR decoder for 12F629 @ 4MHZ 'set for samsung TV on universal rae-1000 (or similar??) remote - TV1 -code 189 most buttons work define OSC 4 '4MHz DEFINE OSCCAL_1K 1 ' Set OSCCAL for 1k -HELPS tuning the crystal for more accurate timing CMCON = 7 'TRISIO = %76543210 ' port GPIO 0=output and 1=input TRISIO = %00000100 ' GPIO.2 is an input all the rest are outputs 'OPTION_REG.7 = 0 ' Internal pull-ups = on 'debug defines DEFINE DEBUG_MODE 0 ' Debug sending INVERTED serial data DEFINE DEBUG_REG GPIO ' Debug Port = GPIO DEFINE DEBUG_BIT 0 ' Debug.bit = GPIO.0 DEFINE DEBUG_BAUD 2400 ' Default baud rate = 2400 'end of debug defines RC5 VAR WORD ' Holds 12-bit RC5 code Loopy VAR BYTE ' Loop variable IRpin VAR GPIO.2 ' RB.0 input pin reading data Startbit2 var bit 'holds first synch bits Startbit1 var bit 'holds synch bits Home: IF IRpin = 1 THEN Home ' Wait for low going pulse ' ' 'if not then continue to read the pulse ' 'RC5 has equal length pulses each ot 1.788ms 'first two bits are START BITS for RC5 one bit = 889uS X2half bits = 17880ms/bit '0 = burst in first half of bit time,1=burst in 'second half of bit time ' half half half half half half half half '________|||||||________||||||||_______|||||||________||||||| ' 889 889 889 889 'STARTbit1 Startbit2 Togglebit First data MSB '--------------|---------------|-------------|---------------| ...12 others ' Bits 4to8 Addr Bits 8to12 Command ' | '.......testfor|........testfor| ' HIGH HIGH ' 'send a message to serial port debug "got something YAY ",DEC Y,13,10 ' PAUSEUS 200 ' Short delay to waste some time and test if pulse is still low ' 'Some conditions IF IRpin = 1 and startbit1=0 THEN Home ' Must be noise so test again IF IRpin = 1 and startbit1=1 THEN getbits 'is startbit1=1 PAUSEUS 1350 ' Pause to read 2nd half of 1st bit period is it 1 or 0 ? ' ' 'send message to serial port Debug "looks like RC5 S1 bit..checking next bit" Startbit1=1 'set startbit to flag we got first start bit if IRpin = 1 and Startbit1 =0 then Startbit1 =1 ' test conditions I may use 'if IRpin=1 and Startbit1=1 and Startbit2=0 then Startbit2=1 'if startbit1=1 and startbit2=1 then goto getbits ' ' While IRpin=1:Wend ' go home when pin goes low again goto home
Last edited by Dennis; - 28th February 2010 at 14:01.
Try http://www.sbprojects.com/knowledge/ir/index.php and follow the instructions on "How to Navigate", there is a dropdown on the menu bar that lists all the different protocols.
Keith
www.diyha.co.uk
www.kat5.tv
Bookmarks