elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Curso de javascript por TickTack


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Usar read en entrada de datos
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Usar read en entrada de datos  (Leído 6,970 veces)
Meta


Desconectado Desconectado

Mensajes: 3.501



Ver Perfil WWW
Usar read en entrada de datos
« en: 1 Diciembre 2023, 22:27 pm »

Una consulta.

A partir de la S en el delimitador indicado abajo.

Código
  1. string entrada = "#I225.7O226.2L006B100V25.7F50.2H50.2R0080S€„€ˆ„\r";


Concretamente esto de abajo.
Código
  1. S€„€ˆ„\r

Más aún el:
Código
  1. €„€ˆ„

En realidad es un binario mezclado con caracteres tipo string del principio. Por muy encoder que use el ponerlo en un Windows Form siempre me suelta 63 en decimal.

Código
  1.            foreach (uint b in Encoding.Default.GetBytes(salida[8]))
  2.            {
  3.                //richTextBox1.Text += b.ToString();
  4.                richTextBox1.Text += Environment.NewLine; // Nueva línea.
  5.                richTextBox1.Text += $"Array: {numeros[j] = b}";
  6.                ++j;
  7.            }

Ya que al capturar datos en el puerto serie lo almaceno tipo String.

Parece ser que es mejor optar por almacenar los datos o tramas de bytes que llegan desde el puerto serie en tipo byte[] y usar read.

Uso el protocolo este para el puerto serie.
Código
  1.                puertoSerie = new SerialPort()
  2.                {
  3.                    // Configuración del puerto serie.
  4.                    PortName = "COM3",           // Nombre del puerto serie.
  5.                    BaudRate = 2400,             // Velocidad en baudios.
  6.                    Parity = Parity.None,        // Esquema para comprobar la paridad de cada byte recibido.
  7.                    StopBits = StopBits.One,     // Número de bits de parada por byte.
  8.                    DataBits = 8,                // Número de bits de datos por byte.
  9.                    Handshake = Handshake.None,  // Protocolo de establecimiento.
  10.                    DtrEnable = true,            // Línea de terminal de datos.
  11.                    RtsEnable = true,            // Línea de solicitud.
  12.  
  13.                    // Establecer los tiempos de espera de lectura / escritura.
  14.                    ReadTimeout = 500,           // Tiempo de espera de escritura en ms.
  15.                    WriteTimeout = 500,          // Tiempo de espera de escritura en ms.
  16.  
  17.                    // Más configuraciones.
  18.                    DiscardNull = false,         // Descartar bytes nulos recibidos.
  19.                    ParityReplace = 63,
  20.                    ReadBufferSize = 4096,
  21.                    WriteBufferSize = 2018,
  22.                    ReceivedBytesThreshold = 1
  23.                };

A la hora de recibir datos, mejor obtener ***** bytes sin formato, tal como vienen y almacenarlo.

¿Cuál es la mejor forma para almacenar datos en un array de bytes?

Ya que luego la parte de la S, quiero mostrarlo en decimal para luego verlo en binario.

Saludos.


En línea

Meta


Desconectado Desconectado

Mensajes: 3.501



Ver Perfil WWW
Re: Usar read en entrada de datos
« Respuesta #1 en: 2 Diciembre 2023, 11:12 am »

Buenas:

Todavía sigo chamusqueándome las neuronas.

Teniendo estos resultados que viene tipo string, lo convierto en hexadecimal y en binario con Windows Form.
Citar
#I223.4O223.6L007B100V26.0F50.2H50.2R0080S??????

23493232332E344F3232332E364C303037423130305632362E304635302E324835302E325230303830533F3F3F3F3F3F0D

1000111001001110010110010110011101110110100100111111001011001011001110111011011010011001100001100001101111000010110001110000110000101011011001011011010111011000010001101101011100001011101100101001000110101110000101110110010101001011000011000011100011000010100111111111111111111111111111111111111111101

¿Cómo se puede capturar los datos exactamente sin editar tal como se recibieron tal como si se muestra abajo?

Precisamente son estos:
35 73 50 50 51 46 52 79 50 50 52 46 50 76 48 48 55 66 49 48 48 86 50 54 46 48 7
0 53 48 46 49 72 53 48 46 49 82 48 48 56 48 83 144 132 128 136 132 192 13

Ver imagen con un terminal que si lo hace.

Ver zoom.

Lo marcado en rojo arriba es justo lo que quiero meter en un array para luego mostrarlo uno a uno en Windows form con su label correspondiente.

Espero que así se entienda mejor.

