UWP sync communication serial device

0

I'm working on a C# UWP APP and I need to communicate with many devices using an USB port as Serial Port. After that I will convert the communication to RS485 to communicate with the other devices. Until now, I have create a class that will make all comunications between my devices and I can sent a trama between my devices.

My problem at this point is that after sending some startup frames, the application changes the page and from that moment gives me the following exception in my ReadAsync method:

**

System.Exception occurred HResult=-2147023901 Message=The I/O operation was canceled due to a module output or an application request. (Exception from HRESULT: 0x800703E3) Source=mscorlib
StackTrace: at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at DrDeliver.CComm.d__31.MoveNext() InnerException:

**

Exception Picture

I already have this problem for a few days and I can't get over it.

I wonder if anyone can figure out where the problem is.

Another question I would like to ask is if anyone knows of any method that allows me to make this communication synchronously.

UPDATE 1 The entire class for communicatons:

public class CComm : IDisposable
{        
    EventLogDB _eldb = new EventLogDB();
    ParameterDB _pdb = new ParameterDB(); 
    cParameter _cParam = new cParameter();


    DataReader _dataReaderObject = null;

    private DispatcherTimer mTimer;

    private int num;

    public bool FlagComm { set; get; }

    public static string InBuffer { set; get; }

    public bool busyFlag = false;

    public CancellationTokenSource _readCancellationTokenSource = new CancellationTokenSource();

    private DeviceInformationCollection DeviceInformation { set; get; }

    private static SerialDevice SerialPort { set; get; }

    // Define a delegate  
    public delegate void CheckReadEventHandler(object source, EventArgs args);

    // Define an event based on that delegate    
    public event CheckReadEventHandler CheckRead;

    // Raise an event
    protected virtual void OnChecRead()
    {
        CheckRead?.Invoke(this, EventArgs.Empty);
    }

    private async Task OpenComm()
    {
        try
        {
            busyFlag = true;
            //_cParam = _pdb.getParameters();
            string selectedPortId = null;
            string aqs = SerialDevice.GetDeviceSelector();
            DeviceInformation = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(aqs);
            foreach (var devInfo in DeviceInformation)
            {
                if (devInfo.Name == "USB-RS485 Cable")
                {
                    selectedPortId = devInfo.Id;
                }
            }
            if (selectedPortId != null)
            {
                SerialPort = await SerialDevice.FromIdAsync(selectedPortId);     

                if (SerialPort != null)
                {
                    SerialPort.ReadTimeout = TimeSpan.FromMilliseconds(1500);
                    SerialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
                    SerialPort.BaudRate = 9600;
                    SerialPort.Parity = SerialParity.None;
                    SerialPort.StopBits = SerialStopBitCount.One;
                    SerialPort.DataBits = 8;
                    FlagComm = true;
                }
                else
                {
                    var status = DeviceAccessInformation.CreateFromId(selectedPortId).CurrentStatus;
                    FlagComm = false;
                    _eldb.attachEvent("E1002", "Starting Comunication Failed: " + status);
                    //ContentDialog noSerialDevice = new ContentDialog()
                    //{
                    //    Title = "No Serial Connection",
                    //    Content = "Check connection and try again. App Closing.",   
                    //};

                    //await noSerialDevice.ShowAsync();
                    //this.Dispose();
                }       
                InitTool();
                await ActivateListen();
                busyFlag = false;
            }   
        }
        catch (Exception ex)
        {
            _eldb.attachEvent("E1cC", ex.Message);
        }
    }    

    private async Task Listen()
    {
        try
        {
            if (SerialPort != null)
            {
                busyFlag = true;
                _dataReaderObject = new DataReader(SerialPort.InputStream);
                await ReadAsync(_readCancellationTokenSource.Token);
                busyFlag = false;
            }
        }
        catch (Exception ex)
        {

        }   
    }

    //using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(1000)))
    //{
    //    await dataReaderObject.LoadAsync(1024).AsTask(cts.Token);
    //}

    private async Task ReadAsync(CancellationToken cancellationToken)
    {      
        busyFlag = true;    
        const uint readBufferLength = 1024;  // only when this buffer would be full next code would be executed
        var loadAsyncTask = _dataReaderObject.LoadAsync(readBufferLength).AsTask(cancellationToken);  // Create a task object  
        _dataReaderObject.InputStreamOptions = InputStreamOptions.ReadAhead;     
        var bytesRead = await loadAsyncTask; // Launch the task and wait until buffer would be full 
        if (bytesRead > 0)
        {
            InBuffer += _dataReaderObject.ReadString(bytesRead);   
            OnChecRead();
        }              
        busyFlag = false;  
    }

    private async void WriteComm(string str2Send)
    {        
        using (var dataWriter = new DataWriter(SerialPort.OutputStream))
        {
            dataWriter.WriteString(str2Send);
            await dataWriter.StoreAsync();
            dataWriter.DetachStream();
        }   
    }

    private async Task ActivateListen()
    {
        while (FlagComm)
        {            
            await Listen();  
        }
    }             

    private void dispatcherTimer_Tick(object sender, object e)
    {
        _eldb.attachEvent("SYSTEM", "Checking ADDR: " + num);
        SendComm(num++, 5);
        if (num == 5)
        {
            mTimer.Stop();
            _eldb.attachEvent("SYSTEM", "Modules Checking Finished.");
            busyFlag = false;
        }
    }

    public void InitTool()
    {   
        busyFlag = true;
        _eldb.attachEvent("SYSTEM", "Setting Parameters.");
        // Get Parameters
        if (_pdb.GetParameters() == null)
        {
            // Set Default Parameters  
            _cParam.SetParam();
            // Insert Default parameters in database
            _pdb.Insert(_cParam);
            // Update Parameters Object
            _cParam = _pdb.GetParameters();
        }
        else
        {
            // Update Parameters Object
            _cParam = _pdb.GetParameters();
        }

        // Check Addresses in Line
        _eldb.attachEvent("SYSTEM", "Start Verifiyng.");

        num = 0;
        mTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(4000) };
        mTimer.Tick += dispatcherTimer_Tick;
        mTimer.Start();  
    }  

    public async void StartSerialComm()
    {
        try
        {
            await OpenComm();   
        }
        catch (Exception ex)
        {                        
            _eldb.attachEvent("E7cC", ex.Message);
        }
    }   

    public void SendComm(params int[] list)
    {
        try
        {
            _cParam = _pdb.GetParameters();
            string toSend = "";// = "A" + list[0] + "#";
            switch (list[1])
            {
                case 0:
                    // Send Initialazation command
                    toSend = "#@" + list[0] + "@" + list[1] + "@#";
                    break;
                case 1:
                    // List of parameters (minPower, maxPower, ramPercent, initSpeed)
                    toSend = "#@" + list[0] + "@" + list[1] + "@" + _cParam.minPower + "@" +
                        _cParam.maxPower + "@" + _cParam.percRamp + "@" + _cParam.initSpeed + "@#";
                    break;
                case 2:
                    // Send Status Request
                    toSend = "#@" + list[0] + "@" + list[1] + "@#";
                    break;
                case 3:
                    // Send a move Request
                    toSend = "#@" + list[0] + "@" + list[1] + "@" + list[2] + "@#";
                    break;
                case 4:
                    // Send a Error Request  
                    toSend = "#@" + list[0] + "@" + list[1] + "@#";
                    break;
                case 5:
                    // Send a start check  
                    toSend = "#@" + list[0] + "@" + list[1] + "@#";
                    break;
                default:
                    _eldb.attachEvent("E1004", "Wrong Function Command.");
                    break;
            }
            if (toSend != "")
            {
                WriteComm(toSend); 
            }
            else
            {
                _eldb.attachEvent("E1003", "Wrong String comunication.");
            }
        }
        catch (Exception ex)
        {                            
            _eldb.attachEvent("E8cC", ex.Message);
        }
    }  

    public void Dispose()
    {
        try
        {
            if (SerialPort == null) return;
            FlagComm = false;
            SerialPort.Dispose();
            SerialPort = null;
            if (_dataReaderObject == null) return;
            _readCancellationTokenSource.Cancel();
            _readCancellationTokenSource.Dispose();
        }
        catch (Exception ex)
        {
            _eldb.attachEvent("E6cC", ex.Message);
        }
    }
}

Main Page:

public sealed partial class MainPage : Page
{
    CComm _cC = new CComm();
    EventLogDB _eldb = new EventLogDB();   
    procTrama _cProcTrama = new procTrama();  

    private DispatcherTimer mTimer;

    public MainPage()
    {
        try
        {
            InitializeComponent();
            // Get the application view title bar
            ApplicationViewTitleBar appTitleBar = ApplicationView.GetForCurrentView().TitleBar;

            // Make the title bar transparent
            appTitleBar.BackgroundColor = Colors.Transparent;

            // Get the core appication view title bar
            CoreApplicationViewTitleBar coreTitleBar = CoreApplication.GetCurrentView().TitleBar;

            /*
                ExtendViewIntoTitleBar
                    Gets or sets a value that specifies whether this title
                    bar should replace the default window title bar.
            */

            // Extend the core application view into title bar
            coreTitleBar.ExtendViewIntoTitleBar = true;

            mTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(5000) };
            mTimer.Tick += dispatcherTimer_Tick;
            mTimer.Start();
            _eldb.attachEvent("S1027", "Init Started...");  
            // Start comunication
            _cC.StartSerialComm();
            // Reference for CheckRead Event
            _cC.CheckRead += OnCheckRead; 
        }
        catch (Exception ex)
        {
            _eldb.attachEvent("MainP", ex.Message);
        }
    }

    private void dispatcherTimer_Tick(object sender, object e)
    {
        if (!_cC.busyFlag)
        {
            Frame.Navigate(typeof(InitPage), null);
            mTimer.Stop();
        }  
    }

    public void OnCheckRead(object source, EventArgs e)
    {
        try
        {                               
            if (CComm.InBuffer == null) return; 
            _cProcTrama.ProcessTrama(CComm.InBuffer);
            CComm.InBuffer = "";                            
        }
        catch (Exception ex)
        {
            _eldb.attachEvent("OnCheckRead: ", ex.Message);
        }

    }

}

