0
votes

this is a related post to my previous question regarding RS485 Data Buffer. I intended to transmit to multiple slave devices from 1 to maybe 50. current I only have 6 slaves devices setup. I am testing a transmit all routine where i have a dispatchertimer with a timespan of 10ms interval to transmit 6 bytes to data at 4800baudrate to each slave. I will start the dispatchertimer when triggered to transmit and stop the dispatchertimer after sending to the last slave device.

enter image description here I encounter error code 0x80004005 External components has thrown an exception when the second transmit all is triggered in my tx485 routine as follow;

            // Configure serial settings
            serialPort.WriteTimeout = TimeSpan.FromMilliseconds(-1);//10 //1000
            serialPort.ReadTimeout = TimeSpan.FromMilliseconds(-1);//100 //1000
            //serialPort.BaudRate = 9600;
            serialPort.BaudRate = 4800;
            serialPort.Parity = SerialParity.None;
            serialPort.StopBits = SerialStopBitCount.One;
            serialPort.DataBits = 8;
            serialPort.Handshake = SerialHandshake.None;

private async void Tx485()
    {
        if (serialPort != null)
        {


            List<byte> data = new List<byte>();

            data.Add(F5);
            data.Add(TxAdr);
            data.Add(TxCommand);
            data.Add(TxData);
            data.Add(comTxData);

            TxChkSum = 0;
            foreach (byte a in data)
            {
                TxChkSum += a;
            }

            TxChkSum = (byte)(TxChkSum - 0x80);
            data.Add(TxChkSum);

            try
            {
                // Create the DataWriter object and attach to OutputStream
                dataWriteObject = new DataWriter(serialPort.OutputStream);

                dataWriteObject.WriteBytes(data.ToArray());

                Task<UInt32> storeAsyncTask;
                // Launch an async task to complete the write operation
                storeAsyncTask = dataWriteObject.StoreAsync().AsTask();

                UInt32 bytesWritten = await storeAsyncTask;

            }
            catch (Exception ex)
            {
                MainStatusDisplay.Text = ex.Message;
            }

        }
        else
        {
            MainStatusDisplay.Text = "No UART port found";
        }
    }

Thanks.

Edited 2020-02-25

To add .. the 485 transmission is triggered by a timeschedule. Once the timescheudle is triggered ... it will transmit the on signal to all the devices and at the same time to play an audio file. once the audio file mediaended .. it will start a 2 seconds delay timer then transmit off signal again to all the devices. I do not have issue when transmitting the on signal but only when transmiting off signal during mediaended and the program.

private async void Schedule_MediaEnded(MediaPlayer sender, object args)
    {
        await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
        {
            try
            {
                scheduleEndedTxOff = true;
                commsDelay.Start();    //commsdelay delays 2 seconds before starting transmitting `OFF` signal
            } catch (Exception ex)
            {
                MainStatusDisplay.Text = ex.Message;
            }
        });
    }

private void CommsDelay_Tick(object sender, object e)
    {
        try
        {
            if (scheduleEndedTxOff)
            {
                scheduleEndedTxOff = false;
                if (allDecoderOn == true)
                {
                    commsDelay.Stop();
                    txAll = true;
                    DecoderAddress = maxDecoder;
                    allOff = true;
                    allOn = false;
                    TestTxToDecoder.IsEnabled = false;
                    commsTimer.Start();  //CommsTimer_Tick
                }
            }
        } catch (Exception ex)
        {
            MainStatusDisplay.Text = ex.Message;
        }

    }

private async void CommsTimer_Tick(object sender, object e)
    {
        if (txAll)
        {
            if (allOn)
            {
                try
                {
                    var a = DecoderAddress | 128;
                    TxAdr = Convert.ToByte(a);
                    TxCommand = TxUpdateSts;
                    TxData = 0x0F;
                    comTxData = (byte)(~TxData);
                    Tx485();
                    DecoderAddress--;

                    if (DecoderAddress == 0)
                    {
                        DecoderAddress = maxDecoder;
                        txAll = false;
                        allOn = false;
                        allOff = false;
                        allDecoderOn = true;
                        commsTimer.Stop();
                    }
                }
                catch (Exception ex)
                {
                    commsTimer.Stop();

                    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                    {
                        MainStatusDisplay.Text = ex.Message;
                    });
                }
            }

            if (allOff)
            {
                try
                {
                    var a = DecoderAddress | 128;
                    TxAdr = Convert.ToByte(a);
                    TxCommand = TxUpdateSts;
                    TxData = 0x00;
                    comTxData = (byte)(~TxData);
                    Tx485();
                    DecoderAddress--;

                    if (DecoderAddress == 0)
                    {
                        DecoderAddress = maxDecoder;
                        txAll = false;
                        allOn = false;
                        allOff = false;
                        allDecoderOn = false;
                        commsTimer.Stop();
                    }
                }
                catch (Exception ex)
                {
                    commsTimer.Stop();

                    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                    {
                        MainStatusDisplay.Text = ex.Message;
                    });
                }
            }

        }
    }

private void initCommsTimer()
    {
        commsTimer = new DispatcherTimer();
        commsTimer.Interval = TimeSpan.FromMilliseconds(10);
        commsTimer.Tick += CommsTimer_Tick;
    }

Exception thrown: 'System.IO.FileNotFoundException' in 485comms.exe WinRT information: Slave address was not acknowledged. Exception thrown: 'System.IO.FileNotFoundException' in 485comms.exe WinRT information: Slave address was not acknowledged. The thread 0x11c4 has exited with code 0 (0x0). The thread 0x11cc has exited with code 0 (0x0). The thread 0x1794 has exited with code 0 (0x0). The thread 0x12f0 has exited with code 0 (0x0). The thread 0x12e8 has exited with code 0 (0x0). The thread 0x12f8 has exited with code 0 (0x0). The thread 0x1044 has exited with code 0 (0x0). The program '[0x170C] 485comms.exe' has exited with code -1073741811 (0xc000000d).

Update: 2020-02-26 I have uploaded the sample code here. https://1drv.ms/u/s!AnzY25rC-8ZkmO1SAOGwLj28HOlKxg?e=2mOEz2

1

1 Answers

0
votes

When you update the content of the component in non-UI thread, you need to use CoreDispatcher that can be used to marshal calls coming from non-UI threads, here is your code, the DispatcherTimer in a non-UI threads.

    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        MainStatusDisplay.Text = ex.Message;
    });

Update:

When I run your project, the app crashes with error Value does not fall within the expected range.. We recommend you to add try catch to every method for troubleshooting the issue. I guess the error System.IO.FileNotFoundException caused by the audio files or other resources used in your app are missing in your solution.