Netduino InterruptPort Inconsistency

306 views Asked by At

Im writing a Netduino 3 program that will control turn lights and other relays for hayrides. My program was written before I got the device, so Im not sure how well it will work, but Im already having a problem with one of the buttons (hazardButton). When applying 3.3v it doesn't cause the interrupt to trigger. Applying 5v does the same, however when applying GND it triggers the interrupt, but when re-applying GND it doesn't turn off the interrupt.

Here's my code:

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

namespace Tractor_Mate
{
    public class Program
    {
        static InterruptPort hazardButton = new InterruptPort(Pins.GPIO_PIN_D0, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);

        static OutputPort hazardLights = new OutputPort(Pins.ONBOARD_LED, false);

        static bool hazardsActive = false;

        public static void Main()
        {
            Debug.Print("Initializing Inputs... ");

            hazardButton.OnInterrupt += new NativeEventHandler(hazardButton_OnInterrupt);

            Thread.Sleep(Timeout.Infinite);
        }

        static void hazardButton_OnInterrupt(uint data1, uint data2, DateTime time)
        {
            while (data2 == 0)
            {
                hazardLights.Write(true);
                Thread.Sleep(500);
                hazardLights.Write(false);
                Thread.Sleep(500);

                hazardsActive = true;
            }
            hazardsActive = false;
        }
    }
}

Im getting the problem with the Hazard Lights and haven't tried any of the others yet. Im wiring the buttons up so that when the pin goes HIGH it will trigger, and then when LOW it turns it off.

1

There are 1 answers

2
Ron Beyer On
public class Program
{
    static InterruptPort hazardButton = new InterruptPort(Pins.GPIO_PIN_D0, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);

    static OutputPort hazardLights = new OutputPort(Pins.ONBOARD_LED, false);

    static volatile bool hazardsActive = false;

    public static void Main()
    {
        Debug.Print("Initializing Inputs... ");

        hazardButton.OnInterrupt += new NativeEventHandler(hazardButton_OnInterrupt);
        bool lightOn = true;

        while (true)
        {
            if (!hazardsActive)
            {
                hazardLights.Write(false);
            }
            else
            {
                hazardLights.Write(lightOn);
                lightOn = !lightOn;
            }
            Thread.Sleep(500);
        }
    }

    static void hazardButton_OnInterrupt(uint data1, uint data2, DateTime time)
    {
        hazardsActive = !hazardsActive;
    }
}

I'm unable to test this since I don't have the Netduino SDK installed (I have a NetDuino, but its been a while since I played with it). The principle is pretty easy:

The interrupt only toggles the hazards being on or off. The variable is marked volatile because it can be set from multiple threads and it needs to be read from the register not a thread cache, so volatile tells the compiler not to optimize it.

The main method has an infinite loop that examines if the hazards are on or off. When the hazards are off (first part of the if), it writes false to the output pin (presumably turning the lights off, unless the pin is inverted).

When the hazards are on (else part), it writes a value to the pin then inverts the value so the next time it turns it off, then on, then off, etc. The last part of the loop just waits 500ms before looping again.

Note

Depending on the "quality" of the contacts in the button you are using, you may need to add debouncing logic to the interrupt handler. "Bouncing" is a phenomenon with switch contacts (or any other mechanical contact) that can cause the contact to open/close many times very quickly when changing state. This is due to the electrical signal bridging the gap as the contacts are very close to each other (think static electricity jumping a gap). A lot of times this is handled on the hardware side by a capacitor, but I'm not sure for the Netduino how it handles it.