INIT Page:

public partial class InitPage : Page
{
    CComm _cC = new CComm();
    EventLogDB _eldb = new EventLogDB();
    procTrama _cProcTrama = new procTrama();

    public InitPage()
    {
        this.InitializeComponent();
        _eldb.attachEvent("S1000", "System Started.");
        // Reference for CheckRead Event
        _cC.CheckRead += OnCheckRead;
    }

    private void button_Click(object sender, RoutedEventArgs e)
    {        
        _eldb.attachEvent("S1001", "Login Activated.");
        Frame.Navigate(typeof(Page1), null);
    }

    public void OnCheckRead(object source, EventArgs e)
    {
        if (CComm.InBuffer == null) return;
        _eldb.attachEvent("OnCheckRead: ", CComm.InBuffer);
        _cProcTrama.ProcessTrama(CComm.InBuffer);
    }
}

Login Page where i more frequently the error occur:

public sealed partial class Page1 : Page
{        
    private CComm _cC = new CComm();
    private procTrama _cProcTrama = new procTrama();
    EventLogDB _eldb = new EventLogDB();

    public Page1()
    {
        this.InitializeComponent();
        // Reference for CheckRead Event
        _cC.CheckRead += OnCheckRead;
        user = null;
        pass = null;
        user_pass = 0;
    }   

    private const int userLimit = 5;
    private const int passLimit = 5;
    private const char passChar = '*';

    public string user
    {
        get; set;
    }

    public string pass
    {
        get; set;
    }

    public int user_pass
    {
        get; set;
    }

    private void execute(char val)
    {
        string aux = null;
        if (user_pass == 1)
        {
            if (user == null)
                user = val.ToString();
            else
            {
                if (user.Length <= userLimit)
                    user = user + val;
            }
            userBtn.Content = user;
        }
        else
        {
            if (user_pass == 2)
            {
                if (pass == null)
                    pass = val.ToString();
                else
                {
                    if (pass.Length <= passLimit)
                        pass = pass + val;
                }
                for (int i = 0; i < pass.Length; i++)
                    aux = aux + passChar;
                passBtn.Content = aux;
            }
        }
    }

    private void key1Btn_Click(object sender, RoutedEventArgs e)
    {
        execute('1');
    }

    private void key2Btn_Click(object sender, RoutedEventArgs e)
    {
        execute('2');
    }

    private void key3Btn_Click(object sender, RoutedEventArgs e)
    {
        execute('3');
    }

    private void key4Btn_Click(object sender, RoutedEventArgs e)
    {
        execute('4');
    }

    private void key5Btn_Click(object sender, RoutedEventArgs e)
    {
        execute('5');
    }

    private void key6Btn_Click(object sender, RoutedEventArgs e)
    {
        execute('6');
    }

    private void key7Btn_Click(object sender, RoutedEventArgs e)
    {
        execute('7');
    }

    private void key8Btn_Click(object sender, RoutedEventArgs e)
    {
        execute('8');
    }

    private void key9Btn_Click(object sender, RoutedEventArgs e)
    {
        execute('9');
    }

    private void key0Btn_Click(object sender, RoutedEventArgs e)
    {
        execute('0');
    }

    private void keyEntrarBtn_Click(object sender, RoutedEventArgs e)
    {            
        if (pass == "123" && user == "123")
        {
            _eldb.attachEvent("S1002", "User Login: " + user);
            Frame.Navigate(typeof(Page2), null);
        }               

        user_pass = 0;
        passBtn.Content = "Insirir Código";
        userBtn.Content = "Inserir Utilizador";

    }

    private void keyApagarBtn_Click(object sender, RoutedEventArgs e)
    {
        pass = null;
        user = null;
        user_pass = 0;
        passBtn.Content = "Inserir Código";
        userBtn.Content = "Inserir Utilizador";
        _eldb.attachEvent("S1003", " User data cleared.");

    }

    private void userBtn_Click(object sender, RoutedEventArgs e)
    {
        user_pass = 1;
        userBtn.Content = "";
        _eldb.attachEvent("S1004", "User button clicked.");
    }

    private void passBtn_Click(object sender, RoutedEventArgs e)
    {
        user_pass = 2;
        passBtn.Content = "";
        _eldb.attachEvent("S1005", "Pass button clicked.");
    }

    private void exitBtn_Click(object sender, RoutedEventArgs e)
    {
        _eldb.attachEvent("S1006", "Page1 exit button clicked.");
        Frame.Navigate(typeof(InitPage), null);
    }

    public void OnCheckRead(object source, EventArgs e)
    {
        try
        {
            if (CComm.InBuffer == null) return;
            _eldb.attachEvent("OnCheckRead: ", CComm.InBuffer);
            _cProcTrama.ProcessTrama(CComm.InBuffer);
        }
        catch (Exception ex)
        {
            _eldb.attachEvent("OnCheckRead: ", ex.Message);
        }

    }
}
c#
serial-port
uwp
usb
windows-10-iot-core
asked on Stack Overflow Apr 18, 2017 by Nuno Santos • edited Apr 20, 2017 by Nuno Santos

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0