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

 

 


Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Recibir dos tramas por RS232 diferentes.
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: Recibir dos tramas por RS232 diferentes.  (Leído 10,039 veces)
Meta


Desconectado Desconectado

Mensajes: 3.501



Ver Perfil WWW
Recibir dos tramas por RS232 diferentes.
« en: 24 Noviembre 2023, 06:49 am »

Hola:

Puedo recibir tramas de bytes por el puerto serie, una es esta si envía este comando:
Código:
serialPort1.Write("B\r");

#I230.3O230.0L007B100V25.7F50.2H50.2R0080S„€ˆ„À

y la otra es esta si envías este otro comando diferente:
Código:
serialPort1.Write("X72\r");

#2000,1400,230,45.0,55.0,8.6

En la primera tengo el código hecho en Windows Form y funciona.
Código:
using System;
using System.IO.Ports;
using System.Threading;
using System.Windows.Forms;

namespace Termite_SAI_04
{
    public partial class Form1 : Form
    {
        private delegate void DelegadoAcceso(String accion);
        public Form1()
        {
            InitializeComponent();
        }

        private void button_Ver_datos_Click(object sender, EventArgs e)
        {
            serialPort1.Write("B\r");
        }

        private void button_Ver_Tabla_Click(object sender, EventArgs e)
        {
            serialPort1.Write("X72\r");
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                serialPort1 = new SerialPort("COM3", 2400, Parity.None, 8, StopBits.One);
                serialPort1.Handshake = Handshake.None;
                serialPort1.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
                serialPort1.ReadTimeout = 500;
                serialPort1.WriteTimeout = 500;
                serialPort1.Open();
                serialPort1.Write("B\r");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (this.Enabled == true)
            {
                Thread.Sleep(500);
                string entrada = serialPort1.ReadExisting();
                this.BeginInvoke(new DelegadoAcceso(si_DataReceived), new object[] { entrada });
                //serialPort1.Write("B\r"); // Envía comando.
            }
        }

        private void si_DataReceived(string accion)
        {
            try
            {
                char[] separadores = { '#', 'I', 'O', 'L', 'B', 'V', 'F', 'H', 'R', 'S' };

                string[] salida = accion.Split(separadores, StringSplitOptions.RemoveEmptyEntries);

                label_I.Text = salida[0] + " Vac";
                label_O.Text = salida[1] + " Vac";
                label_L.Text = salida[2].TrimStart('0') + " %"; // Quita los ceros de la izquierda.
                label_B.Text = salida[3] + " %";
                label_V.Text = salida[4] + " Vdc";
                label_F.Text = salida[5].PadRight(5, '0') + " Hz"; // Añade ceros a la derecha.
                label_H.Text = salida[6].PadRight(5, '0') + " Hz";

                // Convertir variable tipo string a tipo int, es decir, la variable tipo string "salida[7]"
                // se convierte en tipo int "resultadoSalida7".
                int resultadoSalida7 = Int32.Parse(salida[7]);

                // ¿Es igual a 1 minuto?
                if ((resultadoSalida7 % 60) == 1)
                {
                    label_R.Text = resultadoSalida7 / 60 + " hora y " + resultadoSalida7 % 60 + " minuto.";
                }

                // ¿Es mayor a 60 segundos o 1 minuto?
                if ((resultadoSalida7 % 60) > 1)
                {
                    label_R.Text = resultadoSalida7 / 60 + " hora y " + resultadoSalida7 % 60 + " minutos.";
                }

                // ¿Es igual a 60 segundos o 1 minuto?
                if ((resultadoSalida7 % 60) == 0)
                {
                    label_R.Text = resultadoSalida7 / 60 + " hora y " + resultadoSalida7 % 60 + " minutos.";
                }
            }

            catch (IndexOutOfRangeException ex)
            {
                Console.Write("Índice fuera de los límites de la matriz.");
                MessageBox.Show(ex.Message);
            }

            catch (FormatException ex)
            {
                Console.Write("La cadena de entrada no tiene el formato correcto.");
                MessageBox.Show(ex.Message, "Error");
            }
        }
    }
}

Aquí abajo es el trozo de códigos para leer esa trama que no se donde ponerlo.
Código:
            char[] separadores2 = { '#', ',' };

            string[] salida2 = entrada2.Split(separadores2, StringSplitOptions.RemoveEmptyEntries);

            label_Resultado_valores_nonimales_de_alimentacion.Text = salida2[0] + " VA / " + salida2[1] + " W";
            label_Resultado_voltaje_nominal.Text = salida2[2] + " Vac";
            label_Resultado_corriente_nominal.Text = salida2[5] + " A";
            label_Resultado_valores_nominales_de_frecuencia.Text = salida2[3] + " ~ " + salida2[4] + " Hz";

¿Alguna ayuda?

Gracias.


En línea

profinet

Desconectado Desconectado

Mensajes: 31



Ver Perfil
Re: Recibir dos tramas por RS232 diferentes.
« Respuesta #1 en: 24 Noviembre 2023, 11:21 am »

He reorganizado tu código para hacerlo más modular, lo que facilitará futuras implementaciones y tareas de mantenimiento.
También he introducido dos banderas para determinar qué comando se ha utilizado al enviar la solicitud, permitiendo así la llamada a la función correspondiente.

