c# - leer - serial readline arduino
C#SerialPort: ReadLine no funciona (1)
Tengo problemas para leer la entrada de un puerto serie en C #. El dispositivo, que está conectado a través de USB, es un ELM327-Chip para leer el puerto OBD del automóvil.
Mi código consta de dos hilos: Un hilo de escritura y uno de lectura. Se parece a lo siguiente:
static volatile SerialPort moPort;
...
moPort = new SerialPort("COM3");
moPort.BaudRate = 38400;
moPort.Parity = Parity.None;
moPort.DataBits = 8;
moPort.StopBits = StopBits.One;
moPort.NewLine = "/r";
moPort.ReadTimeout = 5000;
moPort.Open();
Hilo de escritura:
for (; ; )
{
foreach (string sPID in Car.getAvailablePIDs())
{
moPort.WriteLine("01 " + sPID);
Thread.Sleep(50);
}
}
Leer-hilo:
for (; ; )
{
string sResult;
try
{
sResult = moPort.ReadLine();
}
catch (TimeoutException)
{
return;
}
}
De esta manera mi programa está funcionando correctamente. La entrada que obtengo del dispositivo tiene el siguiente aspecto:
41 0C 00 1C/r
41 1E 00/r
>NO DATA
El problema simplemente ocurre cuando no uso la función dormir en el hilo principal. La respuesta que recibo del dispositivo se ve así:
41 0C
00 1C
/r41 1E
00/r
>NO
DATA
Ya no separa las cadenas con ''/ r'' sino que simplemente envía ... caos.
No tengo idea de qué debería hacer o si hay algún problema con mi código. Tiene alguna sugerencia?
MfG Kyle
En primer lugar: la implementación de SerialPort en C # es una mierda. Hay muchos, muchos problemas, es decir, funciona en algunos puertos emulados pero no en físicos (ninguno de los dispositivos que probamos). Recomiendo usar http://serialportstream.codeplex.com/ . Quería decírtelo primero porque desperdicié muchas lágrimas, sangre y peinados con muchos comportamientos alógicos de la clase SerialPort estándar.
Ahora, con respecto a su código, lo más importante es separar por completo la lógica de lectura y escritura. Puede escribir a su gusto, pero tenga en cuenta leer datos como en mi ejemplo a continuación
port.DataReceived += port_DataReceived;
y el manejador
private void port_DataReceived(object sender, RJCP.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
SerialPortStream sp = (SerialPortStream)sender;
if (sp.BytesToRead > 0)
{
int bytes_rx = sp.Read(buffer, 0, BYTES_MAX);
if (datacollector != null)
datacollector.InsertData(buffer, bytes_rx);
}
}
catch (Exception ex)
{
///project specific code here...
}
}