Code Examples

The majority of the code shown below is taken from the Sample .Net code delivered as part of the RedRat SDK. It demonstrates, in a simple fashion, the use of the RedRat API and most of the RedRat3’s functionality.

Finding a RedRat3

The code snippet below provides an example of how to find RedRat3 devices attached to a computer or on a network. The method RedRat3USBImpl.FindDevices() returns a list of all RedRat3s found and the first device on the list is selected.

protected IRedRat3 redRat3;

protected void OpenRedRat3() 
{
    try
    {
        // Find the no. of RedRat3s connected.
        var devices = RedRat3USBImpl.FindDevices();
        if (devices.Count > 0)
        {
            // Take the first device found.
            redRat3 = (IRedRat3)devices[0].GetRedRat();
        }
        else
        {
            MessageBox.Show("No RedRat3 devices found.", "TestRemote Warning", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
    }
}

A specific RedRat can be found via information associated with the LocationInfo object, such as the device name or serial number, using the following code:

public IRedRat LookupRedRat(string redRatName)
{
    if (redRatName == null) return null;
    var devices = RedRat3USBImpl.FindDevices();
    foreach (var device in devices)
    {
        var rr3 = (IRedRat3)device.GetRedRat();
        if (rr3.LocationInformation.Name.Equals(redRatName)) return rr3;
    }

    throw new Exception("No RedRat with name: " + redRatName);
}

 

Discovering Information about the RedRat

The code snippet below shows how to print information about the RedRat3.

public void RedRatInfo()
{
    // Obtain and display info about the RedRat3.
    string msg;
    if (redRat3 != null)
    {
        var sb = new StringBuilder();

        // Physical USB hardware information
        var devInfo = (USBDeviceInfo)redRat3.DeviceInformation;
        sb.Append(devInfo + "\n");
        sb.Append("Hardware Version: " + devInfo.ProductName + "." + devInfo.ProductDescriptor.Version);
        sb.Append("\nSerial Number: " + devInfo.SerialNumber);

        // Firmware version information read directly from RedRat3
        sb.Append("\nFirmware Version: " + redRat3.FirmwareVersion);

        // Physical position is returned in LocationInfo object
        sb.Append("\nLocation: " + redRat3.LocationInformation);
           
        msg = sb.ToString();
    }
    else
    {
        msg = "No RedRat3 connected."; 
    }

    MessageBox.Show(msg, @"RedRat3 Info.", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

 

IR Signal Input – Learning Mode

To allow the RedRat3 to enable IR signal input from the learning detector, first a learning-signal event delegate needs to be created.

protected SignalEventArgs SignalInEvent { get; set; }

protected void SignalDataIn(object sender, EventArgs e)
{
    var args = e as SignalEventArgs;
    if (args == null) return;
    SignalInEvent = args;
}

The SignalEventArgs object indicates several things: whether the signal has been captured properly, the signal capture has been cancelled by the user or an error has occurred via exception handling. The following code snippet shows how to add the learning-signal event delegate to the RedRat3 instance and then perform the above checks.

var learningSig = true;
IRPacket irPacket = null;

try
{
    // Tell the RedRat3 we want to input a demodulated signal
    redRat3.GetModulatedSignal(0);

    // Handle the input signal event from the RedRat3.
    redRat3.LearningSignalIn += SignalDataIn;

    while (learningSig)
    {
        if (SignalInEvent != null)
        {
            learningSig = false;

            // Once signal is learnt, get the event object
            var siea = SignalInEvent;

            switch (siea.Action)
            {
                // There is input data of some kind...
                case SignalEventAction.MODULATED_SIGNAL:
                    irPacket = siea.IRPacket;
                    break;

                // There is an error from the comms with the USB device, so read exception and throw it.
                case SignalEventAction.EXCEPTION:
                    throw siea.Exception;

                // The user has cancelled learning input signal
                case SignalEventAction.INPUT_CANCELLED:
                    break;
            }
        }
    }
}
catch (Exception ex)
{
    var msg = ex.Message;
    if (ex.InnerException != null)
    {
        msg += ": " + ex.InnerException.Message;
    }

    MessageBox.Show(msg, "Communication Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
finally
{
    // Remove event listener and object.
    redRat3.LearningSignalIn -= SignalDataIn;
    SignalInEvent = null;
}

The finally section ensures the learning-signal event delegate is removed.

Outputting a Remote Control Signal

The following code snippet provides a simple example of how to output a captured signal.

var sig = irPacket as ModulatedSignal;
if (sig == null) return;
if (redRat3 == null) return;
try
{
    // Send the ModulatedSignal object to the RedRat3
    redRat3.OutputModulatedSignal(sig);
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}

 

Loading a Signal Database

To use a database of IR signals from several audio-visual devices, the code snippet below can be used. The database is loaded from an XML file to create an object of type AVDeviceDB. This object contains multiple AVDevice objects which each represent a particular piece of AV equipment or remote.

// Read signal database from XML file.
AVDeviceDB newAVDeviceDB = null;
var openFileDialog = new OpenFileDialog
{
    Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*",
    RestoreDirectory = true
};

if (openFileDialog.ShowDialog() != DialogResult.OK) return;
var serializer = new XmlSerializer(typeof(AVDeviceDB));
var fileInfo = new FileInfo(openFileDialog.FileName);
FileStream fs = null;

try
{
    fs = new FileStream(fileInfo.FullName, FileMode.Open);
    newAVDeviceDB = (AVDeviceDB)serializer.Deserialize(fs);
}
catch (Exception ex)
{
    MessageBox.Show("Error opening config file: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
finally
{
    if (fs != null)
    {
        fs.Close();
    }
}

 

Using the Database to Decode Signals

Upon input from a remote control, IR signals need to be decoded by a RedRat3 before they can be used. First, a listener for the RCDetectorSignalIn event needs to be added.

// Add listener for incoming signals.
redRat3.RCDetectorSignalIn += RCSignalDataIn;
redRat3.RCDetectorEnabled = true;

// Application code here…

// Tidy up on program termination.
redRat3.RCDetectorSignalIn -= RCSignalDataIn;
redRat3.RCDetectorEnabled = false;

Once a valid signal has been received, it is passed directly to the AVDeviceDB object for decoding.

public void RCSignalDataIn(object sender, EventArgs e)
{
    var siea = e as SignalEventArgs;
    if (siea == null) return;

    switch (siea.Action)
    {
        case SignalEventAction.EXCEPTION:
            MessageBox.Show( siea.Exception.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation );
            break;

        case SignalEventAction.MODULATED_SIGNAL:
            if (avDeviceDB != null)
            {
                // Decode signal if there is a database.
                try
                {
                    var sigKey = avDeviceDB.DecodeSignal(siea.ModulatedSignal);
                    MoveWindow(sigKey);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message + "\n" + ex.StackTrace + "\n");
                }
            }
            break;
    }
}

The DecodeSignal() methods returns a SignalKey object which contains information identifying the signal. As an example, the SignalKey can then be passed to the following MoveWindow() method to change the location of a simple WinForms application window on the screen.

protected void MoveWindow(SignalKey sigKey)
{
    // Read current location
    var curLoc = Location;

    // Should not get a null return, but check in case.
    if (sigKey == null || sigKey.AVDevice == null)
    {
        lastMove = Direction.NONE;
        stepSize = 1;
        return;
    }

    // Respond to buttons on a particular remote, e.g. button "Down" on remote "CD".
    if (!sigKey.AVDevice.Name.Equals("CD")) return;

    if (sigKey.Signal.Name.Equals("Down", StringComparison.InvariantCultureIgnoreCase))
    {
        // Move down
        AdjustStepSize(Direction.DOWN);
        curLoc.Y += (int) stepSize;
        
        // If window moves off screen, move back onto other side
        if (curLoc.Y > workingScreenSize.Height)
        {
            curLoc.Y = 0;
        }
    }
    else
    {
        lastMove = Direction.NONE;
        stepSize = 1;
    }

    SetLocation(curLoc);
}

The new location of the window is set as follows:

protected void SetLocation( Point newLocation )
{
    // Likely to be a cross-thread GUI op.
    if ( InvokeRequired )
    {
        Invoke( new Action( () => Location = newLocation ) );
    }
    else
    {
        Location = newLocation;
    }
}

 

Remote Control Signal Queue

When reading incoming signals from the RedRat3, the action that each signal initiates on the computer cannot take too long or the RedRat will miss part or all of the next signal. As a result, the signal data needs to be decoupled from the RedRat and the signal event dispatching using a FIFO queue as follows:

case SignalEventAction.MODULATED_SIGNAL:
    Console.WriteLine("Have signal. Queue size is: " + siea.QueueSize);
    Thread.Sleep(400);
    break;

In some situations, the signal backlog may become too large and it may be desired to clear the queue. This can be done with the following code snippet:

// Only want to respond to buttons on remote "CD"
if (sigKey.AVDevice.Name.Equals("CD"))
{
    if (sigKey.Signal.Name.Equals("Skip+"))
    {
        mediaPlayer.NextTrack();
        Thread.Sleep(500);
        if (sender is IRedRat3)
        {
            // Clearing the queue.
            ((IRedRat3)sender).ClearRCSignalInQueue();
        }
    }
}

 

Database Signal Lookup for Output

The code snippet below shows  how to obtain a particular signal from the signal database for output.

var sig = (ModulatedSignal)newAVDeviceDB.GetIRPacket("CD", "Pause");
redRat3.OutputModulatedSignal(sig);

Instead of a device and signal name, a UID can also be used to lookup a signal:

var sig = (ModulatedSignal)newAVDeviceDB.GetIRPacket(uid);
This site uses cookies. Find out more about this site’s cookies.