Código:
using System;
using System.IO.Ports;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Termite_SAI_04 {
    public partial class Form1 : Form {

        private SerialPort puertoSerie;
        private bool verDatosFlag = false;
        private bool verTablaFlag = false;
        private readonly string verDatosReq = "B\r";
        private readonly string verTablaReq = "X72\r";

        private void Form1_Load(object sender, EventArgs e) {
        }

        public Form1() {
            InitializeComponent();
            InitSerialPort();
        }

        /* Iniciar y configurar el puerto serie */
        private void InitSerialPort() {
            try {
                puertoSerie = new SerialPort("COM3", 2400,
                    Parity.None, 8, StopBits.One) {
                    Handshake = Handshake.None,
                    ReadTimeout = 500,
                    WriteTimeout = 500,
                };
                // Subscribir el evento Sp_DataReceived cuando lleguen datos
                puertoSerie.DataReceived += Sp_DataReceived;
            } catch (Exception ex) {
                MessageBox.Show(ex.Message);
                puertoSerie.Close(); // Cierra el puerto en caso de error
            }
        }

        /* Evento de botón: Abrir puerto serie y mandar "B" */
        private void Button_Ver_datos_Click(object sender, EventArgs e) {
            if (puertoSerie.IsOpen) {
                verDatosFlag = true;
                puertoSerie.Open();
                puertoSerie.Write(verDatosReq);
            } else {
                Console.Write("Puerto cerrado. " +
                    "No se puede solicitar datos.");
            }
        }

        /* Evento de botón: Abrir puerto serie y mandar "X72" */
        private void Button_Ver_Tabla_Click(object sender, EventArgs e) {
            if (puertoSerie.IsOpen) {
                verTablaFlag = true;
                puertoSerie.Open();
                puertoSerie.Write(verTablaReq);
            } else {
                Console.Write("Puerto cerrado. " +
                    "No se puede enviar datos.");
            }
        }

        /* Evento para leer asíncronamente datos del puerto serie */
        void Sp_DataReceived(object sender, SerialDataReceivedEventArgs e) {
            if (puertoSerie.IsOpen) {
                Task.Run(async () => {
                    try {
                        await Task.Delay(500); // Pausa para recibir datos
                        string str = puertoSerie.ReadExisting();
                        if (!String.IsNullOrEmpty(str)) {
                            if (verDatosFlag) { ProcessVerDatosReq(str); }
                            if (verTablaFlag) { ProcessVerTablaReq(str); }
                        } else {
                            Console.Write("Datos leídos corruptos.");
                        }
                    } catch (IndexOutOfRangeException ex) {
                        Console.Write("Índice fuera de los límites de la matriz.");
                        MessageBox.Show(ex.Message);
                    } catch (FormatException ex) {
                        Console.Write("La cadena de entrada no tiene el formato correcto.");
                        MessageBox.Show(ex.Message, "Error");
                    }
                });
            }
        }

        /* Procesar VerTablaReq */
        private void ProcessVerTablaReq(string str) {
            verTablaFlag = false;
            char[] separadores = { '#', ',' };
            string[] salida = str.Split(separadores, StringSplitOptions.RemoveEmptyEntries);

            // Al manipular controles de Windows Forms desde un hilo diferente al
            // hilo de la interfaz de usuario, es necesario usar Invoke para evitar problemas de concurrencia
            if (InvokeRequired) {
                Invoke(new Action(() => {
                    UpdateUIControlsVerTabla(salida);
                }));
            } else {
                UpdateUIControlsVerTabla(salida);
            }
        }

        /* Procesar VerDatosReq */
        private void ProcessVerDatosReq(string str) {
            verDatosFlag = false;
            char[] separadores = { '#', 'I', 'O', 'L', 'B', 'V', 'F', 'H', 'R', 'S' };
            string[] salida = str.Split(separadores, StringSplitOptions.RemoveEmptyEntries);

            // Al manipular controles de Windows Forms desde un hilo diferente al
            // hilo de la interfaz de usuario, es necesario usar Invoke para evitar problemas de concurrencia
            if (InvokeRequired) {
                Invoke(new Action(() => {
                    UpdateUIControlsVerDatos(salida);
                }));
            } else {
                UpdateUIControlsVerDatos(salida);
            }
        }

        /* Mostrar datos VerTablaReq */
        private void UpdateUIControlsVerTabla(string[] salida) {
            label_Resultado_valores_nonimales_de_alimentacion.Text
               = salida[0] + " VA / " + salida2[1] + " W";
            label_Resultado_voltaje_nominal.Text
                = salida[2] + " Vac";
            label_Resultado_corriente_nominal.Text
                = salida[5] + " A";
            label_Resultado_valores_nominales_de_frecuencia.Text
                = salida[3] + " ~ " + salida2[4] + " Hz";
        }

        /* Mostrar datos VerDatosReq */
        private void UpdateUIControlsVerDatos(string[] salida) {
            label_I.Text
                  = salida[0] + " Vac";
            label_O.Text
                = salida[1] + " Vac";
            label_L.Text
                = salida[2].TrimStart('0') + " %"; // Quita los ceros de la izquierda.
            label_B.Text
                = salida[3] + " %";
            label_V.Text
                = salida[4] + " Vdc";
            label_F.Text
                = salida[5].PadRight(5, '0') + " Hz"; // Añade ceros a la derecha.
            label_H.Text
                = salida[6].PadRight(5, '0') + " Hz";

            // Convertir variable tipo string a tipo int, es decir, la variable tipo string "salida[7]"
            // se convierte en tipo int "resultadoSalida7".
            int resultadoSalida7 = Int32.Parse(salida[7]);

            // ¿Es igual a 1 minuto?
            if ((resultadoSalida7 % 60) == 1) {
                label_R.Text
                    = resultadoSalida7 / 60 + " hora y "
                    + resultadoSalida7 % 60 + " minuto.";
            }

            // ¿Es mayor a 60 segundos o 1 minuto?
            if ((resultadoSalida7 % 60) > 1) {
                label_R.Text
                    = resultadoSalida7 / 60 + " hora y "
                    + resultadoSalida7 % 60 + " minutos.";
            }

            // ¿Es igual a 60 segundos o 1 minuto?
            if ((resultadoSalida7 % 60) == 0) {
                label_R.Text
                    = resultadoSalida7 / 60 + " hora y "
                    + resultadoSalida7 % 60 + " minutos.";
            }
        }
    }
}


En línea

Don't shy away from the terminal; embrace it! In the GNU world, everything is a file.
Meta


Desconectado Desconectado

Mensajes: 3.501



Ver Perfil WWW
Re: Recibir dos tramas por RS232 diferentes.
« Respuesta #2 en: 25 Noviembre 2023, 21:11 pm »

Buenas:

Lo he probado y no hace nada de nada.  :(

No encuentro el motivo.

Eso si, tiene variables que se llama salida2 y es solo salida en tu código, ya corregido al compilar. Compila ahora todo, no da errores pero tampoco hace nada.
En línea

Meta


Desconectado Desconectado

Mensajes: 3.501



Ver Perfil WWW
Re: Recibir dos tramas por RS232 diferentes.
« Respuesta #3 en: 28 Noviembre 2023, 00:06 am »

Hola:

He hecho una interfaz con Windows Form como indica en la captura.

Se trata a la hora de recibir tramas de string o bytes por el puerto serie.

Si envío el comando X72\r, me llega la tramas de Bytes y lo muestra en los labels marcado en rojo.

Si envío otro comando en este caso llamado X72\r muestra los valores en otras etiquetas indicado en el recuardro en verde.

Ver zoom.

El problema como puedes ver en la captura, te muestra cada comando tramas diferentes en el cual quiero guardarlo en su variable para luego poder poner los valores en sus respectivos labels.

Los comandos los puedes ver, sus respuestas y errores si los hay.

Ver comandos PDF.

Código que he hecho hasta ahora solo funciona para el recuerdre verde.
Código:
using System;
using System.IO.Ports;
using System.Threading;
using System.Windows.Forms;

namespace Termite_SAI_04
{
    public partial class Form1 : Form
    {
        private delegate void DelegadoAcceso(String accion);
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                serialPort1 = new SerialPort("COM3", 2400, Parity.None, 8, StopBits.One);
                serialPort1.Handshake = Handshake.None;
                serialPort1.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
                serialPort1.ReadTimeout = 500;
                serialPort1.WriteTimeout = 500;
                serialPort1.DtrEnable = true;
                serialPort1.RtsEnable = true;
                serialPort1.Open();
                ComandoB();
                timer1.Start();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            if (this.Enabled == true)
            {
                Thread.Sleep(500);
                string entrada = serialPort1.ReadExisting();
                this.BeginInvoke(new DelegadoAcceso(si_DataReceived), new object[] { entrada });
                //serialPort1.Write("B\r"); // Envía comando.
            }
        }

        private void si_DataReceived(string accion)
        {
            try
            {
                char[] separadores = { '#', 'I', 'O', 'L', 'B', 'V', 'F', 'H', 'R', 'S', '\r' };

                string[] salida = accion.Split(separadores, StringSplitOptions.RemoveEmptyEntries);

                label_I.Text = salida[0] + " Vac";
                label_O.Text = salida[1] + " Vac";
                label_L.Text = salida[2].TrimStart('0') + " %"; // Quita los ceros de la izquierda.
                label_B.Text = salida[3] + " %";
                label_V.Text = salida[4] + " Vdc";
                label_F.Text = salida[5].PadRight(5, '0') + " Hz"; // Añade ceros a la derecha.
                label_H.Text = salida[6].PadRight(5, '0') + " Hz";

                // Convertir variable tipo string a tipo int, es decir, la variable tipo string "salida[7]"
                // se convierte en tipo int "resultadoSalida7".
                int resultadoSalida7 = Int32.Parse(salida[7]);

                #region Mostrar horas y minutos.
                // Cálculos.
                int horas = resultadoSalida7 / 60;
                int minutos = resultadoSalida7 % 60;

                // ¿0 horas y 1 minuto?
                if ((horas == 0) && (minutos == 1))
                {
                    label_R.Text = $"{minutos} minuto.";
                }

                // ¿0 horas y 0 minuto?
                if ((horas == 0) && (minutos == 0))
                {
                    label_R.Text = $"{minutos} minutos";
                }

                // ¿0 horas y más de 1 minuto?
                if ((horas == 0) && (minutos > 1))
                {
                    label_R.Text = $"{minutos} minutos.";
                }

                // ¿1 hora y 0 minutos?
                if ((horas == 1) && (minutos == 0))
                {
                    label_R.Text = $"{horas} hora.";
                }

                // ¿Más de una hora y 0 minutos?
                if ((horas > 1) && (minutos == 0))
                {
                    label_R.Text = $"{horas} horas.";
                }

                // ¿1 hora y 1 minuto?
                if ((horas == 1) && (minutos == 1))
                {
                    label_R.Text = $"{horas} hora y {minutos} minuto";
                }

                // ¿1 hora y más de 1 minuto?
                if ((horas == 1) && (minutos > 1))
                {
                    label_R.Text = $"{horas} hora y {minutos} minutos.";
                }

                // ¿Más de 1 hora y 1 minuto?
                if ((horas > 1) && (minutos == 1))
                {
                    label_R.Text = $"{horas} horas y {minutos} minuto.";
                }

                // ¿Más de 1 horas y más de 1 minuto?
                if ((horas > 1) && (minutos > 1))
                {
                    label_R.Text = $"{horas} horas y {minutos} minutos.";
                }
                #endregion
            }

            catch (IndexOutOfRangeException ex)
            {
                Console.Write("Índice fuera de los límites de la matriz.");
                MessageBox.Show(ex.Message);
            }

            catch (FormatException ex)
            {
                Console.Write("La cadena de entrada no tiene el formato correcto.");
                MessageBox.Show(ex.Message, "Error");
            }
        }

        private void button_Ver_datos_Click_1(object sender, EventArgs e)
        {
            ComandoB();
        }

        private void button_Ver_Tabla_Click_1(object sender, EventArgs e)
        {
            ComandoX72();
        }

        // Comandos.
        void ComandoB()
        {
            serialPort1.Write("B\r");
        }

        void ComandoX72()
        {
            serialPort1.Write("X72\r");
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            ComandoB();
        }

        // Al cerrar el formulario.
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            timer1.Stop();          // Detiene el temporizador.
            Thread.Sleep(700);      // 0.5 segudos. 500 milisegundos.
            serialPort1.Close();    // Cierra el puerto serie.
        }
    }
}

¿Alguna idea?

Saludos.
En línea

profinet

Desconectado Desconectado

Mensajes: 31



Ver Perfil
Re: Recibir dos tramas por RS232 diferentes.
« Respuesta #4 en: 28 Noviembre 2023, 10:15 am »

Ah sí, tuve un descuido al copiar y pegar directamente la lógica para editar los labels. Mis disculpas por eso.

En cuanto a la afirmación de que "no hace nada", me parece extraño. Al menos debería arrojar un error al configurar el puerto o indicar "puerto cerrado" al presionar uno de los dos botones.

En tu código, sería útil almacenar el tipo de solicitud realizada ("B" o "X72") en dos variables booleanas para procesar la trama en la función correspondiente. Puedes aprovechar el mismo manejador de eventos para recibir ambos tipos de tramas y luego pasar el array de cadenas (string[]) a la función apropiada.
« Última modificación: 28 Noviembre 2023, 10:39 am por profinet » En línea

Don't shy away from the terminal; embrace it! In the GNU world, everything is a file.
Meta


Desconectado Desconectado

Mensajes: 3.501



Ver Perfil WWW
Re: Recibir dos tramas por RS232 diferentes.
« Respuesta #5 en: 28 Noviembre 2023, 14:02 pm »

Cuando llegue a mi casa lo pruebo.

Hay algo que se me escapó y no te conté.

Todas las tramas de string o Bytes siempre empieza con # y acaba en \r.

#I230.3O230.0L007B100V25.7F50.2H50.2R0080S„€ˆ„\r

Lo comento por si acaso y los delimitadores se incluye el \r también.
En línea

Meta


Desconectado Desconectado

Mensajes: 3.501



Ver Perfil WWW
Re: Recibir dos tramas por RS232 diferentes.
« Respuesta #6 en: 28 Noviembre 2023, 23:43 pm »

Hola de nuevo.

He modificado nombre de las variables y lo he adaptado el Windows Form .net 4.8 al .net 8.0.

Me sale este error: Puerto cerrado.

