IR Remote for the Boe-Bot question
I'm having problems with the IR detector detecting something without pressing any remote buttons. I've tried turning off all lights, I've even took it outdoors and it still detects something. Does anyone know what could be the problem? I'm useing the original detectors that come with the Boe-Bot. The remote is set for a Sony tv. I noticed that in the program that tests the signal from the remote that a 1 signal is what it shows in the Debug terminal when it does it.
Comments
Please post the code you are using. I'll test it on my Boe-Bot with known-good IR detectors.
Regards, Andy
Below is a modified Get_Ir_Remote_Code subroutine.· The comment and two·statements I added to fix the problem are red.· I think they'll make the subroutine immune to glitches without causing any other Boe-Bot misbehaviors.· Please give it a try, and let me know how it goes.
Regards, Andy
'
[noparse][[/noparse] Subroutine - Get_Ir_Remote_Code ]
·
' SONY TV IR remote subroutine loads the remote code into the
' remoteCode variable.
·
Get_Ir_Remote_Code:
·
· remoteCode = 0···························· ' Clear all bits in remoteCode.
·
· DO········································ ' Wait for rest between messages.
··· RCTIME IrDet, 1, irPulse
· LOOP UNTIL irPulse > 1000
·
· PULSIN IrDet, 0, irPulse·············· ····' Measure pulse.
· IF irPulse > 500 THEN remoteCode.BIT0 = 1· ' Set (or leave clear) bit-0.
· RCTIME IrDet, 0, irPulse·················· ' Measure next pulse.
· IF irPulse > 300 THEN remoteCode.BIT1 = 1· ' Set (or leave clear) bit-1.
· RCTIME IrDet, 0, irPulse·················· ' etc.
· IF irPulse > 300 THEN remoteCode.BIT2 = 1
· RCTIME IrDet, 0, irPulse
· IF irPulse > 300 THEN remoteCode.BIT3 = 1
· RCTIME IrDet, 0, irPulse
· IF irPulse > 300 THEN remoteCode.BIT4 = 1
· RCTIME IrDet, 0, irPulse
· IF irPulse > 300 THEN remoteCode.BIT5 = 1
· RCTIME IrDet, 0, irPulse
· IF irPulse > 300 THEN remoteCode.BIT6 = 1
·
· ' Filter IR receiver output glitches by making sure that bit7
· ' is 1.
· RCTIME IrDet, 0, irPulse·················· '·Get BIT7 pulse
· IF irPulse < 300 THEN Get_Ir_Remote_Code·· ' If it's not 1, try again
·
· ' Adjust remoteCode so that keypad keys correspond to the value
· ' it stores.
·
· IF (remoteCode < 10) THEN remoteCode = remoteCode + 1
· IF (remoteCode = 10) THEN remoteCode = 0
·
· RETURN
Post Edited (Andy Lindsay (Parallax)) : 1/31/2006 9:36:26 PM GMT
Dave45 said...
could you explain to me exactly what this did, and why it was able to fix the problem
Before reading on, make sure to review Figure 1-4 on page 6 of IR Remote for the Boe-Bot.· Also read section entitled Converting the IR Message Pulse Durations to Decimal Values section (pages 52-57).·
The·Get_Ir_Remote_Code subroutine is not immune to glitches in the IR receiver's output.· I developed the code with the Panasonic PNA4602 receiver.· That’s the one that still comes with the IR Remote with the Boe-Bot kit, and it never glitches.· Later, we changed the Boe-Bot's IR receivers to a silver one that's pretty much a generic version of the PNA4602.· It works much better for the Boe-Bot·because it's a more sensitive and at the same time more resistant to the interference some fluorescent emit.· The one drawback to these receivers is that they·send occasional·glitches.· By glitches, I mean an occasional 100 us low signal.··Depending on the environment, it might be once every ten minutes, or·once every few seconds.·
In terms of autonomous navigation, this glitch behavior is completely invisible to the Boe-Bot.· The statistical likelihood of a glitch overlapping with a sensor measurement is truly minute.· Even if one does happen to coincide with the instant the BASIC Stamp captures the IR receiver’s output, the result·gets swamped by 40 other measurements each second, which makes it impossible to discern while watching the Boe-Bot navigate.
On the other hand, the Get_Ir_Remote_Code subroutine passes·every glitch straight through, and is interpreted by the program as a 1!· Here's why.· When the IR receiver isn't getting any infrared (on/off at 38 kHz), it's output remains high.· But, when you point your remote at the receiver and press a button, the receiver’s output goes low for 2.4 ms.· Then, it goes high again for 0.6 ms, and is followed by 12 low pulses (either 1.2 or 0.6 ms for binary 1 or 0) each separated by a 0.6 ms high signal.· For a timing diagram, see Figure 1-4 in Ir Remote for the Boe-Bot.
This DO...LOOP is the gate keeper that waits for that low signal.··The RCTIME command measures the time from whenever the command started until the low signal from the start pulse occurs.· It keeps discarding and repeating measurements until it finds one that's greater than 2 ms, which means it should be the 20 to 30 ms high time between message packets.·
· DO········································ ' Wait for rest between messages.
··· RCTIME IrDet, 1, irPulse
· LOOP UNTIL irPulse > 1000
·
Each RCTIME measurement can last up to 131 ms, then it takes the loop, maybe 1/2 to 1 ms to repeat.· Since the DO...LOOP is filtering for a high time greater than 2 ms followed by a low, chances are 129 out of 132 that this loop will catch a glitch and allow the program to continue and try to interpret the message.
·
After the program gets past the DO...LOOP because of a star pulse, a·PULSIN·command waits for the start·2.4 ms start pulse to end, and then measures the duration of the·bit-0 low pulse.··Remember, a 1 pulse is·1.2 ms, and·a 0 pulse is 0.6 ms.··Since the·PULSIN command·returns values in 2 us units, that's either 600 for·a 1 pulse or 300 for a 0 pulse.· ·
·
· PULSIN IrDet, 0, irPulse·················· ' Measure pulse.
· IF irPulse > 500 THEN remoteCode.BIT0 = 1· ' Set (or leave clear) bit-0.
·
If a·glitch occurred, it's followed by a sustained high signal.· The PULSIN command will·wait for 0.131 seconds, then timeout, and return a 0.··Since 0 is not greater than 500,·remoteCode.BIT0·keeps the 0 that was stored in it at the beginning of the subroutine (with the command remoteCode = 0, which sets all eight bits in the byte variable to zero).···
·
When the PULSIN command’s State argument is set to 0, it waits for a low signal and then measures its duration.· That means that the PULSIN command waits until it detects the transition from high to low, and then measures the time it takes for the signal to go high again.· In contrast, the RCTIME command with its state argument set to 0 measures the time it takes for a high signal to transition to low.·
·
Since the BASIC Stamp doesn't finish processing the IF irPulse > 500 THEN... statement until part way into the next (bit-1) low pulse, the PULSIN command would miss the pulse entirely since it's looking for a high to low transition before it starts measuring time.· That's why an RCTIME command is used instead, because it can measure what's left of the low pulse.· What's left in the bit-1 low pulse will either be in the neighborhood of 0.9 or 0.3 ms for a binary-1 or 0 respectively.· RCTIME also measures 2 us time increments, which results in a measurement of 450 for a binary-1 or 150 for a binary-0.· The IF...THEN statement that follows the RCTIME command·stores a 1 in remoteCode.bit1 it measures a time greater than 300, or leaves it 0 if it is less than 300.· This process is repeated for the bit-2, bit-3,...bit-6 low signals.·
·
· RCTIME IrDet, 0, irPulse·················· ' Measure next pulse.
· IF irPulse > 300 THEN remoteCode.BIT1 = 1· ' Set (or leave clear) bit-1.
· RCTIME IrDet, 0, irPulse·················· ' etc.
· IF irPulse > 300 THEN remoteCode.BIT2 = 1
· RCTIME IrDet, 0, irPulse
· IF irPulse > 300 THEN remoteCode.BIT3 = 1
···· .
···· .
···· .
·
If these commands are being executed because a glitch got past the DO...LOOP at the beginning of the subroutine, the signal is still high because there are no low pulses being caused by an IR message from the remote.· Each RCTIME command will time-out after 0.131 seconds, and since it never saw a transition from high to low, it returns a 0.· Each IF...THEN statement that follows an RCTIME command finds the value 0 stored in irPulse, which is less than 300, and allows the value of each successive remoteCode bit to remain 0.
·
The remote code is 1 less than the button it represents until you get to 10, which is actually the 0 button.··The remote code 0 actually indicates that the 1 button has been pressed, and this code near the end of the subroutine makes the correction:·
·
· IF (remoteCode < 10) THEN remoteCode = remoteCode + 1
· IF (remoteCode = 10) THEN remoteCode = 0
·
In the event of a glitch, all the low pulse time measurements returned zeros, and the remoteCode variable stores %00000000.· So, the Get_Ir_Remote_Code subroutine interprets it as a 1.· This explains why your Debug Terminal told you the program thought it was receiving a 1 each time the IR receiver glitched.
·
It seemed like there should be a lot of ways to fix this problem, but it also seemed like everything I tried turned out to be a dead-end.··The code changes either disabled the subroutine or made the Boe-Bot twitchy when I tried to drive it with the 1 key.··Then, today, I remembered that the subroutine discards bit-7 to bit-11.· These bits are used to select between various SONY devices that use the same protocol (TV, VCR, CD player, etc).· For the Boe-Bot, it saved both time and code space to forget about these bits.··
·
For a SONY TV, bit-7 is always 1, while bits 8 to 11 are all zero.· That means that the eighth bit pulse (bit-7) has to be a low signal that lasts about 1.2 ms.· Well, gee-whiz, if a glitch occurred, the signal will stay high, and there won't be a low pulse for bit-7.··By adding one more RCTIME command, that bit-7 data pulse can be captured.· If it's zero, it means there was a glitch, and the subroutine should restart at the beginning.· In this case, the·statement IF irPulse < 300 THEN Get_Ir_Remote_Code sends the program back to the start of the subroutine to wait for a message that's not initiated by a glitch.· Otherwise, the IF...THEN·verifies that the 1.2 ms 1 pulse did indeed occur (or at least one greater than 300 -> 0.6 ms), and allows the·program to continue to the RETURN command, with a correct value stored in the remoeteCode variable.·
·
· RCTIME IrDet, 0, irPulse·················· '·Get BIT7 pulse
· IF irPulse < 300 THEN Get_Ir_Remote_Code·· ' If it's not 1, try again
While writing·all this, it occurred to me that it might be possible to modify the first two IF...THEN statements to catch the glitch earlier.· I'm not sure if there is enough·processing time for a BASIC Stamp 2, but we'll see...· In the meantime, please do let me know if you notice any undesirable side effects in programs that use the modified subroutine.
Post Edited (Andy Lindsay (Parallax)) : 2/1/2006 6:38:44 AM GMT
·
'
[noparse][[/noparse] Subroutine - Get_Ir_Remote_Code ]
·
' SONY TV IR remote subroutine loads the remote code into the
' remoteCode variable.
·
Get_Ir_Remote_Code:
·
· remoteCode = 0···························· ' Clear all bits in remoteCode.
·
· ' Wait for resting state between messages to end.
·
· DO
··· RCTIME IrDet, 1, irPulse
· LOOP UNTIL irPulse > 1000
·
· ' Measure start pulse.· If out of range, then retry at Get_Ir_Remote_Code.
·
· RCTIME 9, 0, irPulse
· IF irPulse > 1125 OR irPulse < 675 THEN GOTO Get_Ir_Remote_Code
·
· ' Get data bit pulses.
·
· RCTIME IrDet, 0, irPulse·················· ' Measure pulse
· IF irPulse > 300 THEN remoteCode.BIT0 = 1· ' Set (or leave clear) bit-0
· RCTIME IrDet, 0, irPulse·················· ' Measure next pulse
· IF irPulse > 300 THEN remoteCode.BIT1 = 1· ' Set (or leave clear) bit-1
· RCTIME IrDet, 0, irPulse·················· ' etc
· IF irPulse > 300 THEN remoteCode.BIT2 = 1
· RCTIME IrDet, 0, irPulse
· IF irPulse > 300 THEN remoteCode.BIT3 = 1
· RCTIME IrDet, 0, irPulse
· IF irPulse > 300 THEN remoteCode.BIT4 = 1
· RCTIME IrDet, 0, irPulse
· IF irPulse > 300 THEN remoteCode.BIT5 = 1
· RCTIME IrDet, 0, irPulse
· IF irPulse > 300 THEN remoteCode.BIT6 = 1
·
· ' Adjust remoteCode so that keypad keys correspond to the value
· ' it stores.
·
· IF (remoteCode < 10) THEN remoteCode = remoteCode + 1
· IF (remoteCode = 10) THEN remoteCode = 0
·
· RETURN
Post Edited (Andy Lindsay (Parallax)) : 2/10/2006 5:41:47 AM GMT