Código hecho en Windows Form en C# es este:
Código
  1. private void Actualizar(object sender, EventArgs e)
  2. {
  3.  
  4.    // Asignar el valor de la trama al richTextBox.
  5.    richTextBox1.Text += recibidos;
  6.    // Nueva línea.
  7.    richTextBox1.Text += Environment.NewLine;
  8.  
  9.    // Pasar a hexadecimal.
  10.    //foreach (byte b in recibidos)
  11.    foreach (byte b in recibidos.Select(v => (byte)v))
  12.    {
  13.        // x = minúscula, X = mayúscula.
  14.        richTextBox1.Text += b.ToString("X2");
  15.    }
  16.  
  17.    // Nueva línea.
  18.    richTextBox1.Text += Environment.NewLine;
  19.    richTextBox1.Text += Environment.NewLine;
  20.  
  21.    // Pasar a binario.
  22.    foreach (string leer in recibidos.Select(c => Convert.ToString(c, 2)))
  23.    {
  24.        richTextBox1.Text += leer.ToString();
  25.    }
  26.  
  27.    // Nueva línea.
  28.    richTextBox1.Text += Environment.NewLine;
  29.    richTextBox1.Text += Environment.NewLine;
  30.  
  31.    // Selecciona la posición final para leer los mensajes entrantes.
  32.    richTextBox1.SelectionStart = richTextBox1.Text.Length;
  33.  
  34.    // Mantiene el scroll en la entrada de cada mensaje.
  35.    richTextBox1.ScrollToCaret();
  36.  
  37.    // Limpiar.
  38.    recibidos = "";
  39. }

¿Alguna idea?

Saludos.


« Última modificación: 2 Diciembre 2023, 11:15 am por Meta » En línea

Meta


Desconectado Desconectado

Mensajes: 3.501



Ver Perfil WWW
Re: Usar read en entrada de datos
« Respuesta #2 en: 2 Diciembre 2023, 13:41 pm »

Al final se hace así:

Código
  1.            foreach (byte elemento in recibidos)
  2.            {
  3.                richTextBox1.Text += Convert.ToDecimal(elemento);
  4.            }

Cuyo resultado no es el esperado.

Me da esto:
35735049574657795050484655764849496649484886505446487053484650725348465082484851568363636363636313

El 83 es la S y el 13 es este \r, entre medio hay seis veces el 63, que no debería mostrar porque la conversión está mal, no es el real, el real es el que indiqué antes.
35 73 50 50 51 46 52 79 50 50 52 46 50 76 48 48 55 66 49 48 48 86 50 54 46 48 7
0 53 48 46 49 72 53 48 46 49 82 48 48 56 48 83 144 132 128 136 132 192 13

Se ve que a la hora de recibir datos uso esta variable tipo string.
Código
  1. string recibidos;

Por lo que se ve, no es el adecuado cuando quieres los byte tal cual vienen sin modificar o usar encoder.

Parece ser que la mejor manera es usar una array o matriz como esta:
byte[] = cadenaByte;

En línea

EdePC
Moderador Global
***
Desconectado Desconectado

Mensajes: 2.162



Ver Perfil
Re: Usar read en entrada de datos
« Respuesta #3 en: 2 Diciembre 2023, 22:49 pm »

Cuidado con las codificaciones, los datos reales serán bytes, si a alguno de esos bytes los conviertes a char o string dependerá de la codificación en turno como se hará la conversión y como se hará la visualización, ahí tienes esos dos problemas.

Supuestamente los caracteres problemáticos son 5: €„€ˆ„ pero incluso en la salida que consideras correcta salen 6: 144 132 128 136 132 192 y si las miras bien verás que no encaja con los caracteres que se repiten, así que tampoco es la correcta.

Citar
Parece ser que es mejor optar por almacenar los datos o tramas de bytes que llegan desde el puerto serie en tipo byte[] y usar read.

No sé como estás guardando los datos así que supondré que estás usando puertoSerie.ReadChar(), puertoSerie.ReadLine(), o similar, estos trabajan y convierten basándose en la codificación y por lo tanto habrán cambios si no lo tienes controlado. Si usas puertoSerie.ReadByte() si conseguirás los bytes reales pero para visualizarlos debes usar una codificación adecuada igual o similar a la empleada para representar esos bytes.

Por ejemplo si tienes el decimal 128 y lo quieres mostrar usando codificación ANSI obtendrás: €, pero si usas ASCII obtienes ? (63) porque no existe en la tabla ASCII

Si haces la lectura con ReadByte() y luego cada byte lo pasas a Int no deberías tener problemas salvo la cantidad de bytes que dependerá de la codificación
En línea

Meta


Desconectado Desconectado

Mensajes: 3.501



Ver Perfil WWW
Re: Usar read en entrada de datos
« Respuesta #4 en: 3 Diciembre 2023, 08:07 am »

Buenas.

Lo estaba guardado los bytes en tipo string.

Como indicas, mejor usar sin codificación alguna los bytes recibidos para ternerlo tal cual. Se ve que la mejor opción para recibir los bytes tal cual natural es usando lo que dijiste.

Código
  1. ReadByte()
https://learn.microsoft.com/es-es/dotnet/api/system.io.ports.serialport.readbyte?view=dotnet-plat-ext-8.0&viewFallbackFrom=net-6.0
https://learn.microsoft.com/es-es/dotnet/api/system.io.filestream.readbyte?view=net-6.0

https://learn.microsoft.com/es-es/dotnet/api/system.runtime.interopservices.marshal.readbyte?view=net-6.0


El que estaba usando es este.
https://learn.microsoft.com/es-es/dotnet/api/system.io.ports.serialport.readexisting?view=dotnet-plat-ext-8.0&viewFallbackFrom=net-6.0

No parece ser el más adecuado por lo que se ve.

Estoy gracias a ti, que estos códigos, pero quiero leer bien la parte S y mostrarlo todos los datos en decimal de la trama de bytes que vienen el puerto tal cual. Lo hace bien el RealTerm como se mostró en la imagen de arriba.

Código
  1. using System.IO.Ports;
  2. using System.Text;
  3.  
  4. namespace Termite_SAI_05_.NET_8._0
  5. {
  6.    public partial class Form1 : Form
  7.    {
  8.        SerialPort puertoSerie;
  9.        bool verComandoBFlag = false;
  10.        bool verComandoX72Flag = false;
  11.        bool verComandoX5Flag = false;
  12.        const string COMANDO_B = "B\r";
  13.        const string COMANDO_X72 = "X72\r";
  14.        const string COMANDO_X5 = "X5\r";
  15.  
  16.        public Form1()
  17.        {
  18.            InitializeComponent();
  19.            InicioPuertoSerie();
  20.        }
  21.        private void Form1_Load(object sender, EventArgs e)
  22.        {
  23.            //timer1.Start();
  24.            timer1.Enabled = true;
  25.        }
  26.        /* Iniciar y configurar el puerto serie */
  27.        private void InicioPuertoSerie()
  28.        {
  29.            try
  30.            {
  31.                puertoSerie = new SerialPort()
  32.                {
  33.                    // Configuración del puerto serie.
  34.                    PortName = "COM3",           // Nombre del puerto serie.
  35.                    BaudRate = 2400,             // Velocidad en baudios.
  36.                    Parity = Parity.None,        // Esquema para comprobar la paridad de cada byte recibido.
  37.                    StopBits = StopBits.One,     // Número de bits de parada por byte.
  38.                    DataBits = 8,                // Número de bits de datos por byte.
  39.                    Handshake = Handshake.None,  // Protocolo de establecimiento.
  40.                    DtrEnable = true,            // Línea de terminal de datos.
  41.                    RtsEnable = true,            // Línea de solicitud.
  42.  
  43.                    // Establecer los tiempos de espera de lectura / escritura.
  44.                    ReadTimeout = 500,           // Tiempo de espera de escritura en ms.
  45.                    WriteTimeout = 500,          // Tiempo de espera de escritura en ms.
  46.  
  47.                    // Más configuraciones.
  48.                    DiscardNull = false,         // Descartar bytes nulos recibidos.
  49.                    ParityReplace = 63,          // Reemplaza los bytes recibidos con errores de paridad.
  50.                    ReadBufferSize = 4096,       // Tamaño del búfer de lectura en bytes.
  51.                    WriteBufferSize = 2018,      // Tamaño del búfer de escritura en bytes.
  52.                    ReceivedBytesThreshold = 1   // Número de bytes que se necesitan.
  53.                };
  54.  
  55.                // Abrir puerto serie.
  56.                puertoSerie.Open();
  57.  
  58.                // Subscribir el evento DatosRecividos cuando lleguen datos.
  59.                puertoSerie.DataReceived += DatosRecibidos;
  60.            }
  61.            catch (Exception ex)
  62.            {
  63.                MessageBox.Show(ex.Message, "Aviso",
  64.                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
  65.                timer1.Stop();
  66.                puertoSerie.Close(); // Cierra el puerto en caso de error
  67.  
  68.            }
  69.        }
  70.  
  71.        /* Evento para leer asíncronamente datos del puerto serie */
  72.        void DatosRecibidos(object sender, SerialDataReceivedEventArgs e)
  73.        {
  74.            Task.Run(async () =>
  75.            {
  76.                try
  77.                {
  78.                    await Task.Delay(500); // Pausa para recibir datos
  79.                    string cadena = puertoSerie.ReadExisting();
  80.                    if (!string.IsNullOrEmpty(cadena))
  81.                    {
  82.                        if (verComandoBFlag == true) { ProcesoCOMANDO_B(cadena); }
  83.                        if (verComandoX72Flag) { ProcesoCOMANDO_X72(cadena); }
  84.                        if (verComandoX5Flag) { ProcesoCOMANDO_X5(cadena); }
  85.                    }
  86.                    else
  87.                    {
  88.                        Console.Write("Datos leídos corruptos.");
  89.                    }
  90.                }
  91.                catch (IndexOutOfRangeException ex)
  92.                {
  93.                    Console.Write("Índice fuera de los límites de la matriz.");
  94.                    MessageBox.Show(ex.Message);
  95.                }
  96.                catch (FormatException ex)
  97.                {
  98.                    Console.Write("La cadena de entrada no tiene el formato correcto.");
  99.                    MessageBox.Show(ex.Message, "Error");
  100.                }
  101.            });
  102.        }
  103.  
  104.        /* Procesar COMANDO_X5 */
  105.        private void ProcesoCOMANDO_X5(string cadena)
  106.        {
  107.            verComandoX5Flag = false;
  108.            char[] separadores = { '#', ',', '\r' };
  109.            string[] salida = cadena.Split(separadores, StringSplitOptions.RemoveEmptyEntries);
  110.  
  111.            // Al manipular controles de Windows Forms desde un hilo diferente al
  112.            // hilo de la interfaz de usuario, es necesario usar Invoke para evitar problemas de concurrencia.
  113.            if (InvokeRequired)
  114.            {
  115.                Invoke(new Action(() =>
  116.                {
  117.                    ActualizarUIControlComandoX5(salida);
  118.                }));
  119.            }
  120.            else
  121.            {
  122.                ActualizarUIControlComandoX5(salida);
  123.            }
  124.        }
  125.  
  126.        /* Procesar COMANDO_X72 */
  127.        private void ProcesoCOMANDO_X72(string str)
  128.        {
  129.            verComandoX72Flag = false;
  130.            char[] separadores = { '#', ',', '\r' };
  131.            string[] salida = str.Split(separadores, StringSplitOptions.RemoveEmptyEntries);
  132.  
  133.            // Al manipular controles de Windows Forms desde un hilo diferente al
  134.            // hilo de la interfaz de usuario, es necesario usar Invoke para evitar problemas de concurrencia.
  135.            if (InvokeRequired)
  136.            {
  137.                Invoke(new Action(() =>
  138.                {
  139.                    ActualizarUIControlComandoX72(salida);
  140.                }));
  141.            }
  142.            else
  143.            {
  144.                ActualizarUIControlComandoX72(salida);
  145.            }
  146.        }
  147.  
  148.        /* Procesar COMANDO_B */
  149.        private void ProcesoCOMANDO_B(string str)
  150.        {
  151.            verComandoBFlag = false;
  152.            char[] separadores = { '#', 'I', 'O', 'L', 'B', 'V', 'F', 'H', 'R', 'S', '\r' };
  153.            string[] salida = str.Split(separadores, StringSplitOptions.RemoveEmptyEntries);
  154.  
  155.            // Al manipular controles de Windows Forms desde un hilo diferente al
  156.            // hilo de la interfaz de usuario, es necesario usar Invoke para evitar problemas de concurrencia
  157.            if (InvokeRequired)
  158.            {
  159.                Invoke(new Action(() =>
  160.                {
  161.                    ActualizarUIControlComandoB(salida);
  162.                }));
  163.            }
  164.            else
  165.            {
  166.                ActualizarUIControlComandoB(salida);
  167.            }
  168.        }
  169.  
  170.        /* Mostrar datos COMANDO_X5 */
  171.        private void ActualizarUIControlComandoX5(string[] salida)
  172.        {
  173.            label_Resultado_Tension_nominal.Text
  174.                = salida[0] + " V";
  175.            label_Resultado_Cantidad_del_paquete.Text
  176.                = salida[1] + " Baterías";
  177.            label_Resultado_Capacidad_del_paquete.Text
  178.                = salida[2] + " Ah";
  179.            label_Resultado_Cantidad_externa.Text
  180.                = salida[3];
  181.            label_Resultado_Descarga_maxima.Text
  182.                = salida[4] + " Minuto";
  183.  
  184.            // Convertir variable tipo string a tipo uint, es decir, la variable tipo string "salida[5]"
  185.            // se convierte en tipo uint "resultadoSalida5".
  186.            uint resultadoSalida5 = UInt32.Parse(salida[5]);
  187.  
  188.            // Cálculos.
  189.            uint horas = resultadoSalida5 / 60;
  190.            //uint minutos = resultadoSalida5 % 60;
  191.  
  192.            label_Resultado_Carga_maxima.Text
  193.                = $"{horas} Horas";
  194.  
  195.        }
  196.        /* Mostrar datos COMANDO_X72 */
  197.        private void ActualizarUIControlComandoX72(string[] salida)
  198.        {
  199.            label_Resultado_valores_nonimales_de_alimentacion.Text
  200.               = salida[0] + " VA / " + salida[1] + " W";
  201.            label_Resultado_voltaje_nominal.Text
  202.                = salida[2] + " Vac";
  203.            label_Resultado_corriente_nominal.Text
  204.                = salida[5] + " A";
  205.            label_Resultado_valores_nominales_de_frecuencia.Text
  206.                = salida[3] + " ~ " + salida[4] + " Hz";
  207.        }
  208.  
  209.        /* Mostrar datos COMANDO_B */
  210.        private void ActualizarUIControlComandoB(string[] salida)
  211.        {
  212.            label_I.Text
  213.                  = salida[0] + " Vac";
  214.            label_O.Text
  215.                = salida[1] + " Vac";
  216.            label_L.Text
  217.                = salida[2].TrimStart('0').PadLeft(1, '0') + " %"; // Quita los ceros de la izquierda y pone un cero si no hay nada.
  218.            label_B.Text
  219.                = salida[3].TrimStart('0').PadLeft(1, '0') + " %";
  220.            label_V.Text
  221.                = salida[4] + " Vdc";
  222.            label_F.Text
  223.                = salida[5].PadRight(5, '0') + " Hz"; // Añade ceros a la derecha.
  224.            label_H.Text
  225.                = salida[6].PadRight(5, '0') + " Hz";
  226.  
  227.            // Convertir variable tipo string a tipo uint, es decir, la variable tipo string "salida[7]"
  228.            // se convierte en tipo uint "resultadoSalida7".
  229.            uint resultadoSalida7 = UInt32.Parse(salida[7]);
  230.  
  231.            #region Horas y minutos.
  232.            // Cálculos.
  233.            uint horas = resultadoSalida7 / 60;
  234.            uint minutos = resultadoSalida7 % 60;
  235.  
  236.            // ¿0 horas y 1 minuto?
  237.            if ((horas == 0) && (minutos == 1))
  238.            {
  239.                label_R.Text = $"{minutos} minuto.";
  240.            }
  241.  
  242.            // ¿0 horas y 0 minuto?
  243.            if ((horas == 0) && (minutos == 0))
  244.            {
  245.                label_R.Text = $"{minutos} minutos";
  246.            }
  247.  
  248.            // ¿0 horas y más de 1 minuto?
  249.            if ((horas == 0) && (minutos > 1))
  250.            {
  251.                label_R.Text = $"{minutos} minutos.";
  252.            }
  253.  
  254.            // ¿1 hora y 0 minutos?
  255.            if ((horas == 1) && (minutos == 0))
  256.            {
  257.                label_R.Text = $"{horas} hora.";
  258.            }
  259.  
  260.            // ¿Más de una hora y 0 minutos?
  261.            if ((horas > 1) && (minutos == 0))
  262.            {
  263.                label_R.Text = $"{horas} horas.";
  264.            }
  265.  
  266.            // ¿1 hora y 1 minuto?
  267.            if ((horas == 1) && (minutos == 1))
  268.            {
  269.                label_R.Text = $"{horas} hora y {minutos} minuto";
  270.            }
  271.  
  272.            // ¿1 hora y más de 1 minuto?
  273.            if ((horas == 1) && (minutos > 1))
  274.            {
  275.                label_R.Text = $"{horas} hora y {minutos} minutos.";
  276.            }
  277.  
  278.            // ¿Más de 1 hora y 1 minuto?
  279.            if ((horas > 1) && (minutos == 1))
  280.            {
  281.                label_R.Text = $"{horas} horas y {minutos} minuto.";
  282.            }
  283.  
  284.            // ¿Más de 1 horas y más de 1 minuto?
  285.            if ((horas > 1) && (minutos > 1))
  286.            {
  287.                label_R.Text = $"{horas} horas y {minutos} minutos.";
  288.            }
  289.            #endregion
  290.  
  291.            uint barraProgresoB = UInt32.Parse(salida[2]);
  292.            progressBar_B.Value = (int)barraProgresoB;
  293.  
  294.            uint[] numeros = new uint[6];
  295.            uint contador = 0;
  296.  
  297.            foreach (uint elemento in Encoding.Default.GetBytes(salida[8]))
  298.            {
  299.                //richTextBox1.Text += b.ToString();
  300.                richTextBox1.Text += Environment.NewLine; // Nueva línea.
  301.                richTextBox1.Text += $"Array: {numeros[contador] = elemento}";
  302.                ++contador;
  303.            }
  304.            statusStrip1.Items[0].Text = @$"{puertoSerie.PortName} {puertoSerie.BaudRate} {puertoSerie.DataBits} {puertoSerie.Parity} {puertoSerie.StopBits}";
  305.        }
  306.  
  307.        /* Evento de botón: Abrir puerto serie y mandar "B" */
  308.        private void button_Comando_B_Click(object sender, EventArgs e)
  309.        {
  310.            verComandoBFlag = true;
  311.            puertoSerie.Write(COMANDO_B);
  312.        }
  313.  
  314.        /* Evento de botón: Abrir puerto serie y mandar "X72" */
  315.        private void button_Comando_X72_Click(object sender, EventArgs e)
  316.        {
  317.            verComandoX72Flag = true;
  318.            puertoSerie.Write(COMANDO_X72);
  319.        }
  320.  
  321.        private void button_Comando_X5_Click(object sender, EventArgs e)
  322.        {
  323.            verComandoX5Flag = true;
  324.            puertoSerie.Write(COMANDO_X5);
  325.        }
  326.        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  327.        {
  328.            timer1.Stop();          // Detiene el temporizador.
  329.            Thread.Sleep(700);      // 0.7 segundos. 700 milisegundos.
  330.            puertoSerie.Close();    // Cierra el puerto serie.
  331.        }
  332.  
  333.        private void timer1_Tick_1(object sender, EventArgs e)
  334.        {
  335.            verComandoBFlag = true;
  336.            // Enviar comando B al puerto serie.
  337.            puertoSerie.Write(COMANDO_B);
  338.        }
  339.    }
  340. }
  341.  

A ver si hay suerte y me sale las cosas.
« Última modificación: 3 Diciembre 2023, 08:48 am por Meta » En línea

Meta


Desconectado Desconectado

Mensajes: 3.501



Ver Perfil WWW
[RESUELTO] Usar read en entrada de datos
« Respuesta #5 en: 6 Diciembre 2023, 21:33 pm »

Ya funciona, solo había que poner el encoder correcto.

Código
  1. using System.IO.Ports;
  2. using System.Text;
  3.  
  4. namespace Termite_SAI_05_.NET_8._0
  5. {
  6.    public partial class Form1 : Form
  7.    {
  8.        SerialPort puertoSerie;
  9.        bool verComandoBFlag = false;
  10.        bool verComandoX72Flag = false;
  11.        bool verComandoX5Flag = false;
  12.        const string COMANDO_B = "B\r";
  13.        const string COMANDO_X72 = "X72\r";
  14.        const string COMANDO_X5 = "X5\r";
  15.  
  16.        public Form1()
  17.        {
  18.            InitializeComponent();
  19.            InicioPuertoSerie();
  20.        }
  21.        private void Form1_Load(object sender, EventArgs e)
  22.        {
  23.            //timer1.Start();
  24.            timer1.Enabled = true;
  25.        }
  26.        /* Iniciar y configurar el puerto serie */
  27.        private void InicioPuertoSerie()
  28.        {
  29.            try
  30.            {
  31.                puertoSerie = new SerialPort()
  32.                {
  33.                    // Configuración del puerto serie.
  34.                    PortName = "COM3",           // Nombre del puerto serie.
  35.                    BaudRate = 2400,             // Velocidad en baudios.
  36.                    Parity = Parity.None,        // Esquema para comprobar la paridad de cada byte recibido.
  37.                    StopBits = StopBits.One,     // Número de bits de parada por byte.
  38.                    DataBits = 8,                // Número de bits de datos por byte.
  39.                    Handshake = Handshake.None,  // Protocolo de establecimiento.
  40.                    Encoding = Encoding.GetEncoding(28591),
  41.                    DtrEnable = true,            // Línea de terminal de datos.
  42.                    RtsEnable = true,            // Línea de solicitud.
  43.  
  44.                    // Establecer los tiempos de espera de lectura / escritura.
  45.                    ReadTimeout = 500,           // Tiempo de espera de escritura en ms.
  46.                    WriteTimeout = 500,          // Tiempo de espera de escritura en ms.
  47.  
  48.                    // Más configuraciones.
  49.                    DiscardNull = false,         // Descartar bytes nulos recibidos.
  50.                    ParityReplace = 63,          // Reemplaza los bytes recibidos con errores de paridad.
  51.                    ReadBufferSize = 4096,       // Tamaño del búfer de lectura en bytes.
  52.                    WriteBufferSize = 2018,      // Tamaño del búfer de escritura en bytes.
  53.                    ReceivedBytesThreshold = 1   // Número de bytes que se necesitan.
  54.                };
  55.  
  56.                // Abrir puerto serie.
  57.                puertoSerie.Open();
  58.  
  59.                // Subscribir el evento DatosRecividos cuando lleguen datos.
  60.                puertoSerie.DataReceived += DatosRecibidos;
  61.            }
  62.            catch (Exception ex)
  63.            {
  64.                MessageBox.Show(ex.Message, "Aviso", MessageBoxButtons.OK, MessageBoxIcon.Warning);
  65.                timer1.Stop();
  66.                puertoSerie.Close(); // Cierra el puerto en caso de error                
  67.            }
  68.        }
  69.  
  70.        /* Evento para leer asíncronamente datos del puerto serie */
  71.        void DatosRecibidos(object sender, SerialDataReceivedEventArgs e)
  72.        {
  73.            Task.Run(async () =>
  74.            {
  75.                try
  76.                {
  77.                    await Task.Delay(500); // Pausa para recibir datos.
  78.                    string cadena = puertoSerie.ReadExisting();
  79.                    if (!string.IsNullOrEmpty(cadena))
  80.                    {
  81.                        if (verComandoBFlag == true) { ProcesoCOMANDO_B(cadena); }
  82.                        if (verComandoX72Flag) { ProcesoCOMANDO_X72(cadena); }
  83.                        if (verComandoX5Flag) { ProcesoCOMANDO_X5(cadena); }
  84.                    }
  85.                    else
  86.                    {
  87.                        Console.Write("Datos leídos corruptos.");
  88.                    }
  89.                }
  90.                catch (IndexOutOfRangeException ex)
  91.                {
  92.                    Console.Write("Índice fuera de los límites de la matriz.");
  93.                    MessageBox.Show(ex.Message);
  94.                }
  95.                catch (FormatException ex)
  96.                {
  97.                    Console.Write("La cadena de entrada no tiene el formato correcto.");
  98.                    MessageBox.Show(ex.Message, "Error");
  99.                }
  100.            });
  101.        }
  102.  
  103.        /* Procesar COMANDO_X5 */
  104.        private void ProcesoCOMANDO_X5(string cadena)
  105.        {
  106.            verComandoX5Flag = false;
  107.            char[] separadores = { '#', ',', '\r' };
  108.            string[] salida = cadena.Split(separadores, StringSplitOptions.RemoveEmptyEntries);
  109.  
  110.            // Al manipular controles de Windows Forms desde un hilo diferente al
  111.            // hilo de la interfaz de usuario, es necesario usar Invoke para evitar problemas de concurrencia.
  112.            if (InvokeRequired)
  113.            {
  114.                Invoke(new Action(() =>
  115.                {
  116.                    ActualizarUIControlComandoX5(salida);
  117.                }));
  118.            }
  119.            else
  120.            {
  121.                ActualizarUIControlComandoX5(salida);
  122.            }
  123.        }
  124.  
  125.        /* Procesar COMANDO_X72 */
  126.        private void ProcesoCOMANDO_X72(string str)
  127.        {
  128.            verComandoX72Flag = false;
  129.            char[] separadores = { '#', ',', '\r' };
  130.            string[] salida = str.Split(separadores, StringSplitOptions.RemoveEmptyEntries);
  131.  
  132.            // Al manipular controles de Windows Forms desde un hilo diferente al
  133.            // hilo de la interfaz de usuario, es necesario usar Invoke para evitar problemas de concurrencia.
  134.            if (InvokeRequired)
  135.            {
  136.                Invoke(new Action(() =>
  137.                {
  138.                    ActualizarUIControlComandoX72(salida);
  139.                }));
  140.            }
  141.            else
  142.            {
  143.                ActualizarUIControlComandoX72(salida);
  144.            }
  145.        }
  146.  
  147.        /* Procesar COMANDO_B */
  148.        private void ProcesoCOMANDO_B(string str)
  149.        {
  150.            verComandoBFlag = false;
  151.            char[] separadores = { '#', 'I', 'O', 'L', 'B', 'V', 'F', 'H', 'R', 'S', '\r' };
  152.            string[] salida = str.Split(separadores, StringSplitOptions.RemoveEmptyEntries);
  153.  
  154.            // Al manipular controles de Windows Forms desde un hilo diferente al
  155.            // hilo de la interfaz de usuario, es necesario usar Invoke para evitar problemas de concurrencia.
  156.            if (InvokeRequired)
  157.            {
  158.                Invoke(new Action(() =>
  159.                {
  160.                    ActualizarUIControlComandoB(salida);
  161.                }));
  162.            }
  163.            else
  164.            {
  165.                ActualizarUIControlComandoB(salida);
  166.            }
  167.        }
  168.  
  169.        /* Mostrar datos COMANDO_X5 */
  170.        private void ActualizarUIControlComandoX5(string[] salida)
  171.        {
  172.            label_Resultado_Tension_nominal.Text
  173.                = salida[0] + " V";
  174.            label_Resultado_Cantidad_del_paquete.Text
  175.                = salida[1] + " Baterías";
  176.            label_Resultado_Capacidad_del_paquete.Text
  177.                = salida[2] + " Ah";
  178.            label_Resultado_Cantidad_externa.Text
  179.                = salida[3];
  180.            label_Resultado_Descarga_maxima.Text
  181.                = salida[4] + " Minuto";
  182.  
  183.            // Convertir variable tipo string a tipo uint, es decir, la variable tipo string "salida[5]"
  184.            // se convierte en tipo uint "resultadoSalida5".
  185.            uint resultadoSalida5 = UInt32.Parse(salida[5]);
  186.  
  187.            // Cálculos.
  188.            uint horas = resultadoSalida5 / 60;
  189.            //uint minutos = resultadoSalida5 % 60;
  190.  
  191.            label_Resultado_Carga_maxima.Text
  192.                = $"{horas} Horas";
  193.  
  194.        }
  195.        /* Mostrar datos COMANDO_X72 */
  196.        private void ActualizarUIControlComandoX72(string[] salida)
  197.        {
  198.            label_Resultado_valores_nonimales_de_alimentacion.Text
  199.               = salida[0] + " VA / " + salida[1] + " W";
  200.            label_Resultado_voltaje_nominal.Text
  201.                = salida[2] + " Vac";
  202.            label_Resultado_corriente_nominal.Text
  203.                = salida[5] + " A";
  204.            label_Resultado_valores_nominales_de_frecuencia.Text
  205.                = salida[3] + " ~ " + salida[4] + " Hz";
  206.        }
  207.  
  208.        /* Mostrar datos COMANDO_B */
  209.        private void ActualizarUIControlComandoB(string[] salida)
  210.        {
  211.            label_I.Text
  212.                  = salida[0] + " Vac";
  213.            label_O.Text
  214.                = salida[1] + " Vac";
  215.            label_L.Text
  216.                = salida[2].TrimStart('0').PadLeft(1, '0') + " %"; // Quita los ceros de la izquierda y pone un cero si no hay nada.
  217.            label_B.Text
  218.                = salida[3].TrimStart('0').PadLeft(1, '0') + " %"; // Quita los ceros de la izquierda y pone un cero si no hay nada.
  219.            label_V.Text
  220.                = salida[4] + " Vdc";
  221.            label_F.Text
  222.                = salida[5].PadRight(5, '0') + " Hz"; // Añade ceros a la derecha.
  223.            label_H.Text
  224.                = salida[6].PadRight(5, '0') + " Hz";
  225.  
  226.            // Convertir variable tipo string a tipo uint, es decir, la variable tipo string "salida[7]"
  227.            // se convierte en tipo uint "resultadoSalida7".
  228.            uint resultadoSalida7 = uint.Parse(salida[7]);
  229.  
  230.            #region Horas y minutos.
  231.            // Cálculos.
  232.            uint horas = resultadoSalida7 / 60;
  233.            uint minutos = resultadoSalida7 % 60;
  234.  
  235.            // ¿0 horas y 1 minuto?
  236.            if ((horas == 0) && (minutos == 1))
  237.            {
  238.                label_R.Text = $"{minutos} minuto.";
  239.            }
  240.  
  241.            // ¿0 horas y 0 minuto?
  242.            if ((horas == 0) && (minutos == 0))
  243.            {
  244.                label_R.Text = $"{minutos} minutos";
  245.            }
  246.  
  247.            // ¿0 horas y más de 1 minuto?
  248.            if ((horas == 0) && (minutos > 1))
  249.            {
  250.                label_R.Text = $"{minutos} minutos.";
  251.            }
  252.  
  253.            // ¿1 hora y 0 minutos?
  254.            if ((horas == 1) && (minutos == 0))
  255.            {
  256.                label_R.Text = $"{horas} hora.";
  257.            }
  258.  
  259.            // ¿Más de una hora y 0 minutos?
  260.            if ((horas > 1) && (minutos == 0))
  261.            {
  262.                label_R.Text = $"{horas} horas.";
  263.            }
  264.  
  265.            // ¿1 hora y 1 minuto?
  266.            if ((horas == 1) && (minutos == 1))
  267.            {
  268.                label_R.Text = $"{horas} hora y {minutos} minuto";
  269.            }
  270.  
  271.            // ¿1 hora y más de 1 minuto?
  272.            if ((horas == 1) && (minutos > 1))
  273.            {
  274.                label_R.Text = $"{horas} hora y {minutos} minutos.";
  275.            }
  276.  
  277.            // ¿Más de 1 hora y 1 minuto?
  278.            if ((horas > 1) && (minutos == 1))
  279.            {
  280.                label_R.Text = $"{horas} horas y {minutos} minuto.";
  281.            }
  282.  
  283.            // ¿Más de 1 horas y más de 1 minuto?
  284.            if ((horas > 1) && (minutos > 1))
  285.            {
  286.                label_R.Text = $"{horas} horas y {minutos} minutos.";
  287.            }
  288.            #endregion
  289.  
  290.            // Mostrar nivel barra de progreso.
  291.            uint barraProgresoL = uint.Parse(salida[2]);
  292.            progressBar_L.Value = (int)barraProgresoL;
  293.  
  294.            uint barraProgresoB = uint.Parse(salida[3]);
  295.            progressBar_B.Value = (int)barraProgresoB;
  296.  
  297.            uint[] numeros = new uint[8];
  298.            uint contador = 0;
  299.            richTextBox1.Clear(); // Limpiar.
  300.            foreach (uint elemento in salida[8])
  301.            {
  302.                richTextBox1.Text += Environment.NewLine; // Nueva línea.
  303.                richTextBox1.Text += $"Array: {numeros[contador] = elemento}";
  304.                ++contador;
  305.            }
  306.  
  307.            // Mostrar información configuración del puerto serie.
  308.            statusStrip1.Items[0].Text = @$"{puertoSerie.PortName} {puertoSerie.BaudRate} {puertoSerie.DataBits} {puertoSerie.Parity} {puertoSerie.StopBits}";
  309.        }
  310.  
  311.        /* Evento de botón: Abrir puerto serie y mandar "B" */
  312.        private void button_Comando_B_Click(object sender, EventArgs e)
  313.        {
  314.            verComandoBFlag = true;
  315.            puertoSerie.Write(COMANDO_B);
  316.        }
  317.  
  318.        /* Evento de botón: Abrir puerto serie y mandar "X72" */
  319.        private void button_Comando_X72_Click(object sender, EventArgs e)
  320.        {
  321.            timer1.Enabled = false;
  322.            Thread.Sleep(1000);
  323.            verComandoX72Flag = true;
  324.            puertoSerie.Write(COMANDO_X72);
  325.            timer1.Enabled = true;
  326.        }
  327.  
  328.        private void button_Comando_X5_Click(object sender, EventArgs e)
  329.        {
  330.            timer1.Enabled = false;
  331.            Thread.Sleep(1000);
  332.            verComandoX5Flag = true;
  333.            puertoSerie.Write(COMANDO_X5);
  334.            timer1.Enabled = true;
  335.        }
  336.        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  337.        {
  338.            timer1.Stop();          // Detiene el temporizador.
  339.            Thread.Sleep(700);      // 0.7 segundos. 700 milisegundos.
  340.            puertoSerie.Close();    // Cierra el puerto serie.
  341.        }
  342.  
  343.        private void timer1_Tick_1(object sender, EventArgs e)
  344.        {
  345.            verComandoBFlag = true;
  346.            // Enviar comando B al puerto serie.
  347.            puertoSerie.Write(COMANDO_B);
  348.        }
  349.    }
  350. }

Muchas gracias.
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Entrada de datos desde consola y validación.[Segmentation fault](Resuelto)
Programación C/C++
Tha_Traker 5 4,390 Último mensaje 12 Mayo 2010, 18:23 pm
por Tha_Traker
usar puerto hdmi de laptop como entrada
Hardware
flacc 6 29,560 Último mensaje 22 Septiembre 2014, 06:40 am
por PC Tips
[Resuelto] Problema al probar los script de entrada al localhost
PHP
Blitox1570 7 3,804 Último mensaje 3 Julio 2015, 17:20 pm
por DarK_FirefoX
usar un router technicolor con entrada wan
Redes
Bhorox 0 3,300 Último mensaje 4 Septiembre 2015, 05:48 am
por Bhorox
Error al leer datos función read
Programación C/C++
jose94 4 3,265 Último mensaje 3 Agosto 2017, 20:13 pm
por jose94
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines