Detecting Rising Edges, Falling Edges & Latches with Remote IO Devices and .NET API

FAQs

Download
Brainboxes.IO.Examples.ChangeEvents.zip

With Brainboxes Remote IO Devices (ED-XXX product codes), it is simple to detect changes in digital IO line state. This is when the digital IO line voltage level changes, from High to Low or vice versa, recorded by the Brainboxes ED device as a change in value from 1 to 0.

This is useful when notifying of a change in state of a sensor, which is input to the device, or a change in state of an output from the ED device.

This FAQ will use C# to demonstrate the concepts using the Brainboxes.IO .NET API . The example code attached targets .NET 6, although the code can be ran in almost any version of .NET.

Sample code demonstrating registering and receiving events when a change occurs on a remote IO device

// Download brainboxes library from nuget
using Brainboxes.IO;

// IP address of device to connect to
string ipAddress = "192.168.2.76";

// create a Brainboxes ED device, can be any of the available classes e.g. ED588, ED527, ED008
var device = new ED516(new TCPConnection(ipAddress));

// register for changed to any of the IO lines
device.IOLineChanged += Device_IOLineChanged;

// alternatively can monitor events of just 1 individual line
// device.IOLines[0].IOLineChanged += Device_IOLineChanged;
// or can monitor events of a collection of lines e.g. for the first 4 digital inputs
// device.Inputs.Take(4).AsIOList().IOLineChange += Device_IOLineChanged;
// open a connection to the device to start listening for changes

device.Connect();
Console.WriteLine($"Connected to {device} waiting for changes on IO lines");

// pause main console thread here, press enter to exit application
Console.ReadLine();

/// <summary>
/// any time an IO line of the brainboxes device changes state this function is called
/// there are 3 types of IOLine changes which may invoke this function call:

/// - IOChangeTypes.RisingEdge - when an IOLine transitions from low to high (0 -> 1)
/// - IOChangeTypes.FallingEdge - when an IOLine transitions from high to low (1-> 0)
/// - IOChangeTypes.Latched - when an IOLine rapidly transitions at least twice

/// . e.g. from high to low to high or vice versa (1 -> 0 -> 1, or 0 -> 1 => 0)
/// Latched only applies to Digital Inputs
/// </summary>

void Device_IOLineChanged(IOLine line, EDDevice device, IOChangeTypes changeType)
{
Console.WriteLine($"{DateTime.Now.ToString("hh.mm.ss.ffffff")}: Device_IOLineChanged line:{line}, device:{device}, changeType:{changeType}");

// latched events contain both rising and falling edge events
// they have simple happened more quickly than the polling interval
// we report them as latched, but the binary value of the enum is the same as
// IOChangeTypes.Latched == IOChangeTypes.RisingEdge & IOChangeTypes.FallingEdge & 0x04
// 0x07 = 0x1 & 0x02 & 0x4
// which means all types of rising edges can be detected like this
if ((changeType & IOChangeTypes.RisingEdge) == IOChangeTypes.RisingEdge)

{
Console.WriteLine($"Rising Edge (including latched)");
}
// or all types of falling edges can be detected like this

if ((changeType & IOChangeTypes.FallingEdge) == IOChangeTypes.FallingEdge)
{
Console.WriteLine($"Falling Edge (including latched)");
}
}

There are Three possible change types for digital IO lines:

  1. Rising Edge: Occurs when the digital IO line goes from 0 to 1
  2. Falling Edge: Occurs when the digital IO line goes from 1 to 0
  3. Latched: Occurs when the digital INPUT line transitions more quickly than the background polling interval, and has transitioned at least twice, e.g. at least one Rising Edge and one Falling Edge has occurred (within the IO Timeout Interval)

Its straight forward in the code to then filter out the events of interest. For example for falling Edges we can do the following:

Use the bitwise and operator. This is because the IOChangeType is an enum with values defined as:

The online documentation for this is here: Brainboxes_IO_IOChangeTypes

If the user is only interested in rising edges, regardless of whether they happen through a latch event or standard rising edge event, then register for the rising event as follows:

// register only for the rising edge events including latched events
// all IOline rising edges across device
device.IOLineRisingEdge += Device_IOLineRisingEdge;

// or can monitor rising events of just 1 individual line
device.IOLines[0].IOLineRisingEdge += Device_IOLineRisingEdge;

// or can monitor events of a collection of lines e.g. digital outputs 2,3,4,5
device.Outputs.Skip(2).Take(4).AsIOList().IOLineRisingEdge += Device_IOLineRisingEdge;

// this will only trigger for IOChangeTypes.RisingEdge and IOChangeTypes.Latched events
void Device_IOLineRisingEdge(IOLine line, EDDevice device, IOChangeTypes changeType)
{
Console.WriteLine($"{DateTime.Now.ToString("hh.mm.ss.ffffff")}: Device_IOLineRisingEdge line:{line}, device:{device}, changeType:{changeType}");
}

And the same applies to falling edge events using the IOFallingEdge event. For a list of all available events see:

If Latches are not the desired behaviour, there are two ways to mitigate against them:

    1. Set the debounce for the IO line to a interval which means that the latching behaviour shouldn’t occur (this helps with ‘bouncy’ inputs). For example, if a sensor when it changes state typically bounces (or rings), then set a debounce time which is greater than how long the input rings for. This can be done through the web user interface IO Lines page:
    2. Reduce the IOCacheTimeout setting to be half the expected change interval. For example, if the IO lines change every 100 milliseconds, set the IOCacheTimeout to 50ms to avoid seeing latches. Please note this will increase the amount of background polling done by the .NET API. For many networks, it is unwise to set this number lower than 20ms.
// Download brainboxes library from nuget
using Brainboxes.IO;

// ip address of device to connect to
string ipAddress = "192.168.2.107";

// create a Brainboxes ED device, can be any of the available classes e.g. ED588, ED527, ED008
var device = new ED588(new TCPConnection(ipAddress));

// set the IOLine cache timeout to 50 milliseconds, the device will now poll every 50ms
device.IOLineCacheTimeout = 50;

For more information on the IOCacheTimeout, please see the following link: Brainboxes_IO_EDDevice_IOLineCacheTimeout

Conclusion

This article has covered the how to detect rising and falling edges of Digital IO devices using the .NET API with a focus on C#. The concepts covered are exactly the same if programming in VB or F#.

It has shown how to register events for Rising Edge, Falling edge and all change types. It has also shown how to avoid Latched events if these are not necessary to be distinguished from standard rising or falling edges. Sample code is provided to download and run in .NET 6.

FAQs