PulseInOut InterruptPort

Hi all, is it possible to use the input of the pulseinout module to act as an interruptport for a 3 pin button (common, normally open, normally closed)?

@ growls - Why would you want to do that? Use an InterruptPort with common and one of the sides.

Because I dont want to waste a whole socket on a bumper switch :slight_smile:
Especially when I already use the pulseinout for a couple of servos

I found this on the examples:
http://gadgeteer.codeplex.com/SourceControl/latest#Main/Modules/GHIElectronics/PulseInOut/Software/PulseInOut/PulseInOut_41/PulseInOut_41.cs
however I am having trouble getting it to work:
An unhandled exception of type ‘Gadgeteer.Socket.PinConflictException’ occurred in Gadgeteer.dll

I modified it a little:


using System;
using Gadgeteer;
using Gadgeteer.Modules.GHIElectronics;
using Microsoft.SPOT;

using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using GTI = Gadgeteer.Interfaces;

namespace GadgeteerApp5
{
    /// <summary>
    /// A PulseInOut module for Microsoft .NET Gadgeteer
    /// </summary>
    public class MyPulseInOut : PulseInOut
    {
        // This example implements a driver in managed code for a simple Gadgeteer module.  This module uses a 
        // single GTI.InterruptInput to interact with a button that can be in either of two states: pressed or released.
        // The example code shows the recommended code pattern for exposing a property (IsPressed). 
        // The example also uses the recommended code pattern for exposing two events: Pressed and Released. 
        // The triple-slash "///" comments shown will be used in the build process to create an XML file named
        // GTM.GHIElectronics.PulseInOut. This file will provide IntelliSense and documentation for the
        // interface and make it easier for developers to use the PulseInOut module.        

        // Note: A constructor summary is auto-generated by the doc builder.
        /// <summary></summary>
        /// <param name="socketNumber">The socket that this module is plugged in to.</param>
        /// <param name="socketNumberTwo">The second socket that this module is plugged in to.</param>
        public MyPulseInOut(int socketNumber) : base(socketNumber)
        {
            
            // This finds the Socket instance from the user-specified socket number.  
            // This will generate user-friendly error messages if the socket is invalid.
            // If there is more than one socket on this module, then instead of "null" for the last parameter, 
            // put text that identifies the socket to the user (e.g. "S" if there is a socket type S)
            Socket socket = Socket.GetSocket(socketNumber, true, this, null);

            // This creates an GTI.InterruptInput interface. The interfaces under the GTI namespace provide easy ways to build common modules.
            // This also generates user-friendly error messages automatically, e.g. if the user chooses a socket incompatible with an interrupt input.
            this.input = new GTI.InterruptInput(socket, GT.Socket.Pin.Four, GTI.GlitchFilterMode.On, GTI.ResistorMode.PullUp, GTI.InterruptMode.RisingAndFallingEdge, this);

            // This registers a handler for the interrupt event of the interrupt input (which is bereleased)
            this.input.Interrupt += new GTI.InterruptInput.InterruptEventHandler(this._input_Interrupt);
        }

        private void _input_Interrupt(GTI.InterruptInput input, bool value)
        {
            this.OnButtonEvent(this, value ? ButtonState.Released : ButtonState.Pressed);
        }

        private GTI.InterruptInput input;

        /// <summary>
        /// Gets a value that indicates whether the button of the PulseInOut is pressed.
        /// </summary>
        public bool IsPressed
        {
            get
            {
                return this.input.Read();
            }
        }

        /// <summary>
        /// Represents the state of button of the <see cref="PulseInOut"/>.
        /// </summary>
        public enum ButtonState
        {
            /// <summary>
            /// The button is released.
            /// </summary>
            Released = 0,
            /// <summary>
            /// The button is pressed.
            /// </summary>
            Pressed = 1
        }

        /// <summary>
        /// Represents the delegate that is used to handle the <see cref="ButtonPressed"/>
        /// and <see cref="ButtonReleased"/> events.
        /// </summary>
        /// <param name="sender">The <see cref="PulseInOut"/> object that raised the event.</param>
        /// <param name="state">The state of the button of the <see cref="PulseInOut"/></param>
        public delegate void ButtonEventHandler(PulseInOut sender, ButtonState state);

