Search code examples
c#xamarinuwpiotheadless

serial connection on UWP Headless app


I want to create a headless app for a Raspberry Pi that involves reading data from a serial port.

The sample app from Microsoft works fine, except that it has a user interface.

When creating the headless app, I took all relevant parts over as follows:

var aqs = SerialDevice.GetDeviceSelector();

var dis = await DeviceInformation.FindAllAsync(aqs);

foreach (var t in dis)
{
    if (t.Id.Contains("FTDI"))
    {
        listOfDevices.Add(t);

    }

}

if (listOfDevices.Count == 1)
{
    DeviceInformation entry = listOfDevices[0];

    try
    {
        serialPort = await SerialDevice.FromIdAsync(entry.Id);
        serialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
        serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
        serialPort.BaudRate = 9600;
        serialPort.Parity = SerialParity.None;
        serialPort.StopBits = SerialStopBitCount.One;
        serialPort.DataBits = 8;
        serialPort.Handshake = SerialHandshake.None;

        ...

There is one USB-FTDI-cable, where the ID contains "FTDI" as follows:

serialPort = await SerialDevice.FromIdAsync(entry.Id);

The program reaches this line before the instance of the program disappears and ignores my breakpoint.

Any ideas?


Solution

  • I use your code and add the following lines in Package.appxmanifest.

    <DeviceCapability Name="serialcommunication">
      <Device Id="any">
        <Function Type="name:serialPort" />
      </Device>
    </DeviceCapability>
    

    It works for me.

    Update:

    Based on your project(that you sent to me), because your ListAvailablePorts() is an asynchronous operation, you need to use the GetDeferral method to get a background task deferral to keep the host process from being suspended or terminated before the asynchronous operation complete. You can edit your code like this:

        BackgroundTaskDeferral _deferral = null;
        public async void Run(IBackgroundTaskInstance taskInstance)
        {
            _deferral = taskInstance.GetDeferral();
            // 
            // TODO: Insert code to start one or more asynchronous methods 
            //
            try
            {
                //var u = new USART();
                //await u.Initialize(115200, SerialParity.None, SerialStopBitCount.One, 8);
                listOfDevices = new ObservableCollection<DeviceInformation>();
                ListAvailablePorts();
            }
    
            ...
        }
    

    And call _deferral.Complete() when the asynchronous operation is finished.