visual studio serialport serial application c# winapi serial-port ioexception baud-rate

c# - studio - wpf serialport



Error de excepción de IO al usar serialport.open() (5)

Esto viene del controlador del puerto serie, no está contento con una de las configuraciones. Dado que la velocidad en baudios es un buen candidato, los conductores tienden a permitir solo hasta 115200. Aunque esto no debería ser una restricción cuando se trata de un producto de bus CAN dedicado.

La mejor manera de abordar esto es mediante la utilidad PortMon de SysInternals, puede ver qué se envía al controlador. Obsérvelo para Terminar primero, esa es su línea de base conocida para trabajar. Luego, pruebe las propiedades de SerialPort hasta que los comandos de inicialización, como los ve en PortMon, enviados por su programa coincidan con los de Termite. Sólo los valores, no el orden. Si eso tampoco funciona, llévelo al estacionamiento y vuélvalo a colocar con su automóvil varias veces y compre otra marca.

Actualización: ciertamente parece un problema de baudrate. Eso es un problema en .NET, no va a ignorar el código de retorno de error del controlador como lo hacen los programas de emulador de terminal. El valor real no debería importar ya que está hablando con un puerto serie emulado . Sin embargo, existe un posible problema con la velocidad del bus CAN, las tarifas son variables y no me queda claro cómo se negocian. Esto solía hacerse con los interruptores DIP en los días anteriores, puede ser que el conductor desee que especifique la velocidad a través de la configuración de velocidad en baudios. Debería haber algo al respecto en la caja o en el manual. Las velocidades típicas son 40, 250 o 500 Kbps. El fabricante sin duda lo sabría, llámalos.

ACTUALIZACIÓN FINAL Era nuestro firmware todo el tiempo. Avergonzado hasta cierto punto, pero estoy contento de que podamos avanzar y puedo dejar de aprender Java para otro día. Mi respuesta está abajo.

ACTUALIZACIÓN Así que más o menos me he dado por vencido en esto. Creo que es un error que se reduce a la API, pero no tengo ni el tiempo ni los recursos ni las habilidades para llegar al fondo. Creo que existe algún hardware a quien Windows solo le da el dedo medio. Descargué Eclipse, cambié a Java e intentaré ver si funciona. Si no, me verás de vuelta aquí. Sin embargo, me encantaría resolver esto y, por lo tanto, si alguien tiene el tiempo o la inclinación para profundizar en esto, me encantaría ver lo que se te ocurre. Obviamente volveré aquí de vez en cuando. Por favor, asegúrate de incluirme en tus comentarios para que esté alerta.

POSTE ORIGINAL

Sé que hay algunas otras personas que se ocupan de este problema, pero esperaba que alguien pudiera ayudarme. Estoy intentando conectarme a un puerto COM, pero serialport.Open() una excepción de IO cuando intento usar el serialport.Open() :

System.IO.IOException: The parameter is incorrect. at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str) at System.IO.Ports.InternalResources.WinIOError() at System.IO.Ports.SerialStream.InitializeDCB(Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Boolean discardNull) at System.IO.Ports.SerialStream..ctor(String portName, Int32 baudRate, Parity parity, Int32 dataBits, StopBits stopBits, Int32 readTimeout, Int32 writeTimeout, Handshake handshake, Boolean dtrEnable, Boolean rtsEnable, Boolean discardNull, Byte parityReplace) at System.IO.Ports.SerialPort.Open() at *programtitlehere.cs*:line 90

Estoy utilizando un Stellaris LM4F232 para emular un puerto COM. Puedo abrir, acceder y obtener buenos resultados utilizando Termite (un programa de terminal), pero cada vez que intento con Visual Studio, ni siquiera se conecta y aparece este error. Ahora ni siquiera sé qué significa este error y, a pesar de intentar leer en otro lugar, todavía me siento perdido.

¿Alguien puede explicarme lo que está pasando aquí y tal vez pueda comenzar a tratar de resolver esto? Puedo incluir más código, pero para ser honesto, no hay mucho allí; Todas las propiedades del dispositivo serialport son normales, y solo ocurre con este dispositivo (puedo usar un MSP430 sin problemas con los mismos detalles).

Mi código se muestra a continuación para las personas que desean verlo (tenga en cuenta que esto es solo un "cajón de arena", no el programa real, pero los síntomas son idénticos):

try { serialPort1.PortName = "COM5"; serialPort1.Open(); if (serialPort1.IsOpen == true) { textBox1.Text = "CONNECTED"; } else { textBox1.Text = "NOT CONNECTED"; } } catch (Exception ex) { MessageBox.Show("Error: " + ex.ToString(), "ERROR"); }

y las otras configuraciones se realizan con el administrador de propiedades (solo la diferencia es que baudios está establecido en 230400, todos los demás están en su valor predeterminado). Puedo abrir COM4 con este (un MSP430) que para todos los propósitos es un dispositivo idéntico. Puedo abrir COM5 con Termite, así que sé que la conexión es buena). Y no, no estoy intentando abrirlos al mismo tiempo. Si necesita más información, hágamelo saber y puedo publicar más.

¡Gracias!

EDIT: Estoy en el tercer día de tratar de resolver esto y todavía no tengo suerte. Realmente no entiendo por qué puedo acceder a este COM a través de un programa terminal y no al mío cuando, tan cerca como puedo ver, no hay absolutamente ninguna diferencia. ¿Alguien sabe de un programa que pueda "examinar" un puerto COM para ver sus propiedades (además del administrador de Windows, quiero decir)? Me estoy frustrando bastante y estoy como parado en mi proyecto hasta que descubro esto ...

EDIT2: He encontrado una solución aparente, pero todavía tengo que hacer que funcione here . Ahora recibo algunos errores de E / S diferentes, pero al menos es movimiento (no estoy seguro si es progreso). También aprendí que esto es un error de .NET, que ha existido desde 2.0. Todavía me encantaría cualquier ayuda, pero si lo descubro, informaré. El código de Zach (la solución enlazada arriba) se muestra a continuación:

using System; using System.IO; using System.IO.Ports; using System.Runtime.InteropServices; using System.Text; using Microsoft.Win32.SafeHandles; namespace SerialPortTester { public class SerialPortFixer : IDisposable { public static void Execute(string portName) { using (new SerialPortFixer(portName)) { } } #region IDisposable Members public void Dispose() { if (m_Handle != null) { m_Handle.Close(); m_Handle = null; } } #endregion #region Implementation private const int DcbFlagAbortOnError = 14; private const int CommStateRetries = 10; private SafeFileHandle m_Handle; private SerialPortFixer(string portName) { const int dwFlagsAndAttributes = 0x40000000; const int dwAccess = unchecked((int) 0xC0000000); if ((portName == null) || !portName.StartsWith("COM", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException("Invalid Serial Port", "portName"); } SafeFileHandle hFile = CreateFile(@"//./" + portName, dwAccess, 0, IntPtr.Zero, 3, dwFlagsAndAttributes, IntPtr.Zero); if (hFile.IsInvalid) { WinIoError(); } try { int fileType = GetFileType(hFile); if ((fileType != 2) && (fileType != 0)) { throw new ArgumentException("Invalid Serial Port", "portName"); } m_Handle = hFile; InitializeDcb(); } catch { hFile.Close(); m_Handle = null; throw; } } [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int FormatMessage(int dwFlags, HandleRef lpSource, int dwMessageId, int dwLanguageId, StringBuilder lpBuffer, int nSize, IntPtr arguments); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool GetCommState(SafeFileHandle hFile, ref Dcb lpDcb); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool SetCommState(SafeFileHandle hFile, ref Dcb lpDcb); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool ClearCommError(SafeFileHandle hFile, ref int lpErrors, ref Comstat lpStat); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, IntPtr securityAttrs, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile); [DllImport("kernel32.dll", SetLastError = true)] private static extern int GetFileType(SafeFileHandle hFile); private void InitializeDcb() { Dcb dcb = new Dcb(); GetCommStateNative(ref dcb); dcb.Flags &= ~(1u << DcbFlagAbortOnError); SetCommStateNative(ref dcb); } private static string GetMessage(int errorCode) { StringBuilder lpBuffer = new StringBuilder(0x200); if ( FormatMessage(0x3200, new HandleRef(null, IntPtr.Zero), errorCode, 0, lpBuffer, lpBuffer.Capacity, IntPtr.Zero) != 0) { return lpBuffer.ToString(); } return "Unknown Error"; } private static int MakeHrFromErrorCode(int errorCode) { return (int) (0x80070000 | (uint) errorCode); } private static void WinIoError() { int errorCode = Marshal.GetLastWin32Error(); throw new IOException(GetMessage(errorCode), MakeHrFromErrorCode(errorCode)); } private void GetCommStateNative(ref Dcb lpDcb) { int commErrors = 0; Comstat comStat = new Comstat(); for (int i = 0; i < CommStateRetries; i++) { if (!ClearCommError(m_Handle, ref commErrors, ref comStat)) { WinIoError(); } if (GetCommState(m_Handle, ref lpDcb)) { break; } if (i == CommStateRetries - 1) { WinIoError(); } } } private void SetCommStateNative(ref Dcb lpDcb) { int commErrors = 0; Comstat comStat = new Comstat(); for (int i = 0; i < CommStateRetries; i++) { if (!ClearCommError(m_Handle, ref commErrors, ref comStat)) { WinIoError(); } if (SetCommState(m_Handle, ref lpDcb)) { break; } if (i == CommStateRetries - 1) { WinIoError(); } } } #region Nested type: COMSTAT [StructLayout(LayoutKind.Sequential)] private struct Comstat { public readonly uint Flags; public readonly uint cbInQue; public readonly uint cbOutQue; } #endregion #region Nested type: DCB [StructLayout(LayoutKind.Sequential)] private struct Dcb { public readonly uint DCBlength; public readonly uint BaudRate; public uint Flags; public readonly ushort wReserved; public readonly ushort XonLim; public readonly ushort XoffLim; public readonly byte ByteSize; public readonly byte Parity; public readonly byte StopBits; public readonly byte XonChar; public readonly byte XoffChar; public readonly byte ErrorChar; public readonly byte EofChar; public readonly byte EvtChar; public readonly ushort wReserved1; } #endregion #endregion } internal class Program { private static void Main(string[] args) { SerialPortFixer.Execute("COM1"); using (SerialPort port = new SerialPort("COM1")) { port.Write("test"); } } } }

EDIT3: Día 6: Todavía estoy desconectado de esto. Mis raciones de agua son bajas pero todavía sigo luchando. Siento que la ayuda seguramente debe estar en el horizonte. Quien encuentre este diario, trae mis restos a Canadá y encuentra a Nicole. Dile que la amo.

Pero en serio, no tengo idea de qué está causando este problema. Me pregunto si está puramente en el lado incrustado; tal vez porque es USB-to-go, o porque el dispositivo también puede ser un host. ¿Alguien se ha encontrado con ese problema? Sin embargo, no explica por qué puedo usar Termite (un programa de terminal, para aquellos espectadores que se unen a nosotros). He estado tratando de encontrar un programa de terminal de código abierto que a) funcione yb) vea a). Como de costumbre, informaré si descubro el problema aquí, ya que ahora he encontrado innumerables foros en los que parece que las personas han tenido este problema desde 2006.

EDIT4: De acuerdo con los consejos dados, descargué una aplicación de software de monitoreo de puertos (obtuve el Monitor de puerto serial de Eltima) y parece un problema de baudios:

Pero extrañamente no importa qué baudios lo coloque, todavía falla. ¿Y también puede alguien explicar lo que significa arriba / abajo? Intenté googlearlo pero las palabras clave son demasiado generales. Como de costumbre, seguiré informando cualquier cambio.

Además, para que quede constancia, puedo conectarme usando Eltima a una velocidad de 115200 (igual que Termite). Desafortunadamente esto no funciona en Visual Studio.

EDIT5: Nuestra trama toma un giro sorpresa. Estaba monitoreando lo que sucede cuando Termite se conecta al puerto COM en cuestión y BLAM! La termita lanza exactamente el mismo error que mi programa, pero lo ignora . Genio, ¿verdad? Sloppy, pero funciona. Ahora necesito aprender a ignorar las IOExceptions. Voy a informar de nuevo cuando lo tengo resuelto.

EDIT6: Así que resulta que es un problema de velocidad de transmisión, pero va más allá. He estado usando el software Eltima Serial Port Monitoring y es muy intuitivo y fácil de usar. Yo lo recomendaría. Después de algunas investigaciones , he aprendido que no puede ignorar esta excepción y aún así conectarse al puerto serie utilizando la biblioteca .NET. Así que tengo que profundizar en la API de Win32 y escribir la mía. He encontrado algunas páginas que tocan esto, pero, para ser honesto, nunca he hecho algo como esto antes, así que puede pasar un tiempo antes de informar, pero definitivamente lo resolveré y volveré con todos. Hay demasiados que sufren de este problema. He encontrado bastantes foros y sitios web donde puedo ver exactamente los mismos síntomas, pero nadie realmente ha hecho mucho, además de decir ''Sí, .NET apesta''. Planeo escribir una clase de biblioteca estática completa y luego publicar en mi sitio web, aquí y en cualquier otro lugar que pueda. Con suerte .NET tomará nota (este error ha existido desde 2.0). Voy a informar de nuevo cuando esté hecho!

EDIT7: Esto es mucho más difícil de lo que pensé que sería.

EDIT 8: No sé si alguien está siguiendo esto o no, pero quería decir que todavía estoy en eso, pero estoy fuera de la ciudad por una semana en un viaje de negocios. ¡Todavía estoy feliz de escuchar sugerencias e ideas alternativas!


Me encontré con la misma situación. Estoy intentando conectar la comunicación en serie a mi Dongle USB 3G (Huawei E303F) en / dev / ttyUSB0. Yo uso mono en Raspbian (raspberry-pi2). En mi PC de desarrollo y macOS, mi programa funciona bien. Pero cuando lo implemento en Raspbian, recibí el error IOException Broken Pipe en Serial.Open ().

Tomé mis tres días de depuración y probé todas las soluciones posibles. Finalmente encontré que tengo que configurar ...

serialPort.DtrEnable = true; serialPort.RtsEnable = true;

Antes de las llamadas .Abrir (). Espero que esto pueda ayudar a otras personas que enfrentan el mismo problema que el mío.


Me enfrento a un problema similar como se informa en este hilo, ¡pero logré resolver el problema!

Estoy usando STM32F2xx para el VCP!

Y, de hecho, es mi problema de firmware. ¡Olvidé incluir la configuración del puerto serie en mi devolución de llamada USB!

El proceso de conexión del puerto serie desde PC y firmware:

  1. Cuando una PC abre una comunicación de puerto serie, la PC enviará algún comando al "punto final de configuración"
  2. En el firmware, tendría una devolución de llamada y el firmware proporcionará toda la información de USB (lo llaman descriptor de USB)
  3. La información del USB es la configuración de cada punto final (por ejemplo, latencia, transmisión de tamaño de datos, tipo de USB - alta velocidad o baja velocidad)
  4. Una vez que el firmware haya completado el envío de toda la información, la PC lo reconocerá y la comunicación USB se abrirá con éxito
  5. Luego, la PC enviará el comando para obtener la configuración del puerto serie del firmware
  6. Los ajustes del puerto serie son: velocidad en baudios, paridad de datos, longitud de bits
  7. En el firmware, debería devolver la configuración del puerto serie a la PC ( mi error se produce aquí, no respondo ninguna configuración del puerto serie a la PC )
  8. Si tiene éxito, la PC iniciará la comunicación del puerto serie!
  9. Si falla, la PC dará un error de puerto serie abierto (pero, tenga en cuenta que este error a veces se omite)

En el código de firmware STM32:

static int8_t CDC_Control_FS (uint8_t cmd, uint8_t* pbuf, uint16_t length) { switch (cmd) { case CDC_GET_LINE_CODING: { //I was missing this part uint32_t baudrate = 9600; pbuf[0] = (uint8_t)(baudrate); pbuf[1] = (uint8_t)(baudrate >> 8); pbuf[2] = (uint8_t)(baudrate >> 16); pbuf[3] = (uint8_t)(baudrate >> 24); pbuf[4] = 0; pbuf[5] = 0; pbuf[6] = 8; break; }: ....


Tuve el mismo problema y configurando la tasa de baudios a 1 lo solucioné!


Y así, nuestra emocionante historia llega a su fin. Fue firmware todo el tiempo (es decir, el código en el dispositivo integrado). Cambiamos algunas funciones y esencialmente buscamos, cortamos, añadimos y limpiamos el código y listo, el código está funcionando. Esta foto lo resume bastante bien. Maldito sea el firmware !!

Sin embargo, el error descrito en mi (extensa) pregunta aún persiste en muchas personas y sé que hay muchas personas que todavía lo tienen. Todo lo que puedo decir es buena suerte y verifique cuádruple su firmware (al parecer, la comprobación triple no es suficiente en estos días).