        /// <summary>
        /// Raised when the button of the <see cref="PulseInOut"/> is pressed.
        /// </summary>
        /// <remarks>
        /// Implement this event handler and/or the <see cref="ButtonReleased"/> event handler
        /// when you want to provide an action associated with button events.
        /// Since the state of the button is passed to the <see cref="ButtonEventHandler"/> delegate,
        /// so you can use the same event handler for both button states.
        /// </remarks>
        public event ButtonEventHandler ButtonPressed;

        /// <summary>
        /// Raised when the button of the <see cref="PulseInOut"/> is released.
        /// </summary>
        /// <remarks>
        /// Implement this event handler and/or the <see cref="ButtonPressed"/> event handler
        /// when you want to provide an action associated with button events.
        /// Since the state of the button is passed to the <see cref="ButtonEventHandler"/> delegate,
        /// you can use the same event handler for both button states.
        /// </remarks>
        public event ButtonEventHandler ButtonReleased;

        private ButtonEventHandler onButton;

        /// <summary>
        /// Raises the <see cref="ButtonPressed"/> or <see cref="ButtonReleased"/> event.
        /// </summary>
        /// <param name="sender">The <see cref="PulseInOut"/> that raised the event.</param>
        /// <param name="buttonState">The state of the button.</param>
        protected virtual void OnButtonEvent(PulseInOut sender, ButtonState buttonState)
        {
            if (this.onButton == null)
            {
                this.onButton = new ButtonEventHandler(this.OnButtonEvent);
            }

            if (buttonState == ButtonState.Pressed)
            {
                // Program.CheckAndInvoke helps event callers get onto the Dispatcher thread.  
                // If the event is null then it returns false.
                // If it is called while not on the Dispatcher thread, it returns false but also re-invokes this method on the Dispatcher.
                // If on the thread, it returns true so that the caller can execute the event.
                if (Gadgeteer.Program.CheckAndInvoke(ButtonPressed, this.onButton, sender, buttonState))
                {
                    this.ButtonPressed(sender, buttonState);
                }
            }
            else
            {
                if (Gadgeteer.Program.CheckAndInvoke(ButtonReleased, this.onButton, sender, buttonState))
                {
                    this.ButtonReleased(sender, buttonState);
                }
            }
        }
    }
}

Are you using framework 4.1? If not, go back and grab the 4.2 code. (big note though: this is the DRIVER SOURCE not an example!)

‘Gadgeteer.Socket.PinConflictException’

Says it all. You are using a pin twice. If you include this code in your program, but you also include the PulseInOut module in your Gadgeteer designer, you get two copies of the code trying to use the same thing - that’s as simple as removing the code or removing the module from the designer.

What are you trying to achieve???

im trying to plug a button into the pulseinout module and create events or at the very least check for its high or low state to see if it has been pressed.

@ Jeff@ GHI, this would be a good module to add some example code around on the Documents page…

Here’s where the latest driver for the PulseInOut module is (which is the 4.2 framework code) http://gadgeteer.codeplex.com/SourceControl/latest#Main/Modules/GHIElectronics/PulseInOut/Software/PulseInOut/PulseInOut_42/PulseInOut_42.cs

From there, I can see that the module is explicitly exposing the PWM capability and not a general IO capability. So the “simplest” answer to your original question is no, you can’t use the PulseInOut as a general purpose IO device, including interrupts.

@ Taylorza has a community Daisylink DL40 IO project. https://www.ghielectronics.com/community/forum/topic?id=10325&page=1

I am betting that because this is a DL module, you could potentially use the DL40IO firmware on your PulseInOut and then access both the PWM capability and the general IO capability. If Chris sees this post, maybe he’ll comment ?

PulseInOut module firmware is available as well, so going back is possible. Linked from https://www.ghielectronics.com/docs/107/pulse-inout-module-daisylink

Thanks to @ Brett for letting me know about this post.

Unfortunately the DL40 I/O firmware will not work without a minor modification. The modules have minor differences in the pins mapped to the Gadgeteer sockets. For example, the downstream socket uses pin 1.2 on the DL40 while the Pulse I/O use pin 3.5 for the downstream signal line.

I could very well work if you do not need to chain downstream modules so you could try that, since the upstream socket is wired the same. I do not have a Pulse I/O so I cannot test this, but I expect it would work for a single module.