Código
  1. using System.IO.Ports;
  2.  
  3. namespace Termite_SAI_05_.NET_8._0
  4. {
  5.    public partial class Form1 : Form
  6.    {
  7.        SerialPort puertoSerie;
  8.        bool verComandoBFlag = false;
  9.        bool verComandoX72Flag = false;
  10.        readonly string verComandoBReq = "B\r";
  11.        readonly string verComandoX72Req = "X72\r";
  12.  
  13.        private void Form1_Load(object sender, EventArgs e)
  14.        {
  15.  
  16.        }
  17.  
  18.        public Form1()
  19.        {
  20.            InitializeComponent();
  21.            InitSerialPort();
  22.        }
  23.  
  24.        /* Iniciar y configurar el puerto serie */
  25.        private void InitSerialPort()
  26.        {
  27.            try
  28.            {
  29.                puertoSerie = new SerialPort("COM3", 2400,
  30.                    Parity.None, 8, StopBits.One)
  31.                {
  32.                    Handshake = Handshake.None,
  33.                    ReadTimeout = 500,
  34.                    WriteTimeout = 500,
  35.                    DtrEnable = true,
  36.                    RtsEnable = true
  37.                };
  38.  
  39.                // Subscribir el evento Sp_DataReceived cuando lleguen datos
  40.                puertoSerie.DataReceived += Sp_DataReceived;
  41.            }
  42.            catch (Exception ex)
  43.            {
  44.                MessageBox.Show(ex.Message);
  45.                puertoSerie.Close(); // Cierra el puerto en caso de error
  46.            }
  47.        }
  48.  
  49.        /* Evento para leer asíncronamente datos del puerto serie */
  50.        void Sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
  51.        {
  52.            if (puertoSerie.IsOpen)
  53.            {
  54.                Task.Run(async () =>
  55.                {
  56.                    try
  57.                    {
  58.                        await Task.Delay(500); // Pausa para recibir datos
  59.                        string str = puertoSerie.ReadExisting();
  60.                        if (!String.IsNullOrEmpty(str))
  61.                        {
  62.                            if (verComandoBFlag) { ProcessverComandoBReq(str); }
  63.                            if (verComandoX72Flag) { ProcessverComandoX72Req(str); }
  64.                        }
  65.                        else
  66.                        {
  67.                            Console.Write("Datos leídos corruptos.");
  68.                        }
  69.                    }
  70.                    catch (IndexOutOfRangeException ex)
  71.                    {
  72.                        Console.Write("Índice fuera de los límites de la matriz.");
  73.                        MessageBox.Show(ex.Message);
  74.                    }
  75.                    catch (FormatException ex)
  76.                    {
  77.                        Console.Write("La cadena de entrada no tiene el formato correcto.");
  78.                        MessageBox.Show(ex.Message, "Error");
  79.                    }
  80.                });
  81.            }
  82.        }
  83.  
  84.        /* Procesar verComandoX72Req */
  85.        private void ProcessverComandoX72Req(string str)
  86.        {
  87.            verComandoX72Flag = false;
  88.            char[] separadores = { '#', ',' };
  89.            string[] salida = str.Split(separadores, StringSplitOptions.RemoveEmptyEntries);
  90.  
  91.            // Al manipular controles de Windows Forms desde un hilo diferente al
  92.            // hilo de la interfaz de usuario, es necesario usar Invoke para evitar problemas de concurrencia
  93.            if (InvokeRequired)
  94.            {
  95.                Invoke(new Action(() =>
  96.                {
  97.                    UpdateUIControlsVerTabla(salida);
  98.                }));
  99.            }
  100.            else
  101.            {
  102.                UpdateUIControlsVerTabla(salida);
  103.            }
  104.        }
  105.  
  106.        /* Procesar verComandoBReq */
  107.        private void ProcessverComandoBReq(string str)
  108.        {
  109.            verComandoBFlag = false;
  110.            char[] separadores = { '#', 'I', 'O', 'L', 'B', 'V', 'F', 'H', 'R', 'S', '\r'};
  111.            string[] salida = str.Split(separadores, StringSplitOptions.RemoveEmptyEntries);
  112.  
  113.            // Al manipular controles de Windows Forms desde un hilo diferente al
  114.            // hilo de la interfaz de usuario, es necesario usar Invoke para evitar problemas de concurrencia
  115.            if (InvokeRequired)
  116.            {
  117.                Invoke(new Action(() =>
  118.                {
  119.                    UpdateUIControlsVerDatos(salida);
  120.                }));
  121.            }
  122.            else
  123.            {
  124.                UpdateUIControlsVerDatos(salida);
  125.            }
  126.        }
  127.  
  128.        /* Mostrar datos verComandoX72Req */
  129.        private void UpdateUIControlsVerTabla(string[] salida)
  130.        {
  131.            label_Resultado_valores_nonimales_de_alimentacion.Text
  132.               = salida[0] + " VA / " + salida[1] + " W";
  133.            label_Resultado_voltaje_nominal.Text
  134.                = salida[2] + " Vac";
  135.            label_Resultado_corriente_nominal.Text
  136.                = salida[5] + " A";
  137.            label_Resultado_valores_nominales_de_frecuencia.Text
  138.                = salida[3] + " ~ " + salida[4] + " Hz";
  139.        }
  140.  
  141.        /* Mostrar datos verComandoBReq */
  142.        private void UpdateUIControlsVerDatos(string[] salida)
  143.        {
  144.            label_I.Text
  145.                  = salida[0] + " Vac";
  146.            label_O.Text
  147.                = salida[1] + " Vac";
  148.            label_L.Text
  149.                = salida[2].TrimStart('0') + " %"; // Quita los ceros de la izquierda.
  150.            label_B.Text
  151.                = salida[3] + " %";
  152.            label_V.Text
  153.                = salida[4] + " Vdc";
  154.            label_F.Text
  155.                = salida[5].PadRight(5, '0') + " Hz"; // Añade ceros a la derecha.
  156.            label_H.Text
  157.                = salida[6].PadRight(5, '0') + " Hz";
  158.  
  159.            // Convertir variable tipo string a tipo int, es decir, la variable tipo string "salida[7]"
  160.            // se convierte en tipo int "resultadoSalida7".
  161.            int resultadoSalida7 = Int32.Parse(salida[7]);
  162.  
  163.            #region Horas y minutos.
  164.            // Cálculos.
  165.            int horas = resultadoSalida7 / 60;
  166.            int minutos = resultadoSalida7 % 60;
  167.  
  168.            // ¿0 horas y 1 minuto?
  169.            if ((horas == 0) && (minutos == 1))
  170.            {
  171.                label_R.Text = $"{minutos} minuto.";
  172.            }
  173.  
  174.            // ¿0 horas y 0 minuto?
  175.            if ((horas == 0) && (minutos == 0))
  176.            {
  177.                label_R.Text = $"{minutos} minutos";
  178.            }
  179.  
  180.            // ¿0 horas y más de 1 minuto?
  181.            if ((horas == 0) && (minutos > 1))
  182.            {
  183.                label_R.Text = $"{minutos} minutos.";
  184.            }
  185.  
  186.            // ¿1 hora y 0 minutos?
  187.            if ((horas == 1) && (minutos == 0))
  188.            {
  189.                label_R.Text = $"{horas} hora.";
  190.            }
  191.  
  192.            // ¿Más de una hora y 0 minutos?
  193.            if ((horas > 1) && (minutos == 0))
  194.            {
  195.                label_R.Text = $"{horas} horas.";
  196.            }
  197.  
  198.            // ¿1 hora y 1 minuto?
  199.            if ((horas == 1) && (minutos == 1))
  200.            {
  201.                label_R.Text = $"{horas} hora y {minutos} minuto";
  202.            }
  203.  
  204.            // ¿1 hora y más de 1 minuto?
  205.            if ((horas == 1) && (minutos > 1))
  206.            {
  207.                label_R.Text = $"{horas} hora y {minutos} minutos.";
  208.            }
  209.  
  210.            // ¿Más de 1 hora y 1 minuto?
  211.            if ((horas > 1) && (minutos == 1))
  212.            {
  213.                label_R.Text = $"{horas} horas y {minutos} minuto.";
  214.            }
  215.  
  216.            // ¿Más de 1 horas y más de 1 minuto?
  217.            if ((horas > 1) && (minutos > 1))
  218.            {
  219.                label_R.Text = $"{horas} horas y {minutos} minutos.";
  220.            }
  221.            #endregion
  222.        }
  223.  
  224.        /* Evento de botón: Abrir puerto serie y mandar "B" */
  225.        private void button_Comando_B_Click(object sender, EventArgs e)
  226.        {
  227.            if (puertoSerie.IsOpen)
  228.            {
  229.                verComandoBFlag = true;
  230.                puertoSerie.Open();
  231.                puertoSerie.Write(verComandoBReq);
  232.            }
  233.            else
  234.            {
  235.                MessageBox.Show("Puerto cerrado. " +
  236.                "No se puede solicitar datos.");
  237.  
  238.            }
  239.        }
  240.  
  241.        /* Evento de botón: Abrir puerto serie y mandar "X72" */
  242.        private void button1_Click(object sender, EventArgs e)
  243.        {
  244.            if (puertoSerie.IsOpen)
  245.            {
  246.                verComandoX72Flag = true;
  247.                puertoSerie.Open();
  248.                puertoSerie.Write(verComandoX72Req);
  249.            }
  250.            else
  251.            {
  252.                MessageBox.Show("Puerto cerrado. " +
  253.                    "No se puede enviar datos.");
  254.            }
  255.        }
  256.    }
  257. }
  258.  
  259.  

Algo pasa que no me deja abrir el puerto.
« Última modificación: 29 Noviembre 2023, 00:12 am por Meta » En línea

Danielㅤ


Desconectado Desconectado

Mensajes: 1.853


🔵🔵🔵🔵🔵🔵🔵


Ver Perfil
Re: Recibir dos tramas por RS232 diferentes.
« Respuesta #7 en: 29 Noviembre 2023, 00:00 am »

Hola, desactiva el Firewall de Windows o cualquier otro Firewall luego prueba a ejecutar ese programa exe con permisos de administrador y nos comentas las novedades.


Saludos
En línea

Meta


Desconectado Desconectado

Mensajes: 3.501



Ver Perfil WWW
Re: Recibir dos tramas por RS232 diferentes.
« Respuesta #8 en: 29 Noviembre 2023, 00:08 am »

.
« Última modificación: 29 Noviembre 2023, 08:39 am por Meta » En línea

Meta


Desconectado Desconectado

Mensajes: 3.501



Ver Perfil WWW
Re: Recibir dos tramas por RS232 diferentes.
« Respuesta #9 en: 29 Noviembre 2023, 07:25 am »

Buenos días.

El puertoSerie.Open(); se tiene que poner desde el principio, para que quede abierto siempre.

Ahora el programa si funciona.

Lo tendré que pulir después cuando salga de trabajar.

Dejo el código aquí y gracias a tu ayuda ya funciona todo.

A parte de esto, hay más comandos que enviar, espero que tu programa me sirva de ejemplo para que se me ejecuten todos.

Dejar claro que si hay algún error, me por ejemplo, al enviar un comando que no existe me viene con este error:
#-0\r

Si lo has hecho bien, en algunos comando devuelve uno similar pero sin guión en medio -.
#0\r

Otro errores que no se cual es son.
#3\r
#4\r
#10\r

Y no recuerdo más. Son errores que ya pondré en un label.

Código
  1. using System.IO.Ports;
  2.  
  3. namespace Termite_SAI_05_.NET_8._0
  4. {
  5.    public partial class Form1 : Form
  6.    {
  7.        SerialPort puertoSerie;
  8.        bool verComandoBFlag = false;
  9.        bool verComandoX72Flag = false;
  10.        readonly string verComandoBReq = "B\r";
  11.        readonly string verComandoX72Req = "X72\r";
  12.  
  13.        private void Form1_Load(object sender, EventArgs e)
  14.        {
  15.  
  16.        }
  17.  
  18.        public Form1()
  19.        {
  20.            InitializeComponent();
  21.            InitSerialPort();
  22.        }
  23.  
  24.        /* Iniciar y configurar el puerto serie */
  25.        private void InitSerialPort()
  26.        {
  27.            try
  28.            {
  29.                puertoSerie = new SerialPort("COM3", 2400,
  30.                    Parity.None, 8, StopBits.One)
  31.                {
  32.                    Handshake = Handshake.None,
  33.                    ReadTimeout = 500,
  34.                    WriteTimeout = 500,
  35.                    DtrEnable = true,
  36.                    RtsEnable = true,
  37.                    DiscardNull = false,
  38.                    ParityReplace = 63,
  39.                    ReadBufferSize = 4096,
  40.                    WriteBufferSize = 2018,
  41.                    ReceivedBytesThreshold = 1
  42.                };
  43.  
  44.                // Abrir puerto serie.
  45.                puertoSerie.Open();
  46.  
  47.                // Subscribir el evento Sp_DataReceived cuando lleguen datos
  48.                puertoSerie.DataReceived += Sp_DataReceived;
  49.            }
  50.            catch (Exception ex)
  51.            {
  52.                MessageBox.Show(ex.Message);
  53.                puertoSerie.Close(); // Cierra el puerto en caso de error
  54.            }
  55.        }
  56.  
  57.        /* Evento para leer asíncronamente datos del puerto serie */
  58.        void Sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
  59.        {
  60.            if (puertoSerie.IsOpen)
  61.            {
  62.                Task.Run(async () =>
  63.                {
  64.                    try
  65.                    {
  66.                        await Task.Delay(500); // Pausa para recibir datos
  67.                        string str = puertoSerie.ReadExisting();
  68.                        if (!String.IsNullOrEmpty(str))
  69.                        {
  70.                            if (verComandoBFlag) { ProcessverComandoBReq(str); }
  71.                            if (verComandoX72Flag) { ProcessverComandoX72Req(str); }
  72.                        }
  73.                        else
  74.                        {
  75.                            Console.Write("Datos leídos corruptos.");
  76.                        }
  77.                    }
  78.                    catch (IndexOutOfRangeException ex)
  79.                    {
  80.                        Console.Write("Índice fuera de los límites de la matriz.");
  81.                        MessageBox.Show(ex.Message);
  82.                    }
  83.                    catch (FormatException ex)
  84.                    {
  85.                        Console.Write("La cadena de entrada no tiene el formato correcto.");
  86.                        MessageBox.Show(ex.Message, "Error");
  87.                    }
  88.                });
  89.            }
  90.        }
  91.  
  92.        /* Procesar verComandoX72Req */
  93.        private void ProcessverComandoX72Req(string str)
  94.        {
  95.            verComandoX72Flag = false;
  96.            char[] separadores = { '#', ',' };
  97.            string[] salida = str.Split(separadores, StringSplitOptions.RemoveEmptyEntries);
  98.  
  99.            // Al manipular controles de Windows Forms desde un hilo diferente al
  100.            // hilo de la interfaz de usuario, es necesario usar Invoke para evitar problemas de concurrencia
  101.            if (InvokeRequired)
  102.            {
  103.                Invoke(new Action(() =>
  104.                {
  105.                    UpdateUIControlsComandoX72(salida);
  106.                }));
  107.            }
  108.            else
  109.            {
  110.                UpdateUIControlsComandoX72(salida);
  111.            }
  112.        }
  113.  
  114.        /* Procesar verComandoBReq */
  115.        private void ProcessverComandoBReq(string str)
  116.        {
  117.            verComandoBFlag = false;
  118.            char[] separadores = { '#', 'I', 'O', 'L', 'B', 'V', 'F', 'H', 'R', 'S', '\r'};
  119.            string[] salida = str.Split(separadores, StringSplitOptions.RemoveEmptyEntries);
  120.  
  121.            // Al manipular controles de Windows Forms desde un hilo diferente al
  122.            // hilo de la interfaz de usuario, es necesario usar Invoke para evitar problemas de concurrencia
  123.            if (InvokeRequired)
  124.            {
  125.                Invoke(new Action(() =>
  126.                {
  127.                    UpdateUIControlsComandoB(salida);
  128.                }));
  129.            }
  130.            else
  131.            {
  132.                UpdateUIControlsComandoB(salida);
  133.            }
  134.        }
  135.  
  136.        /* Mostrar datos verComandoX72Req */
  137.        private void UpdateUIControlsComandoX72(string[] salida)
  138.        {
  139.            label_Resultado_valores_nonimales_de_alimentacion.Text
  140.               = salida[0] + " VA / " + salida[1] + " W";
  141.            label_Resultado_voltaje_nominal.Text
  142.                = salida[2] + " Vac";
  143.            label_Resultado_corriente_nominal.Text
  144.                = salida[5] + " A";
  145.            label_Resultado_valores_nominales_de_frecuencia.Text
  146.                = salida[3] + " ~ " + salida[4] + " Hz";
  147.        }
  148.  
  149.        /* Mostrar datos verComandoBReq */
  150.        private void UpdateUIControlsComandoB(string[] salida)
  151.        {
  152.            label_I.Text
  153.                  = salida[0] + " Vac";
  154.            label_O.Text
  155.                = salida[1] + " Vac";
  156.            label_L.Text
  157.                = salida[2].TrimStart('0') + " %"; // Quita los ceros de la izquierda.
  158.            label_B.Text
  159.                = salida[3] + " %";
  160.            label_V.Text
  161.                = salida[4] + " Vdc";
  162.            label_F.Text
  163.                = salida[5].PadRight(5, '0') + " Hz"; // Añade ceros a la derecha.
  164.            label_H.Text
  165.                = salida[6].PadRight(5, '0') + " Hz";
  166.  
  167.            // Convertir variable tipo string a tipo int, es decir, la variable tipo string "salida[7]"
  168.            // se convierte en tipo int "resultadoSalida7".
  169.            int resultadoSalida7 = Int32.Parse(salida[7]);
  170.  
  171.            #region Horas y minutos.
  172.            // Cálculos.
  173.            int horas = resultadoSalida7 / 60;
  174.            int minutos = resultadoSalida7 % 60;
  175.  
  176.            // ¿0 horas y 1 minuto?
  177.            if ((horas == 0) && (minutos == 1))
  178.            {
  179.                label_R.Text = $"{minutos} minuto.";
  180.            }
  181.  
  182.            // ¿0 horas y 0 minuto?
  183.            if ((horas == 0) && (minutos == 0))
  184.            {
  185.                label_R.Text = $"{minutos} minutos";
  186.            }
  187.  
  188.            // ¿0 horas y más de 1 minuto?
  189.            if ((horas == 0) && (minutos > 1))
  190.            {
  191.                label_R.Text = $"{minutos} minutos.";
  192.            }
  193.  
  194.            // ¿1 hora y 0 minutos?
  195.            if ((horas == 1) && (minutos == 0))
  196.            {
  197.                label_R.Text = $"{horas} hora.";
  198.            }
  199.  
  200.            // ¿Más de una hora y 0 minutos?
  201.            if ((horas > 1) && (minutos == 0))
  202.            {
  203.                label_R.Text = $"{horas} horas.";
  204.            }
  205.  
  206.            // ¿1 hora y 1 minuto?
  207.            if ((horas == 1) && (minutos == 1))
  208.            {
  209.                label_R.Text = $"{horas} hora y {minutos} minuto";
  210.            }
  211.  
  212.            // ¿1 hora y más de 1 minuto?
  213.            if ((horas == 1) && (minutos > 1))
  214.            {
  215.                label_R.Text = $"{horas} hora y {minutos} minutos.";
  216.            }
  217.  
  218.            // ¿Más de 1 hora y 1 minuto?
  219.            if ((horas > 1) && (minutos == 1))
  220.            {
  221.                label_R.Text = $"{horas} horas y {minutos} minuto.";
  222.            }
  223.  
  224.            // ¿Más de 1 horas y más de 1 minuto?
  225.            if ((horas > 1) && (minutos > 1))
  226.            {
  227.                label_R.Text = $"{horas} horas y {minutos} minutos.";
  228.            }
  229.            #endregion
  230.        }
  231.  
  232.        /* Evento de botón: Abrir puerto serie y mandar "B" */
  233.        private void button_Comando_B_Click(object sender, EventArgs e)
  234.        {
  235.            if (puertoSerie.IsOpen)
  236.            {
  237.                verComandoBFlag = true;
  238.                //puertoSerie.Open();
  239.                puertoSerie.Write(verComandoBReq);
  240.            }
  241.            else
  242.            {
  243.                MessageBox.Show("Puerto cerrado. " +
  244.                "No se puede solicitar datos.");
  245.  
  246.            }
  247.        }
  248.  
  249.        /* Evento de botón: Abrir puerto serie y mandar "X72" */
  250.        private void button1_Click(object sender, EventArgs e)
  251.        {
  252.            if (puertoSerie.IsOpen)
  253.            {
  254.                verComandoX72Flag = true;
  255.                //puertoSerie.Open();
  256.                puertoSerie.Write(verComandoX72Req);
  257.            }
  258.            else
  259.            {
  260.                MessageBox.Show("Puerto cerrado. " +
  261.                    "No se puede enviar datos.");
  262.            }
  263.        }
  264.    }
  265. }

Una cosa muy importante. No sé si se puede corregir con estos código o hay que empezar desde cero.

Para mi s muy buena idea recibir las tramas de Bytes en Bytes y no en string.

¿Es posible hacerlo?


Muchísimas gracias mi muy distinguido amigo.  ;-) ;-) ;-)
« Última modificación: 29 Noviembre 2023, 08:41 am por Meta » En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
rs232
Electrónica
juanjuan19 3 3,837 Último mensaje 10 Febrero 2012, 14:24 pm
por Meta
agregar diferentes arraylist a diferentes jlist
Java
manuhendrix 0 3,023 Último mensaje 20 Febrero 2013, 17:09 pm
por manuhendrix
[pregunta]como separo diferentes threats en diferentes ventanas en windows « 1 2 »
Programación C/C++
daryo 10 5,719 Último mensaje 4 Octubre 2013, 23:10 pm
por daryo
Recibir datos a través de AJAX diferentes divs
Desarrollo Web
itzg3 4 2,496 Último mensaje 10 Abril 2014, 22:36 pm
por itzg3
control rs232 via php
PHP
danny17 2 1,994 Último mensaje 21 Mayo 2014, 14:05 pm
por danny17
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines