Eblock IR sensor confusion

I finally have a question of my own. More specifically, I’m hoping someone can explain IR sensor behaviour that baffles me.

My set up is as basic as can be: Spider board, DP power module, button module (in socket 4), eblock expansion module (in socket 11). IRLED and IR receiver eblocks are plugged into pins 3 and 4, respectively.

The code that runs my program is:

    public partial class Program
    {
        GT.Interfaces.DigitalOutput irLED;
        GT.Interfaces.InterruptInput irSensor;

        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");

            irLED = eBlockExpansion.SetupDigitalOutput( GT.Socket.Pin.Three, false );

            SetupInterruptIR();

            button.ButtonPressed += new Button.ButtonEventHandler( button_ButtonPressed );
            button.ButtonReleased += new Button.ButtonEventHandler( button_ButtonReleased );
        }

        void irSensor_Interrupt( GT.Interfaces.InterruptInput sender, bool value )
        {
            Debug.Print( "value: " + value + " sender: " + sender.Read() + " irSensor: " + irSensor.Read() );
        }

        void button_ButtonPressed( Button sender, Button.ButtonState state )
        {
            Debug.Print( "Button Down. Time: " + System.DateTime.Now );
            irLED.Write( true );
        }

        void button_ButtonReleased( Button sender, Button.ButtonState state )
        {
            irLED.Write( false );
            Debug.Print( "Button Up. Time: " + System.DateTime.Now );
        }

        void SetupInterruptIR()
        {
            irSensor = eBlockExpansion.SetupInterruptInput( GT.Socket.Pin.Four, GT.Interfaces.GlitchFilterMode.On, GT.Interfaces.ResistorMode.PullDown, GT.Interfaces.InterruptMode.RisingAndFallingEdge );
            irSensor.Interrupt += new GT.Interfaces.InterruptInput.InterruptEventHandler( irSensor_Interrupt );
        }

    }

While holding the IR LED about an inch over and directly facing the IR sensor, after pressing the button a few times I get the following debug output:

[quote]Using mainboard GHIElectronics-FEZSpider version 1.0
Program Started
Button Down. Time: 01/01/2009 00:08:45
value: False sender: True irSensor: True
value: True sender: True irSensor: True
Button Up. Time: 01/01/2009 00:08:48
value: False sender: True irSensor: True
Button Down. Time: 01/01/2009 00:08:51
value: False sender: False irSensor: False
value: False sender: True irSensor: True
value: False sender: True irSensor: False
value: False sender: True irSensor: True
value: False sender: True irSensor: True
Button Up. Time: 01/01/2009 00:08:54
value: False sender: True irSensor: True
Button Down. Time: 01/01/2009 00:08:57
value: False sender: False irSensor: False
value: True sender: True irSensor: True
value: False sender: True irSensor: True
Button Up. Time: 01/01/2009 00:09:01
value: False sender: True irSensor: True
Button Down. Time: 01/01/2009 00:09:04
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: False
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: True
Button Up. Time: 01/01/2009 00:09:12
value: False sender: True irSensor: True
Button Down. Time: 01/01/2009 00:09:14
value: False sender: False irSensor: False
value: True sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: True
value: False sender: True irSensor: False
value: False sender: True irSensor: True
value: True sender: True irSensor: True
Button Up. Time: 01/01/2009 00:09:16
value: False sender: True irSensor: True
The program ‘[12] Micro Framework application: Managed’ has exited with code 0 (0x0).
[/quote]

What may not be obvious from this sample output is its semi-randomness. For the most part, the mass of interrupts happens when the button is pressed and stops when the button is released. Sometimes though, I’ll get an odd random interrupt when nothing is supposed to be going on. Sometimes, when the button is pressed nothing happens, but I still get an interrupt when I release it. Sometimes I get a couple of interrupts when I release. At times, I’ll get 5-10 interrupts on button down, then nothing, no matter how long I hold it down.

What’s more confusing to me, are the values I get. I would expect

Debug.Print( "value: " + value + " sender: " + sender.Read() + " irSensor: " + irSensor.Read() );

to return three identical values every single time. But you can see quite a few permutations of the values even from the short sample run I posted.

So, can anybody explain to me, in simple words, why is my h/w and s/w setup producing this output? Why the deluge of interrupts, and why those values during the interrupts?

–Edit–
Oh, and I should mention that in:

 irSensor = eBlockExpansion.SetupInterruptInput( GT.Socket.Pin.Four, GT.Interfaces.GlitchFilterMode.On, GT.Interfaces.ResistorMode.PullDown, GT.Interfaces.InterruptMode.RisingAndFallingEdge );

I tried all sorts of permutations with the parameters. Nothing seemed to really influence my outputs in a radical fashion (except InterruptMode, which just confuses me even more).

And I should mention that I tried plugging things into different sockets too. Nothing changed results appreciably.

I think the button driver uses glitch filter and this will not work fro you. See this
http://code.tinyclr.com/project/287/tv-remote-rc5-for-driving-a-fez--panda/
and
http://code.tinyclr.com/project/465/sony-ir-remote-driver/

I understand the glitch filter is only used for buttons. So it’s inconsequential in this case.

I’m still confused about the receiver. If I pump steady IR signal into it, should I not be getting a steady signal in the code? The example code posted (official GHI) kind of relies on that.

            void IRM_OnInterrupt(uint port, uint state, DateTime time)
            {
                bit_time[bit_count]= time.Ticks-last_tick;
                last_tick = time.Ticks;

You measure the length time since the signal last changed. That means, for as long as IR signal is on, you should not be getting the next edge/interrupt (and vice versa for off). All the gooblygook afterwards is nothing else but interpreting the signal meaning and has little to do with the actual sensor usage.

How would I set up my code to just get an on/off notification from the sensor, based on input being a steady on/off IR signal? Imagine a “trip wire” sensor. One state for when my sensor can see the source, and another state when something gets into the path of the signal.

Or even more meaningfully, if I wanted to set up an alarm. Light up a green LED when I have an IR connection, and light up red when there is a break in my path. Should I not be able to just read the state of the sensor and set my LED values appropriately?

        void irSensor_Interrupt( GT.Interfaces.InterruptInput sender, bool value )
        {
            redLED.Write( !value );
            greenLED.Write( value );
        }

Also, how can the value and sender.Read() from the above code differ? I would think they represent the same value.

I think you need to understand IR signals and interrupts a little more.

Interrupts are used any time you want to record when a signal changes from 0 to 1 or 1 to 0, and a glitch filter “smoothes” out some of the noise on that. It tries to reduce the impact of noise on the line. This is NOT just used for buttons, but on any interrupt handler.

IR is usually a series of bits sent as an on/off signal (think like your TV’s remote control). I don’t think the module you have is meant to be used in a “permanently on” mode for a “broken beam” type scenario, and I’ve never heard of anyone using it in that way. You may find that you’ll burn out the IR LED over time (where time is somewhat variable). The usual use for these modules is as I say, sending, recieving, and interpreting codes sent by remote controls.

Thanks for replying Brett.

I get everything you’re saying. But I still don’t understand the behaviour of the sensor, based on the code.

Without getting hung up on the performance of the LED, why am I not getting a steady response from the receiver? If I turn on the LED, and then 3 seconds later I turn it off, why am I not getting a single “true” interrupt from the sensor, followed by a single “false” interrupt 3 seconds later?

So you have an IR receiver on one end and IR LED on other? How do you “turn the LED on”?

possibly because IR is “heat” and thats not binary? I was going to suggest you releat the tests in a contolled atmosphere at known atmospheric pressure at some point above absolute zero, but then I thought just try putting the whole thing across the two (sealed) ends of an enclosed housing, otherwise known as a toilet roll.

Gus is this the interrupt.read() issue?

(FYI the button pressed events for press and release are responsible for doing IRled.Write(true/false) actions)

@ Gus

As per my original code post:

        GT.Interfaces.DigitalOutput irLED;
...
            irLED = eBlockExpansion.SetupDigitalOutput( GT.Socket.Pin.Three, false );
...
            irLED.Write( true );
...
            irLED.Write( false );

In the same code, the IR LED is turned on and off in corresponding button pressed and released event handlers, respectively. But I tried toggling it on with button press (to eliminate button pressed electronics from the circuit), as well as just doing it on a timer. Everything has the same results.

@ Brett

No disagreement on the heat issue. That may explain a rare and occasional spontaneous interrupt. But doesn’t explain how people manage to detect digital signals from their TV remotes with significantly high percentage of success as to not complain about it. I’m thinking that either I have a bum sensor/LED, or I’m doing something wrong. I still think it’s something I did that’s wrong, but am not so sure any more.

Could someone with irLED and irReceiver eblocks please confirm my results, with the above code?

Maybe you need to upgrade your emitter … how about this one: ;D

@ MoonDragon

That’s not how IR is used. You don’t just turn on an IR LED and get an output from the reciever. IR uses a carrier frequency (typically in the 38000hz range) which is then turned on and off in the pattern of the IR “bits”. It is the transition from on to off (or vice-versa), at 38khz, NOT just an IR LED that’s on, that the IR detector detects.

See here for a great tutorial on the topic:

http://www.ladyada.net/learn/sensors/ir.html

In the first section, it states:

(emphasis mine)

Check out the section of this page entitled “Sending Signal to Control a Tv”:

It shows the proper way to output a signal from an IR LED.

Hope that helps.

@ devhammer

Thank you! That’s exactly what I needed: a detailed explanation of how the detector works.

Glad I could help. :slight_smile:

And when you outgrow the range of the IR LED eblock (which you likely will quickly), as @ mhectorgato noted, I have an IR LED Array module that can provide a bit more oomph. One important note…like the IR LED eblock, my module relies on the OutputCompare feature that is baked into the FEZ Spider mainboard…but OutputCompare isn’t (at this time, anyway) supported on other Gadgeteer mainboards.

Yeah. It may be a bit longer until I have advanced needs like yourself. But I am aware of your efforts. Been lurking on the forum for a while and I’ve followed your development of the IR module with great interest.