User Tools

Site Tools


cfnet:cfheader:mode_of_operation:index

This is an old revision of the document!


CFHEADER Mode of Operation

The CFHEADER serves as a USB device interface between a host PC and the CFNET IO modules.

The host PC communicates with the CFHEADER module over USB while the CFHEADER module communicates with each CFNET IO module over I²C.

Normal Mode of Operation

  1. The program running on the host PC updates the state of the output modules by writing to properties such as DigitalOutputModule.Channel.State.
  2. When the Cfheader.Sync() function is called:
    1. The host PC transmits the updated state of the CFNET output modules to the CFHEADER's memory over USB.
    2. The CFHEADER module writes the updated state to the CFNET output modules via I²C.
    3. The CFHEADER module reads the state of the CFNET input modules via I²C.
    4. The CFHEADER module transmits the updated state of the CFNET input modules to the host PC over USB.
    5. The host PC updates the state of the CFNET input modules in the host PC's memory by writing to properties such as DigitalInputModule.Channel.State.
  3. The program, running on the host, processes the updated state of the CFNET input modules as read from the CFHEADER module.

That procedure can be visualized in source code form in the following program.

using ComfileTech.Cfnet.Cfheader;
 
// Get CFHEADER module at address 0
var cfheader0 = Cfheader.Instances[0];
 
// Get digital output module at address 0
var do0= cfheader0.DigitalOutputModules[0];
 
// Get digital input module at address 0
var di0= cfheader0.DigitalInputModules[0];
 
// Open USB communication with the CFHEADER module
cfheader0.Open();
 
while (true)
{
    // Update the state of the digital output modules
    foreach(var doChannel in do0.Channels)
    {
        doChannel.State = true;
    }
 
    // Write the updated state of the output modules to the CFHEADER module, and
    // read the updated state of the input modules from the CFHEADER module
    cfheader0.Sync();
 
    // Process the new state of the digital input modules
    foreach(var diChannel in di0.Channels)
    {
        // Process the digital input channel's state
        Console.WriteLine(diChannel.State);
    }
}

Calling `Sync` Asynchronously With `BackgroundSync`

Calling Sync() synchronously on the main thread may be straightforward for a console application, but for a graphical user interface, it may be best to call Sync() asynchronously in the background.

Use the BackgroundSync class to call Sync() asynchronously and repeatedly in a background thread.

using ComfileTech.Cfnet.Cfheader;
 
// Get CFHEADER module at address 0
var cfheader0 = Cfheader.Instances[0];
 
// Get digital output module at address 0
var do0 = cfheader0.DigitalOutputModules[0];
 
// Get digital input module at address 0
var di0 = cfheader0.DigitalInputModules[0];
 
// Open USB communication with the CFHEADER module
cfheader0.Open();
 
// Start the background sync thread
cfheader0.BackgroundSync.Start();
 
while (true)
{
    // Update the state of the digital output modules
    foreach(var doChannel in do0.Channels)
    {
        doChannel.State = true;
    }
 
    // Process the new state of the digital input modules
    foreach(var diChannel in di0.Channels)
    {
        // Process the digital input channel's state
        Console.WriteLine(diChannel.State);
    }
}

Use polling in a timer, or subscribe to BackgroundSync's, IO modules', and channels' events (e.g. Synced, StateChanged, ConversionCompleted, etc.) to respond to state changes. Be aware that the events fired from BackgroundSync will be in the context of the background thread, so it may be necessary to use techniques such as BeginInvoke and InvokeAsync to update a UI on the main UI thread.

Error Handling

To program a robust IO solution, all sources of errors must be handled. For the CFHEADER, there 2 primary sources for potential errors.

  1. USB communication errors
  2. I²C communication errors

Handling USB Communication Errors

USB communications errors can occur in either the Cfheader.Open() method or the Cfheader.Sync() method. To handle any errors that may occur in those methods, simply wrap them in a try…catch block, and handle any exceptions that occur in the catch block.

using ComfileTech.Cfnet.Cfheader;
 
// Open USB communication with the CFHEADER module
try
{
    cfheader0.Open();
}
catch (Exception ex)
{
    // Handle any USB communication errors that occur here.
}
 
while (true)
{
    // Write the updated state of the output modules to the CFHEADER module, and
    // read the updated state of the input modules from the CFHEADER module
    try
    {
        cfheader0.Sync();
    }
    catch (Exception ex)
    {
        // Handle any USB communication errors that occur here.
    }
}

For any error that occurs when calling Sync(), it may be necessary to Close() and Open() the CFHEADER module again to recover.

Handling USB Communication Errors From `BackgroundSync`

If using BackgroundSync, subscribe to the BackgroundSync.ExceptionThrown event to capture any errors that occur when the background thread calls Cfheader.Sync().

using ComfileTech.Cfnet.Cfheader;
 
// Open USB communication with the CFHEADER module
try
{
    cfheader0.Open();
}
catch (Exception ex)
{
    // Handle any USB communication errors that occur here.
}
 
// Capture any errors that occur when calling `Sync` in the background thread.
cfheader0.BackgroundSync.ExceptionThrown += (bs, ex) =>
{
    Console.Error.WriteLine($"Exception was through from `BackgroundSync`: {ex.Message}");
}
 
// Start the background sync thread
cfheader0.BackgroundSync.Start();
 
while (true)
{
    Thread.Yield();
}

For any error that occurs, it may be necessary to Close() and Open() the CFHEADER module again to recover.

Handling I²C Communication Errors

If the CFHEADER module encounters an error while communicating with CFNET IO module over I²C, then the error will be reported in the IIOModule.I2cStatus property after the Sync() method returns.

If such an error occurs, the CFHEADER module will no longer attempt to communicate with the CFNET IO module until the IIOModule.AcknowledgeI2cFailure() method is called to acknowledge the error. After acknowledging the error, the CFHEADER module will attempt to communicate with the CFNET IO module again in the next call to Sync().

while (true)
{
    // Write the updated state of the output modules to the CFHEADER module, and
    // read the updated state of the input modules from the CFHEADER module
    cfheader0.Sync();
 
    if (do0.I2cStatus != I2cStatus.Success)
    {
        // Handle the I²C communication failure
        Console.Error.WriteLine($"I²C communication with the digital output module at address {do0.Address} failed.");
 
        // Acknowledge the I²C communication failure
        do0.AcknowledgeI2cFailure();
    }
}

Handling I²C Communication Errors If Using `BackgroundSync`

If using BackgroundSync, subscribe the the IO module's I2cFailed event to capture any I²C communication errors that occur with that module.

do0.I2cFailed += module =>
{
    Console.WriteLine($"I²C communication with digital output module at address {module.Address} failed.");
}
cfnet/cfheader/mode_of_operation/index.1771222432.txt.gz · Last modified: by 127.0.0.1