COM Exception on serial port

  • Thread starter Thread starter LemonPies
  • Start date Start date
L

LemonPies

Guest
Hi!

I'm working on reading a serial port where is attached a USB/Modbus converter. I wrote the code following the official Microsoft UART example ( write and read from a serial port).

But it randomly gives me this type of exception.(first code block)

Checking on serial port I figured out that the message sent like"hello" sometimes is sent two times consequently like "hellohello" which makes out the issue.

How can I avoid it? May I need a cancellation token? Can someone give me some advice on this topic? thank you very much!


"System.Runtime.InteropServices.COMException HResult=0x800710DD Messaggio=L'identificatore di operazione non è valido. L'identificatore di operazione non è valido. Origine=Windows Analisi dello stack: at Windows.Storage.Streams.DataReader.LoadAsync(UInt32 count) at DQ61_Quanta.ModBus.<ReadAsync>d__9.MoveNext() in C:\Users\mtroplini\source\repos\DQ61_Alfa\DQ61_Quanta\ModBus.cs:line 88 at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at DQ61_Quanta.MainPage.<VisualizzaDati>d__13.MoveNext() in C:\Users\mtroplini\source\repos\DQ61_Alfa\DQ61_Quanta\MainPage.xaml.


using System;
using System.Diagnostics;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using System.Threading.Tasks;
using Windows.UI;

namespace DQ61_Quanta


{
public sealed partial class MainPage : Page
{



private ModBus modBus;
private _F03 F03;
private ProbDATA probDATA;
private IOTHub iotHUB;

private DispatcherTimer Timer;

private string Ricevuto;


#region: Inizializzo le variabili
private string NomeIoTHUB = "RaspIoTemp.azure-devices.net";
private string NomeDispositivo = "prova";
private string ChiaveDispositivo = "978ZpSN2oZgLzaljFgH3g3KE8ly0x/eFtxak+6XtKRg="; //base 64, primaria
private string ricevuto;
#endregion

public MainPage()
{
this.InitializeComponent();
AvvioTimer();
AvvioSeriale();
AvvioF03();
AvvioProb();

}

private async void MainTimer(object sender, object e)
{
try
{
if (modBus.Opened)
{
await modBus.WriteAsync();
VisualizzaDati();
}

}
catch (Exception ex)
{
Debug.WriteLine("Errore riscontrato al Timer:" + ex);
}
} //Timer Tick a 10 sec

private void AvvioTimer()
{
Timer = new DispatcherTimer();
Timer.Interval = TimeSpan.FromSeconds(10);
Timer.Tick += MainTimer;
Timer.Start();

} //avvio timer set a 10 sec


public async void VisualizzaDati()
{
if (modBus.Opened)
{
Ricevuto = await modBus.ReadAsync(1024);

if (Ricevuto != null)
{
probDATA = F03.TryParse(Ricevuto);

/** Aggiunta x Verificare elementi **/
string Id = Convert.ToString(probDATA.ID);
string Val1 = Convert.ToString(probDATA.Registro_1);
string Val2 = Convert.ToString(probDATA.Registro_2);
string Val3 = Convert.ToString(probDATA.Registro_3);
string Val4 = Convert.ToString(probDATA.Registro_4);

/** Visual. Sonde **/

if (probDATA.Registro_1 >= 25)
{
Alarm_Led.Fill = new SolidColorBrush(Colors.Red);
Sonda_1.Foreground = new SolidColorBrush(Colors.Red);
Sonda_1.Text = Val1;
}
else {Sonda_1.Text = Val1;} //Sonda 1

if (probDATA.Registro_2 >= 25)
{
Alarm_Led.Fill = new SolidColorBrush(Colors.Red);
Sonda_2.Foreground = new SolidColorBrush(Colors.Red);
Sonda_2.Text = Val2;
}
else { Sonda_2.Text = Val2; }//Sonda 2

if (probDATA.Registro_3 >= 25)
{
Alarm_Led.Fill = new SolidColorBrush(Colors.Red);
Sonda_3.Foreground = new SolidColorBrush(Colors.Red);
Sonda_3.Text = Val3;
}
else { Sonda_3.Text = Val3; }//Sonda 3

if (probDATA.Registro_4 >= 25)
{
Alarm_Led.Fill = new SolidColorBrush(Colors.Red);
Sonda_4.Foreground = new SolidColorBrush(Colors.Red);
Sonda_4.Text = Val4;
}
else { Sonda_4.Text = Val4; }//Sonda 4

}
if (iotHUB.Opened_)
{
iotHUB.InvioDati(probDATA);
}

}
} //funzione per visualizzare i dati, farci un parse, e inviarli ad iot hub



private void AvvioSeriale()
{
modBus = new ModBus();
} //inizializzo seriale


using System;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading;
using System.Threading.Tasks;
using Windows.Devices.Enumeration;
using Windows.Devices.SerialCommunication;
using Windows.Storage.Streams;

namespace DQ61_Quanta
{
class ModBus
{
private SerialDevice PortaSeriale = null; //iniz porta seriale
DataReader dataReader = null; // iniz oggetto di lettura

public bool Open; // serve per il main
public bool Opened { get { return Open; } } // funzione per richiamare il valore di Open

private CancellationTokenSource ReadCancellationTokenSource; //token inizializzato

private DeviceInformationCollection DeviceInformationCollection; //device Info inizializzato

public async Task ConnectCOM()
{
Open = false;

//selezione ID porta automatico **** da testare se funziona con due seriali collegati
string aqs = SerialDevice.GetDeviceSelector();
DeviceInformationCollection = await DeviceInformation.FindAllAsync(aqs);
DeviceInformation selectedDevice = DeviceInformationCollection[0];

PortaSeriale = await SerialDevice.FromIdAsync(selectedDevice.Id);

//settaggio parametri MODBUS RS485 RTU 19200-8bit-parità-1stopBit
PortaSeriale.WriteTimeout = TimeSpan.FromMilliseconds(1000);
PortaSeriale.ReadTimeout = TimeSpan.FromMilliseconds(1000);
PortaSeriale.BaudRate = 19200;
PortaSeriale.Parity = SerialParity.Even;
PortaSeriale.StopBits = SerialStopBitCount.One;
PortaSeriale.DataBits = 8;
PortaSeriale.Handshake = SerialHandshake.None;

ReadCancellationTokenSource = new CancellationTokenSource(); //token funzioni I/O


if (PortaSeriale != null)
{
Open = true; //parametro che mi serve nel main frame
dataReader = new DataReader(PortaSeriale.InputStream); //apertura alla lettura dello stream
}



} //connessione alla porta COM del MODBUS RS485 RTU

public async Task WriteAsync()
{
DataWriter dataWriter = new DataWriter(PortaSeriale.OutputStream);

#region: conversione in hex
string Funzione03 = "0x01 0x03 0x80 0x01 0x00 0x04 0x3C 0x09";

// Spezzo Array negli spazzi //converto in byte base 16// Passo ad array
byte[] bytes = Funzione03.Split(' ').Select(item => Convert.ToByte(item, 16)).ToArray();

// Converto in Hexadecimal, formato invio "01-03-80-... ecc"
// string HexMessage = string.Join("-", bytes.Select(item => item.ToString("X2"))); ma serve? XD
#endregion

// standard per scrittura dati al seriale collegando e scollegando il buffer
dataWriter.WriteBytes(bytes);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
dataWriter = null;

} //scrittura asincrona sul buffer della porta COM

public async Task<string> ReadAsync(uint ReadBufferLength)
{
Task<UInt32> loadAsyncTask;
byte[] ByteLettura = null;

// Set InputStreamOptions per completare la lettura asincrona di 1 o + byte
dataReader.InputStreamOptions = InputStreamOptions.Partial;

// creazione task per aspettare dati alla serialPort.InputStream
loadAsyncTask = dataReader.LoadAsync(ReadBufferLength).AsTask();

UInt32 bytesRead = await loadAsyncTask; //base 32bit

if (bytesRead > 0) //se leggi byte, convertili in Hexadecimal
{
#region: conversione in hex
ByteLettura = dataReader.ReadBuffer(bytesRead).ToArray();
string HexMessage = string.Join("-", ByteLettura.Select(item => item.ToString("X2")));
#endregion
return HexMessage;
}
return $""; //ritorna nulla se i byte letti sono vuoti
}

Continue reading...
 
Back
Top