Diagnosing IR interference

Relayer

New Member
It's tough to search for the phrase "IR" on this forum, so please bear with me while I probably ask a previously asked question.

What methods are there to eliminate issues with interference from surrounding light, through optical filters or code?

I have a project that uses a TV remote (programmed for Sony codes) and a 38KHz IR decoder (a 3-pin version from the local Radio Shack). This decoder is already optically filtered. I'm using a 28x1 PICAXE

It works beautifully and responds well up to 20 feet (in the right lighting). However, when I turn on the fluorescent lights, my code appears to respond to the lighting and then locks up the app. Same thing happens if I press a button on the remote that I don't specifically check for in code. Here is my detection routine, activated via an interrupt on the IR in port.

Code:
interrupt:
	
	irin [100, mainloop],0,IR_IN

	if IR_IN <> LAST_IR and IR_IN <> 255 then

		LAST_IR = IR_IN

		IR_IN = IR_IN + 1
	
		if IR_IN = 17 then
			CURCOUNT = CURCOUNT + 1 MAX 999
			POSITION = 0
		elseif IR_IN = 18 then
			CURCOUNT = CURCOUNT - 1 MIN 1
			POSITION = 0
		elseif IR_IN > 0 and IR_IN < 11 then
		
				IR_IN = IR_IN DIG 0
						
				POSITION = POSITION + 1
	
				select case POSITION
				case 1
					CURCOUNT = IR_IN
					
				case 2, 3
					CURCOUNT = CURCOUNT * 10 + IR_IN
					
				endselect

				SET_TIMEOUT = 800
				
		else
			LAST_IR = 99
								
		endif
		
		TIMEOUT = 120
					
	endif

	IR_IN = 255
		
	setint %00000000,%00000001
		
	return
This code does several things. It waits for CH-UP/CH-DN and individual number presses. I add 1 to the captured value for my convenience because I'm using the captured value for math operations. Remember, with the IRIN command, button '1' comes in as 0, '2' as 1, etc.

I also have the POSITION variable peppered in the code because I'm building a value, up to three digits, by shifting in sequential number presses. The POSITION variable tracks the digit sequence for me.

I use IR_IN as a variable name to capture the IRIN result. I set IR_IN to '255' as a default, for my own use because I don't know what the value returned by the IRIN command is if it times out. My guess is, the IR_IN variable remains unchanged in that case. So, I use '255' as my timeout value. The first IF block should not execute if the IR_IN variable = '255'.

That being said, something must happen. After all, the interrupt gets generated when I switch on the room lights and the code executes. How do I detect this as garbage data? Is it possible a bug in the IRIN function?
 

manuka

Senior Member
I've not checked your code (brain still on first coffee...), but fluoro. lighting of course is full of all sorts of rubbish,although most is usually at the UV end. Hence initially consider further simple IR filters- darkened 35mm camera film (if you can now find any!) used to be suitable. Also house the sensor deeply in a darkened tube so it responds only to your direct IR?
 

Technical

Technical Support
Staff member
irin [100, mainloop],0,IR_IN


if the ir times out, you do a 'goto mainloop' out of the interrupt - without resetting setint or using a return - both bad practice!

Make your timeout jump to the the setint line at the end of the procedure instead, so that you execute both a setint and return upon a timeout.
 

BeanieBots

Moderator
As soon as there is ANY trigger from your IR sensor, you will enter the interrupt routine and enter the "IRIN" command.
You have set it up to have a timeout which jumps to "mainloop".
I see no such label within your interrupt routine, hence, I assume you jump out of the interrupt without doing a return. This will eventually crash the PICAXE.
You need to put it in the interrupt routine so that you can correctly "return". It is from that label (the timeout) that you handle "garbage". That is, your routine has been triggered, but not by a valid IR signal. Hence the timeout.
You don't actually need to do anything (unless you want to). Simply "return" and the false trigger will be ignored.

As stated by Manuka, fluorescent lights put out loads of junk but not much IR. You may well be suffering from electrical pickup problems.
 

Relayer

New Member
BeanieBots and Technical,

That's what I was doing wrong and couldn't see it for myself. I guess being a newbie to PICAXE got me in trouble with my code. :rolleyes:

I understand the unfinished interrupt and how it can crash the PICAXE (like a stack overload).

As a newbie to the PICAXE API, I used MAINLOOP as my main loop as opposed to MAIN, like everyone else uses.

I'll have to make the change tonight when I get home, but I'm confident that'll make the application much more stable.

Manuka,

I have plenty of old 35MM negatives around that I can cut a small piece out of an exposed leader to get a darkened filter. Never really thought of that idea before, but I can see how it'll help. I can't put the sensor in a tube as it needs a fair field of view to respond to a remote within a large meeting room.
 

inglewoodpete

Senior Member
Do you have a CRO? A CRO attached to the output or the IR sensor will indicate how much noise is being detected in different conditions.

If you don't have a CRO, you can make a simple soundcard-based dual beam oscilloscope on your PC. I have used a soundcard-based CRO to debug IR signals. Software is freely available from a number of sources on the internet: search for "soundcard oscilloscope". For showing TTL logic voltages (0 to 5v), use a voltage divider to limit the input level to the sound card.

Soundcards tend to be limited to about 1v RMS maximum. A suitable attenuator is 4.7k to the probe and 1k between the line-in live and 0v.
 

Relayer

New Member
Here's where I'm at now.

I fixed my code to allow the interrupt to exit properly. Afterwords, my output (three LED displays, multiplexed) start acting strangely. The individual digits would blink and/or have their multiplexing operation interrupted. Nothing appeared to lock up the PICAXE, so I figure that part is working well now. No more lockups.

The strange acting display is a setback that I understand, it's based on interference triggering the interrupt. The strange behavior still happened very often, at least until I discovered that it would stop when I put my hands on the table. Lifting my hands restarted the issue. Turns out that I was blocking the IR window on my laptop when I put my hands down. There's one source of interference abated.

The fluorescent lights in my office (where I'm testing the circuit) don't interfere either, even when turning them on/off. That's a good thing too.

However, when I move the device I'm making into a larger room with more fluorescent lights, it gets all funny again. Turning off some of the lights fixed the issue. I guess I'll just need to use a little more filtering to remedy that, or find a more strategic location to mount the device.
 

BeanieBots

Moderator
Well, sounds like you've made very good progress.
As mentioned earlier, there is very little IR in fluorescent lights. Hence, a little bit of IR filtering on your sensor will probably solve that issue.
It might also be worth playing with the timeout value on the IRIN command to reduce the display flicker to some extent.
 
Top