Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   .NET (https://www.clubdelphi.com/foros/forumdisplay.php?f=17)
-   -   Detectar tramas de bytes (https://www.clubdelphi.com/foros/showthread.php?t=96489)

REHome 15-11-2023 20:51:52

Detectar tramas de bytes
 
Hola:

Teniendo esta entrada de bytes por el puerto serie:
#I225.7O226.2L006B100V25.7F50.2H50.2R0080S€„€ˆ„À

O otra trama de byte diferente como este:
#2000,1400,230,45.0,55.0,8.6

Si se fijan, cada trama de bytes empieza por #.

Haciendo pruebas dando las gracias a los compañeros de este foro, quiero saber si a la entrada de datos es capaz de detectar cada trama de byte recibida se muestre correctamente en sus label como indica abajo.


Ver zoom.

Su código es este:
Código:

using System;
using System.Windows.Forms;

namespace Termite_SAI_03
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button_Ver_datos_Click(object sender, EventArgs e)
        {
            string entrada = "#I225.7O226.2L006B100V25.7F50.2H50.2R0080S€„€ˆ„À";

            char[] separadores = { '#', 'I', 'O', 'L', 'B', 'V', 'F', 'H', 'R', 'S' };

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

            label_I.Text = salida[0] + " V";
            label_O.Text = salida[1] + " V";
            label_L.Text = salida[2].TrimStart('0') + " %"; // Quita los ceros de la izquierda.
            label_B.Text = salida[3] + " %";
            label_V.Text = salida[4] + " V";
            label_F.Text = salida[5] + " Hz";
            label_H.Text = salida[6] + " 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.";
            }
        }

        private void button_Ver_Tabla_Click(object sender, EventArgs e)
        {
            string entrada2 = "#2000,1400,230,45.0,55.0,8.6";

            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] + " V";
            label_Resultado_corriente_nominal.Text = salida2[5] + " A";
            label_Resultado_valores_nominales_de_frecuencia.Text = salida2[3] + " ~ " + salida2[4] + " Hz";
        }
    }
}

Por ahora no te tocado nada del puerto serie, solo muestro con botones de prueba a la hora de recibir datos y mostrar su información en Windows Form.

Saludos.

tsk 16-11-2023 00:30:58

Supongo que la trama viene después de enviar un comando, y dado que conoces dicho comando podrías usar un diccionario para aplicarle a la trama recibida el tratamiento correspondiente.

Aquí te muestro dos formas en que lo podrías hacer. En la primera tienes funciones específicas para cada comando y, en la segunda, tienes una sola función para todos los comandos.

Código PHP:

using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;

public class 
Dict
{
    public static 
void Main()
    {
        
IDictionary<string,Func<string,string[]>> d0 = new Dictionary<string,Func<string,string[]>>();
        
IDictionary<string,stringd1 = new Dictionary<string,string>();

        
d0.Add("Comando1",func1);
        
d0.Add("Comando2",func2);

        
d1.Add("Comando1","Patron 1");
        
d1.Add("Comando2","Patron 2");

        
d0["Comando1"]("Frame 1");
        
d0["Comando2"]("Frame 2");

        
func3("Frame 1"d1["Comando1"]);
        
func3("Frame 2"d1["Comando2"]);
    }

    private static 
string[] func1(string frame)
    {
        
Console.WriteLine("Entra a func1 y el frame es {0}",frame);
        return new [] {
"0001","00002"};
    }

    private static 
string[] func2(string frame)
    {
        
Console.WriteLine("Entra a func2 y el frame es {0}",frame);
        return new [] {
"0001","00002"};
    }

    private static 
string[] func3(string framestring pattern)
    {
        
Console.WriteLine("Entra a func3 y el frame es {0} y este es el patron {1}",frame,pattern);
        return new [] {
"0001","00002"};
    }



Código:

Entra a func1 y el frame es Frame 1
Entra a func2 y el frame es Frame 2
Entra a func3 y el frame es Frame 1 y este es el patron Patron 1
Entra a func3 y el frame es Frame 2 y este es el patron Patron 2


También dale un rato a aprender expresiones regulares, esto fue algo así de rápido, por lo que no está completo, pero ve lo que puede hacer

Código PHP:

using System;
using System.Text.RegularExpressions;

public class 
Mr
{
    public static 
void Main()
    {
        
string pattern = @"([A-Z])([\d]*[\.]*[\d]*)|([\d]*[\.]*[\d]*)[,]*";
        
Regex rx = new Regex(pattern,
                
RegexOptions.Compiled RegexOptions.IgnoreCase);

        
string text "#I225.7O226.2L006B100V25.7F50.2H50.2R0080S€„€ˆ„À#2000,1400,230,45.0,55.0,8.6";

        
MatchCollection matches rx.Matches(text);

        foreach(
Match match in matches)
        {
            if(
match.Value != ""){
                
Console.WriteLine(match.Groups.Count);
                
Console.WriteLine("{0} : {1} : {2} : {3} : {4}",match.Value,
                                                          
match.Groups[0].Value,
                                                          
match.Groups[1].Value,
                                                          
match.Groups[2].Value,
                                                          
match.Groups[3].Value);
            }
        }
            
    }


Código:

4
I225.7 : I225.7 : I : 225.7 :
4
O226.2 : O226.2 : O : 226.2 :
4
L006 : L006 : L : 006 :
4
B100 : B100 : B : 100 :
4
V25.7 : V25.7 : V : 25.7 :
4
F50.2 : F50.2 : F : 50.2 :
4
H50.2 : H50.2 : H : 50.2 :
4
R0080 : R0080 : R : 0080 :
4
S : S : S :  :
4
2000, : 2000, :  :  : 2000
4
1400, : 1400, :  :  : 1400
4
230, : 230, :  :  : 230
4
45.0, : 45.0, :  :  : 45.0
4
55.0, : 55.0, :  :  : 55.0
4
8.6 : 8.6 :  :  : 8.6


REHome 21-11-2023 03:40:13

Muchas gracias mi muy distinguido amigo. :)


La franja horaria es GMT +2. Ahora son las 23:53:15.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi