none
Problemas al leer datos del puerto serial con c# RRS feed

  • Pregunta

  • Cómo puedo limpiar el buffer de mi puerto serial, debido que tengo un problema al leer una segunda tarjeta rfid, me recuperar el codigo de la tarjeta rfid  anterior y me hace el registro de la otra mas no de la que deberia.

    Cómo podria limpiar mi buffer después de hacer la lectura de una tarjeta?

    La comunicacion lo realizo de la siguiente manera.

       public inicio()
            {
                InitializeComponent();
                mySerialPort = new SerialPort("COM4", 115200, Parity.None, 8, StopBits.One);//comunicacion con el puerto
                if (!mySerialPort.IsOpen)
                {
                    try
                    {
                        mySerialPort.Open();//abrir puerto
                    }
                    catch (System.Exception ex)
                    {
                        MessageBox.Show(ex.ToString());
                    }
                }
                // Ejecutar la funcion recepcion por disparo del evento data received
                mySerialPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(Recepcion);
            }

    Y los datos que resibe ago uso del método registro() para agregar el registro de entrada o salida.

     private void Recepcion(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            {
                //Acumular los caracteres recibidos a nuestro buffer (string)
                datosRecibidos += mySerialPort.ReadExisting();
                
                registro(datosRecibidos);
    
                //Invocar o llamar al proceso de tramas
                //this.Invoke(new EventHandler(Actualizar));
    
            }

    Alguien podra ayudarme porfavor.

    viernes, 1 de junio de 2018 15:32

Respuestas

  • Gracias a todos al parecer ya se logro limpiar el buffer. 

    datosRecibidos  = ""; 

    Utilice esa linea después de mandar a traer mi método Registro.

    Una pregunta, como puedo mostrar mi tabla de registros en un datagridview en el procedimiento alamacenado o después de utilizar el procedimiento almacenado?

    viernes, 8 de junio de 2018 12:10

Todas las respuestas

  • Pues no sé si resolverá su problema, pero para descartar datos, puede usar mySerialPort.DiscardInBuffer().

    Jose R. MCP
    My GIT Repositories | Mis Repositorios GIT

    viernes, 1 de junio de 2018 20:23
    Moderador
  • Esta iria dentro de mi método  Recepción?
    lunes, 4 de junio de 2018 15:22
  • hola

    pero porque tendrias un problema de buffer ? si alli veo que defines el evento DataReceived esto va leyendo a medida que recibe info del puerto

    lo que no veo es porque defines la variable datosRecibidos  de form global y le contatenas los que recibes, porque no solo usas

    string datosRecibidos += mySerialPort.ReadExisting();

    SerialPort.ReadExisting()

    si veo que menciona algo del buffer pero podrias cambiarlo por otro metodo

    ReadLine

    entonces si quien envia los datos envia un salto de linea leera hasta alli

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    lunes, 4 de junio de 2018 17:13
  • Esta iria dentro de mi método  Recepción?
    Yo imagino que sí, después de usar ReadExisting().  Pero como traté de insinuarle antes, no sé si esto resuelve en algo su problema.

    Jose R. MCP
    My GIT Repositories | Mis Repositorios GIT

    lunes, 4 de junio de 2018 19:59
    Moderador
  • Hola:

    using System;
    using System.IO;
    using System.IO.Ports;
    using System.Text;
    using System.Speech.Recognition; // No olvidar. Micro.
    using System.Speech.Synthesis; // No olvidar. Altavoz.
    
    namespace Arduino_Consola_Color_Voz_cs
    {
        class Program
        {
            static void Main(string[] args)
            {
                string COM = "";
    
                // Título de la ventana.
                Console.Title = "Arduino Consola color y voz C#";
    
                // Tamaño ventana consola.
                Console.WindowWidth = 55; // X. Ancho.
                Console.WindowHeight = 18; // Y. Alto.
    
                SerialPort Puerto_serie;
    
                // Crear un nuevo objeto SerialPort con la configuración predeterminada.
                Puerto_serie = new SerialPort();
    
                // Configuración.
                Console.Write(@"
    Introduzca un número para seleccionar puerto COM.
    Por ejemplo el 4, sería COM4.
    
    Puerto: ");
                COM = Console.ReadLine(); // Escribir el número del puerto.
                Console.Clear();
    
                Puerto_serie.PortName = "COM" + COM; // Número del puerto serie.
    
    
                Puerto_serie.BaudRate = 115200; // Baudios.
                Puerto_serie.Parity = Parity.None; // Paridad.
                Puerto_serie.DataBits = 8; // Bits de datos.
                Puerto_serie.StopBits = StopBits.Two; // Bits de parada.
                Puerto_serie.Handshake = Handshake.None; // Control de flujo.
    
                // Establecer la lectura / escritura de los tiempos de espera.
                Puerto_serie.ReadTimeout = 500;
                Puerto_serie.WriteTimeout = 500;
    
                try
                {
                    Puerto_serie.Open(); // Abrir el puerto serie.
                }
    
                catch (IOException)
                {
                    Console.ForegroundColor = ConsoleColor.Red; // Texto en rojo.
                    Console.CursorVisible = false;
                    Console.SetCursorPosition(16, 6);
                    Console.WriteLine(@"El puerto " + Puerto_serie.PortName + @" no existe
                    o no lo encuentra.");
                    Console.ReadKey();   // Pulse cualquier tecla.
                    Environment.Exit(1); // Salir de la aplicación.
                }
    
    
    
                // Detecta cualquier dato recibido.
                Puerto_serie.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
    
                ConsoleKey tecla;
                Console.WriteLine("Pulse tecla 1 para encender, 2 para apagar y \n" +
                    "Escape para salir. \n" +
                    "--------------------------------------------------------------\n");
    
                do
                {
                    tecla = Console.ReadKey(true).Key; // Espera pulsación de teclas.
                                                       // Inicializar una nueva instancia de SpeechSynthesizer.
                    using (SpeechSynthesizer altavoz = new SpeechSynthesizer())
                    {
                        // Configure la salida de audio.
                        altavoz.SetOutputToDefaultAudioDevice();
    
                        // Velocidad de la voz.
                        altavoz.Rate = -2; // Valores entre -10 a 10.
    
                        // Volumen de la voz.
                        altavoz.Volume = 100; // Valores entre 0 y 100.
    
                        switch (tecla)
                        {
                            case ConsoleKey.D1: // Tecla 1 del teclado estandar.
                            case ConsoleKey.NumPad1: // Tecla 1 del número del pad.
                                byte[] miBuffer1 = Encoding.ASCII.GetBytes("Luz_ON"); // Codificación ASCII y guarda en la variable array tipo byte.
                                Puerto_serie.Write(miBuffer1, 0, miBuffer1.Length); // Envía los datos del buffer todo su contenido.
                                Console.ForegroundColor = ConsoleColor.Gray;
                                Console.Write("Comando"); // Muestra en pantalla comandos enviado.
                                Console.ForegroundColor = ConsoleColor.Green;
                                Console.Write(" \"Luz_ON\" ");
                                Console.ForegroundColor = ConsoleColor.Gray;
                                Console.WriteLine("enviado.");
                                Console.ForegroundColor = ConsoleColor.Gray;
                                altavoz.Speak("Luz encendida.");
                                break;
    
                            case ConsoleKey.D2:
                            case ConsoleKey.NumPad2:
                                byte[] miBuffer2 = Encoding.ASCII.GetBytes("Luz_OFF");
                                Puerto_serie.Write(miBuffer2, 0, miBuffer2.Length);
                                Console.ForegroundColor = ConsoleColor.Gray;
                                Console.Write("Comando"); // Muestra en pantalla comandos enviado.
                                Console.ForegroundColor = ConsoleColor.Green;
                                Console.Write(" \"Luz_OFF\" ");
                                Console.ForegroundColor = ConsoleColor.Gray;
                                Console.WriteLine("enviado.");
                                Console.ForegroundColor = ConsoleColor.Gray;
                                altavoz.Speak("Luz apagada.");
                                break;
    
                            case ConsoleKey.Escape:
                                Console.WriteLine("Saliendo...");
                                altavoz.Speak("Saliendo.");
                                break;
    
                            default:
                                Console.WriteLine("Tecla el 1, el 2 y Escape para salir.");                          
                                break;
                        }
                    }
                } while (tecla != ConsoleKey.Escape); // Pulsa Escape para salir del menú.
    
                Console.ForegroundColor = ConsoleColor.Yellow;
    
                Console.WriteLine();
                Console.WriteLine("╔═════════════════════════════════════════════════════╗");
                Console.WriteLine("║ Electrónica PIC                 metaconta@gmail.com ║");
                Console.WriteLine("║                                                     ║");
                Console.WriteLine("║               Ángel Acaymo M. G.                    ║");
                Console.WriteLine("╚═════════════════════════════════════════════════════╝");
                Console.WriteLine();
    
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine("Pulse cualquier tecla para salir...");
                Console.WriteLine();
                Console.ReadKey(); // Espera pulsar una tecla cualquiera.
                Puerto_serie.Close(); // Cierra el puerto serie.
            }
    
            // Detecta cualquier dato entrante.
            private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
            {
                SerialPort sp = (SerialPort)sender;
                string entradaDatos = sp.ReadExisting(); // Almacena los datos recibidos en la variable tipo string.
                Console.ForegroundColor = ConsoleColor.Gray;
                Console.Write("Dato recibido desde Arduino: "); // Muestra en pantalla los datos recibidos.
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(entradaDatos + "\n");
                Console.ForegroundColor = ConsoleColor.Gray;
            }
    
            // Maneje el evento SpeechRecognized.
            static void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
            {
                Console.WriteLine("Texto reconocido: " + e.Result.Text);
    
                string palabras = e.Result.Text;
            }
        }
    }

    Más información del puerto serie en modo consola.

    Ver tutortial.

    Cualquier tema sobre peurto serie, se hace en esta sección del foro.

    Si quieres borrar datos del buffer, solamente tiene que hacer esto.

    datosRecibidos  = ""; 
    Saludos.


    http://electronica-pic.blogspot.com



    • Editado Metaconta martes, 5 de junio de 2018 15:15
    martes, 5 de junio de 2018 15:11
  • Hola Leandro buen dia!!

    Entonces no necesito limpiar mi buffer?

    O tendre algun problema en mi método registro() ?

    Este es el código que utilizo a través de un procedimiento almacenado.

    public void registro(string datosRecibidos)//Metodo Registro E/S
            {
               // string[] split = datosRecibidos.Split(new char[] { '\r' }, 2);
    
                string cadena = datosRecibidos;
                string split = cadena.Substring(1, 20);
               
               
                try
                {
                    con.Open();
                    SqlCommand cmd = new SqlCommand("ValidarTag", con);
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@idC", split);
                    SqlParameter ValorRetorno = new SqlParameter("@pMessage", SqlDbType.VarChar, 50);
                    //asignamos el valor de retorno
                    ValorRetorno.Direction = ParameterDirection.Output;
                    cmd.Parameters.Add(ValorRetorno);
                    //declaramos el parámetro de retorno
                    SqlParameter ValorRetorno2 = new SqlParameter("@pMessage2", SqlDbType.VarChar, 50);
                    //asignamos el valor de retorno
                    ValorRetorno2.Direction = ParameterDirection.Output;
                    cmd.Parameters.Add(ValorRetorno2);
                    SqlParameter ValorRetorno3 = new SqlParameter("@pMessage3", SqlDbType.VarChar, 50);
                    //asignamos el valor de retorno
                    ValorRetorno3.Direction = ParameterDirection.Output;
                    cmd.Parameters.Add(ValorRetorno3);
                    //executamos la consulta
                    cmd.ExecuteNonQuery();
                    // traemos el valor de retorno
                   
                   String mesa = Convert.ToString(ValorRetorno.Value);
                   String mesa2 = Convert.ToString(ValorRetorno2.Value);
                   String mesa3 = Convert.ToString(ValorRetorno3.Value);
                  
                    if ( mesa != "" ) 
                    {
                        MessageBox.Show(mesa + split);
                       //mostrarReg(); 
                    }
                    else if (mesa2 != "") 
                    {
                        MessageBox.Show(mesa2);
                       // mostrarReg();
            
                    }
                    else if (mesa3 != "")
                    {
                        MessageBox.Show(mesa3);
                        //mostrarReg();
                       
                    }
                 else
                     {
                         MessageBox.Show("No se realizo el registro" + split);
                        // mostrarReg(); 
    
                     }
                 
                    
                }
    
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }
                finally
                {
                    con.Close();
                }
                
    
            }
            


    • Editado Dhaniel..M martes, 5 de junio de 2018 18:22
    martes, 5 de junio de 2018 18:20
  • Ya te lo dije, el buffer se limpia así;

    datosRecibidos  = ""; // limpiar buffer.

    Lo pones al final de todo cuando deje de entrar datos.


    http://electronica-pic.blogspot.com

    miércoles, 6 de junio de 2018 5:28
  • Ya te lo dije, el buffer se limpia así;

    datosRecibidos  = ""; // limpiar buffer.

    Lo pones al final de todo cuando deje de entrar datos.


    http://electronica-pic.blogspot.com

    No lo es, lo siento.  Debo aclarar este punto como moderador.  datosRecibidos parece ser una variable tipo string y punto.  El buffer del puerto serial está contenido dentro del objeto de puerto.  La variable datosRecibidos simplemente es una variable externa al objeto del puerto serial.

    Jose R. MCP
    My GIT Repositories | Mis Repositorios GIT

    miércoles, 6 de junio de 2018 7:19
    Moderador
  • Entonces lo que necesito es limpiarlo desde mi objeto?
    miércoles, 6 de junio de 2018 12:30
  • Hola:

    If you are using the System.IO.Ports.SerialPort then you could use the two methods:

    DiscardInBuffer() and DiscardOutBuffer() to flush the buffers.

    If you are reading the data from a serial port:

    private void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        if (!this.Open) return; // We can't receive data if the port has already been closed.  This prevents IO Errors from being half way through receiving data when the port is closed.
        string line = String.empty;
        try
        {
            line = _SerialPort.ReadLine();
            line = line.Trim();
           //process your data if it is "DATA C", otherwise ignore
        }
        catch (IOException ex)
        {
            //process any errors
        }
    }

    https://stackoverflow.com/questions/11571522/clear-serial-port-receive-buffer-in-c-sharp

    https://www.e-learn.cn/content/wangluowenzhang/290154


    http://electronica-pic.blogspot.com

    miércoles, 6 de junio de 2018 15:20
  • Esta linea aun la necesitaria?

    // Detecta cualquier dato recibido.
                Puerto_serie.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
    

    miércoles, 6 de junio de 2018 18:12
  • Esta linea aun la necesitaria?

    // Detecta cualquier dato recibido.
                Puerto_serie.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);


    Esa línea es para recibir con el += para concatenar los datos recibidos.

    http://electronica-pic.blogspot.com

    jueves, 7 de junio de 2018 19:58
  • Gracias a todos al parecer ya se logro limpiar el buffer. 

    datosRecibidos  = ""; 

    Utilice esa linea después de mandar a traer mi método Registro.

    Una pregunta, como puedo mostrar mi tabla de registros en un datagridview en el procedimiento alamacenado o después de utilizar el procedimiento almacenado?

    viernes, 8 de junio de 2018 12:10
  • Gracias a todos al parecer ya se logro limpiar el buffer. 

    datosRecibidos  = ""; 

    Utilice esa linea después de mandar a traer mi método Registro.

    Una pregunta, como puedo mostrar mi tabla de registros en un datagridview en el procedimiento alamacenado o después de utilizar el procedimiento almacenado?

    ¿Vez?

    Te había dicho que se limpia con

    datosRecibidos  = ""; 

    Lo del datagridview, primero nos cuenta como son esos datos dices, luego lo interpretamos.

    Ver vídeo.

    Saludos.


    http://electronica-pic.blogspot.com

    jueves, 30 de julio de 2020 17:00