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

 

 


Tema destacado: Arreglado, de nuevo, el registro del warzone (wargame) de EHN


  Mostrar Mensajes
Páginas: 1 [2] 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ... 254
11  Programación / .NET (C#, VB.NET, ASP) / Re: ERROR: Referencia a objeto no establecida como instancia de un objeto. en: 25 Diciembre 2023, 08:17 am
La idea del programa es almacenar los bytes recibidos y mostrarlo en pantalla.

Si no ha llegado nada, que diga que no hay nada con un mensaje.
12  Programación / .NET (C#, VB.NET, ASP) / Re: ERROR: Referencia a objeto no establecida como instancia de un objeto. en: 13 Diciembre 2023, 21:48 pm
Me ejecuta pero en pantalla no me muestra nada a la hora de enviar tramas de bytes para ver si lo capta. Si no hay nada, que también indique algo para saberlo.
13  Programación / .NET (C#, VB.NET, ASP) / Re: ERROR: Referencia a objeto no establecida como instancia de un objeto. en: 7 Diciembre 2023, 23:37 pm
Me equivoqué. La captura es esta:



Ver zoom.

Disculpen.
14  Programación / .NET (C#, VB.NET, ASP) / ERROR: Referencia a objeto no establecida como instancia de un objeto. en: 6 Diciembre 2023, 22:37 pm
Hola:

En este código me sale un error y no se como corregirlo, ya que me interesa mostrar datos en pantalla y no me sale.

Ver error.

Código hecho hasta ahora.
Código
  1. using System;
  2. using System.IO.Ports;
  3.  
  4. namespace Almacenar_byte_puerto_serie_Consola_01
  5. {
  6.    internal class Program
  7.    {
  8.        static SerialPort puertoSerie;
  9.        static byte[] datoRecibido;
  10.        static void Main(string[] args)
  11.        {
  12.            #region Configuración ventana.
  13.            // Título de la ventana.
  14.            Console.Title = "Almacenar byte[] desde el puerto serie.";
  15.  
  16.            // Tamaño de la ventana, x, y, o ancho y alto.
  17.            const byte ANCHO_X = 70, ALTO_Y = 25;
  18.            Console.SetWindowSize(ANCHO_X, ALTO_Y);
  19.  
  20.            // Color de fondo.
  21.            Console.BackgroundColor = ConsoleColor.Black;
  22.  
  23.            // Color de las letras.
  24.            Console.ForegroundColor = ConsoleColor.Yellow;
  25.  
  26.            // Limpiar pantalla y dejarlo todo en color de fondo.
  27.            Console.Clear();
  28.  
  29.            // Visible el cursor.
  30.            Console.CursorVisible = true;
  31.            #endregion
  32.  
  33.            puertoSerie = new SerialPort()
  34.            {
  35.                // Configuración del puerto serie.
  36.                PortName = "COM4",           // Nombre del puerto serie.
  37.                BaudRate = 2400,             // Velocidad en baudios.
  38.                Parity = Parity.None,        // Esquema para comprobar la paridad de cada byte recibido.
  39.                StopBits = StopBits.One,     // Número de bits de parada por byte.
  40.                DataBits = 8,                // Número de bits de datos por byte.
  41.                Handshake = Handshake.None,  // Protocolo de establecimiento.
  42.                DtrEnable = true,            // Línea de terminal de datos.
  43.                RtsEnable = true,            // Línea de solicitud.
  44.  
  45.                // Establecer los tiempos de espera de lectura / escritura.
  46.                ReadTimeout = 500,           // Tiempo de espera de escritura en ms.
  47.                WriteTimeout = 500,          // Tiempo de espera de escritura en ms.
  48.  
  49.                // Más configuraciones.
  50.                DiscardNull = false,         // Descartar bytes nulos recibidos.
  51.                ParityReplace = 63,          // Reemplaza los bytes recibidos con errores de paridad.
  52.                ReadBufferSize = 4096,       // Tamaño del búfer de lectura en bytes.
  53.                WriteBufferSize = 2018,      // Tamaño del búfer de escritura en bytes.
  54.                ReceivedBytesThreshold = 1   // Número de bytes que se necesitan.
  55.            };
  56.  
  57.            puertoSerie.DataReceived += SerialPort_DataReceived;
  58.            puertoSerie.Open();
  59.  
  60.            Console.WriteLine("Presiona cualquier tecla para detener la captura...");
  61.            Console.ReadKey();
  62.  
  63.            puertoSerie.Close();
  64.  
  65.            Console.WriteLine("Datos recibidos:");
  66.            MostrarBytes(datoRecibido);
  67.        }
  68.        static void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
  69.        {
  70.            SerialPort sp = (SerialPort)sender;
  71.            int bytesToRead = sp.BytesToRead;
  72.            byte[] buffer = new byte[bytesToRead];
  73.            sp.Read(buffer, 0, bytesToRead);
  74.  
  75.            if (datoRecibido == null)
  76.            {
  77.                datoRecibido = buffer;
  78.            }
  79.            else
  80.            {
  81.                Array.Resize(ref datoRecibido, datoRecibido.Length + bytesToRead);
  82.                Array.Copy(buffer, 0, datoRecibido, datoRecibido.Length - bytesToRead, bytesToRead);
  83.            }
  84.        }
  85.  
  86.        static void MostrarBytes(byte[] dato)
  87.        {
  88.            for (int i = 0; i < dato.Length; i++)
  89.            {
  90.                Console.Write($"{dato[i]} ");
  91.            }
  92.            Console.WriteLine();
  93.        }
  94.    }
  95. }

Se trata de obtener bytes puro y duro desde el RS232 o puerto serie, almacenarlo en un array tipo byte[] y mostrarlo en pantalla.

¿Alguna idea?

Saludos.
15  Programación / .NET (C#, VB.NET, ASP) / [RESUELTO] Usar read en entrada de datos 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.
16  Programación / .NET (C#, VB.NET, ASP) / Re: Usar read en entrada de datos 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.
17  Programación / .NET (C#, VB.NET, ASP) / Re: Usar read en entrada de datos 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;

18  Programación / .NET (C#, VB.NET, ASP) / Re: Usar read en entrada de datos 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.
19  Programación / .NET (C#, VB.NET, ASP) / 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.
20  Programación / .NET (C#, VB.NET, ASP) / Re: Tengo un problema con delimitadores en: 30 Noviembre 2023, 22:42 pm
Muy bueno la idea.

Estaba intentado guardar en un array los resultado que suelta la variable B.

Luego escojo cualquier valor en decimal y lo muestro en pantalla.

¿Cuál es la mejor manera?

El programa tuyo funciona a la primera.

Edito:
Código
  1.            string entrada = "#I225.7O226.2L006B100V25.7F50.2H50.2R0080S&#8364;&#8222;&#8364;&#710;&#8222;\r";
  2.            char[] separadores = { '#', 'I', 'O', 'L', 'B', 'V', 'F', 'H', 'R', 'S', '\r' };
  3.            string[] salida = entrada.Split(separadores);
  4.            uint[] numeros = new uint[6];
  5.            uint j = 0;
  6.  
  7.            for (int i = 2; i < 10; i++)
  8.            {
  9.                Console.WriteLine($"> {salida[i]}");
  10.            }
  11.  
  12.            foreach (uint b in Encoding.Default.GetBytes(salida[10]))
  13.            {
  14.                Console.WriteLine($"> {b}");
  15.                Console.WriteLine($"Array: {numeros[j] = b}");
  16.                ++j;
  17.            }
Páginas: 1 [2] 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ... 254
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines