SIMPL# Pro Primer: Part 3

By now you should be a pro at creating new SIMPL# Pro projects. Let’s create another one, but we’re going to set this one up slightly different this time. We’ll still call it Part3, but change the solution name to Primer:

Slight change in project creation, we’ll add everything to the Primer solution from now on

First things first. Let’s strip back our program in ControlSystem.cs to its essentials:

using System;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.CrestronThread;

namespace Part3
{
    public class ControlSystem : CrestronControlSystem
    {
        public ControlSystem()
            : base()
        {
            Thread.MaxNumberOfUserThreads = 20;
        }

        public override void InitializeSystem()
        {

        }
   }
}

Remember I said InitializeSystem is one of those methods your program needs to return from quickly? What happens if your program takes too long in this one method? Add the following to InitializeSystem to find out:

public override void InitializeSystem()
{
    Thread.Sleep(60000); // Wait for 60s
}

If you watch in Text Console, you’ll see the program takes about 60 seconds longer to start up now:

I’ll be honest, I thought taking a full minute to do anything would have locked up the system, but it appears to work just fine. Let’s keep that in mind: if a process may take longer than a minute (say downloading an entire phonebook), delay that until after the system has started. Otherwise, we can put most things into InitializeSystem.

Let’s imagine a simple system we want to program. Here’s a quick diagram:

We already know how to add touchpanels to our program, so go ahead and do that now. Add the default SigChange handler as well. Our code should now look like:

using System;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.CrestronThread;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.UI;

namespace Part3
{
    public class ControlSystem : CrestronControlSystem
    {
        private Tsw1050 _tp;

        public ControlSystem()
            : base()
        {
            Thread.MaxNumberOfUserThreads = 20;
        }

        public override void InitializeSystem()
        {
            _tp = new Tsw1050(0x03, this);
            _tp.SigChange += new SigEventHandler(_tp_SigChange);
            _tp.Register();
        }

        void _tp_SigChange(BasicTriList currentDevice, SigEventArgs args)
        {
            throw new NotImplementedException();
        }
   }
}

Lets add the 8×8 DM switcher. You’ll need to add a reference to Crestron.SimplSharpPro.DM to your project to access all things related to Digital Media. Just a few updates to our program, and we’ll have the DM-TX-4K-100-C-1G and DM-RMC-4K-100-C added:

using System;
using System.Collections.Generic;
using Crestron.SimplSharp;
using Crestron.SimplSharpPro;
using Crestron.SimplSharpPro.CrestronThread;
using Crestron.SimplSharpPro.DeviceSupport;
using Crestron.SimplSharpPro.DM;
using Crestron.SimplSharpPro.DM.Cards;
using Crestron.SimplSharpPro.DM.Endpoints.Receivers;
using Crestron.SimplSharpPro.DM.Endpoints.Transmitters;
using Crestron.SimplSharpPro.UI;

namespace Part3
{
    public class ControlSystem : CrestronControlSystem
    {
        private Tsw1050 _tp;
        private Switch _sw;
        private List<CardDevice> _inputs;
        private List<DmcOutputSingle> _outputs;

        private DmTx4K100C1G _tx;
        private DmRmc4k100C _rx;

        public ControlSystem()
            : base()
        {
            Thread.MaxNumberOfUserThreads = 20;
        }

        public override void InitializeSystem()
        {
            _tp = new Tsw1050(0x03, this);
            _tp.SigChange += new SigEventHandler(_tp_SigChange);
            _tp.Register();

            _inputs = new List<CardDevice>();
            _outputs = new List<DmcOutputSingle>();

            _sw = new DmMd8x8(0x10, this);
            _inputs.Add(new Dmc4kC(1, _sw));
            _outputs.Add(new DmcCoHdSingle(1, _sw));
            
            _tx = new DmTx4K100C1G(0x14, _sw.Inputs[1]);
            _tx.OnlineStatusChange +=new OnlineStatusChangeEventHandler(_tx_OnlineStatusChange);
            
            _rx = new DmRmc4k100C(0x15, _sw.Outputs[1]);
            _rx.OnlineStatusChange += new OnlineStatusChangeEventHandler(_rx_OnlineStatusChange);
            
            _sw.OnlineStatusChange += new OnlineStatusChangeEventHandler(_sw_OnlineStatusChange);
            _sw.Register();
        }

