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...
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...