serialport serial read leer c# serial-port thread-safety

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