        void _tp_SigChange(BasicTriList currentDevice, SigEventArgs args)
        {

        }

        void _sw_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
        {

        }

        void _tx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
        {

        }

        void _rx_OnlineStatusChange(GenericBase currentDevice, OnlineOfflineEventArgs args)
        {

        }
    }
}

Adding endpoints to our switcher gets a bit weird… we need to tell the program which input and output cards are installed first. Then we can add the DM endpoints to the switcher. Once we register the switcher, all of our endpoints will also register. And here’s where I have to take it on faith that any of this actually works since I can’t test with real hardware yet. Maybe in the future?

To control the Blu-ray player, we need to load an appropriate IR driver. Lets use a generic Samsung driver. I’ve copied the Samsung BD Series.ir driver out of the Crestron database and saved it to the project directory. Right-click on our project and select Add > Existing Item…

Locate the IR file and add it to your project.

Once it’s added, select it in the Solution Explorer. In the Properties window, make sure Copy to Output Directory is set to Copy if newer

Build the project (F6) and load it to your processor. It still won’t do anything, but lets see where that IR file gets copied to. Using WinSCP, I found it in /Program01/Samsung BD Series.ir. In order to load it, we’re going to need to add a new using statement at the top of our program:

using Crestron.SimplSharp;
using Crestron.SimplSharp.CrestronIO;
using Crestron.SimplSharpPro;

Now add the following code to the _tx_OnlineStatusChange handler:

void _tx_OnlineStatusChange(GenericBase currentDevice,
                            OnlineOfflineEventArgs args)
{
    if (args.DeviceOnLine)
    {
        (currentDevice as DmTx4K100C1G).IROutputPorts[1].LoadIRDriver(
            Directory.GetApplicationDirectory() +
            Path.PathSeparator + "Samsung BD Series.ir");
    }
}

Now when the DM-TX-4K-100-C-1G comes online, we’ll load the IR file to it. But why the call to Directory.GetApplicationDirectory() and Path.PathSeparator? These are platform-independent ways of getting to the folder where our program files are copied to. That way if it changes in the future (say with the release of the 4-series), hopefully, our program will work without many changes.

The only thing remaining for our device control now is serial communication with our display. We’re going to assume a Samsung display as well, so we’ll need to configure the serial port settings. Lets add the following code to _rx_OnlineStatusChange:

void _rx_OnlineStatusChange(GenericBase currentDevice,
                            OnlineOfflineEventArgs args)
{
    if (args.DeviceOnLine)
    {
        (currentDevice as DmRmc4k100C).ComPorts[1].SetComPortSpec(
            ComPort.eComBaudRates.ComspecBaudRate9600,
            ComPort.eComDataBits.ComspecDataBits8,
            ComPort.eComParityType.ComspecParityNone,
            ComPort.eComStopBits.ComspecStopBits1,
            ComPort.eComProtocolType.ComspecProtocolRS232,
            ComPort.eComHardwareHandshakeType.ComspecHardwareHandshakeNone,
            ComPort.eComSoftwareHandshakeType.ComspecSoftwareHandshakeNone,
            false);
    }
}

This is a very wordy way of setting up the COM port on the DM-RMC-4KZ-100-C for RS-232 at 9600 baud, 8 data bits, no parity, no handshaking.

And this is probably a good place to stop for now. In the next part, we’ll get into how to pulse IR commands, send/receive serial strings to the display, and create a touchpanel layout for testing.

All the code for this section is available in my GitHub at: https://github.com/kielthecoder/SimplSharpPrimer.

3 thoughts on “SIMPL# Pro Primer: Part 3

  1. Hey bro, looks like there is a mistake in the ” _tx_OnlineStatusChange ” function.currentDevice should be set as DmTx4K100C1G, am I right? Btw, is there any tutorials for controlling Cisco VC by using SIMPL# Pro?

    Liked by 1 person

    1. Hey good catch! I’ll fix the code snippet above. I’ve thought about writing some posts on controlling Cisco codecs, so I’ll probably make that the next topic I explore. Thanks!

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s