none
Intentar hacer este código de lo más sencillo RRS feed

  • Pregunta

  • Hola:

    Estoy intentando de C# en modo consola enviar y recibir datos por el puerto serie.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using System.IO.Ports; // No olvidar.
    using System.Threading;
    
    namespace Puerto_serie_consola_CS
    {
        class Program
        {
            string Recibidos; // Utilizaremos un string como buffer de recepción.
            static SerialPort Puerto_serie;
            string Recepcion; // Variable recepción de datos.
    
            static void Main(string[] args)
            {
                Console.Title = "Puerto serie C#";
    
                StringComparer Compara_String = StringComparer.OrdinalIgnoreCase;
                // Thread Leer_hilo = new Thread(Read);
    
                // Crear un nuevo objeto SerialPort con la configuración predeterminada.
                Puerto_serie = new SerialPort();
    
                // Configuración.
                Puerto_serie.PortName = "COM1"; // 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;
    
                Puerto_serie.Open(); // Abrir puerto serie.
    
                string Recepcion = Puerto_serie.ReadLine();
    
                Puerto_serie.DataReceived += new SerialDataReceivedEventHandler(Recepcion);
    
                        
                        Console.WriteLine(Recepcion);
    
        }
    
            // Al recibir datos.
            private void Recepcion(object sender, SerialDataReceivedEventArgs e)
            {
                // Acumula los caracteres recibidos a nuestro 'buffer' (string).
                Recibidos += Puerto_serie.ReadExisting();
    
                // Invocar o llamar al proceso de tramas.
                Invoke(new EventHandler(Actualizar));
            }
    
            // Procesar los datos recibidos en el bufer y extraer tramas completas.
            private void Actualizar(object sender, EventArgs e)
            {
                Console.WriteLine(Recibidos);
            }
        }
    }

    Me da estos errores.

    Si se puede hacer el código sencillo, como enviar y recibir dator por el puerto serie, mejor que mejor, en moco consola C#.

    Gracias.


    http://electronica-pic.blogspot.com

    miércoles, 9 de diciembre de 2015 17:12

Todas las respuestas

  • Sugerencia:

    Antes de pasearte por varios lenguajes  (note que quieres probar de todo a lo que le llamas diversión o aventura) es bueno que profundices en temas básicos, no puedes pretender programar con tan sólo digitar sin fundamento o hacer copy-paste, inicia tu carrera con la revisión de temas básicos, consideralo.

    El primer error menciona que no puedes declarar un método con el nombre de un atributo. Recepción es un atributo y un método

    miércoles, 9 de diciembre de 2015 17:16
  • Hola

    string Recepcion = Puerto_serie.ReadLine();

    private void Recepcion(object sender, SerialDataReceivedEventArgs e)

    Recepcion se llama igual que el metodo y por eso el error el compilador no se aclara, cambia esa variable, es mas creo que no es necesaria donde la tienes.


    Es de buena educación dar las gracias cuando te ayudan, si alguna respuesta te ha sido útil agradécelo marcándola como útil.



    • Editado Rodripelto miércoles, 9 de diciembre de 2015 17:19
    miércoles, 9 de diciembre de 2015 17:18
  • Hola Rodripelto,

    No, en realidad el conflicto no es con la variable Recepción que está dentro del método Main porque esa variable tiene ámbito del método, el conflicto es con el atributo Recepción que está definida al nivel de la clase y al mismo nivel hay un método con el mismo nombre

    string Recepcion; // Variable recepción de datos.

    miércoles, 9 de diciembre de 2015 17:24
  • Hola Williams.

    string Recepcion = Puerto_serie.ReadLine(); Puerto_serie.DataReceived += new SerialDataReceivedEventHandler(Recepcion);

    Entonces cres que el comflicto no esta aquí, que no sabe si apuntar al (metodo evento) o al string.

    Bueno da lo mismo, el caso es que tiene un conflicto con Recepción.

    Es de buena educación dar las gracias cuando te ayudan, si alguna respuesta te ha sido útil agradécelo marcándola como útil.



    • Editado Rodripelto miércoles, 9 de diciembre de 2015 17:31
    miércoles, 9 de diciembre de 2015 17:29
  • Hola:

    También en Invoke.

    ¿Cómo lo harían el código?

    A lo mejor en vuentra manera no falla.

    Con Windows Form me funciona bien, en modo consola, me cuesta mucho.

    En el vídeo de abajo muestra como recibe comandos y mensajes desde un dispositivo. Es lo que quiero hacer, también enviar mensajes.

    Ver vídeo.

    Saludos.



    • Editado Metaconta jueves, 10 de diciembre de 2015 0:14
    miércoles, 9 de diciembre de 2015 22:17
  • Hola Metaconta.

    Para usar un Invoke lo mas seguro que necesites delegados.

    ¿El evento Actualizar tiene que ser un evento o podria ser un metodo? Podria ser algo así.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using System.IO.Ports; // No olvidar.
    using System.Threading;
    
    namespace Puerto_serie_consola_CS
    {
        class Program
        {
            string Recibidos; // Utilizaremos un string como buffer de recepción.
            static SerialPort Puerto_serie;
            string Recepcion; // Variable recepción de datos.
    public delegate void midelegado(string mensaje);// Creo delegado con la misma firma que metodo a utilizar
            static midelegado delegadomensaje = new midelegado(Actualizar);// Instancio delegado y le apunto el metodo que utilizara
    
            static void Main(string[] args)
            {
                Console.Title = "Puerto serie C#";
    
                StringComparer Compara_String = StringComparer.OrdinalIgnoreCase;
                // Thread Leer_hilo = new Thread(Read);
    
                // Crear un nuevo objeto SerialPort con la configuración predeterminada.
                Puerto_serie = new SerialPort();
    
                // Configuración.
                Puerto_serie.PortName = "COM1"; // 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;
    
                Puerto_serie.Open(); // Abrir puerto serie.
    
               // string Recepcion = Puerto_serie.ReadLine();// No es necesario.
    
                Puerto_serie.DataReceived += new SerialDataReceivedEventHandler(Recepcion_Evento);
    
                        
                        //Console.WriteLine(Recepcion);// Inecesario escribe en consola una variable que siempre estara vacia y se cerrara la consola
    Console.ReadLine();// Necesario para que no se cierre la consola
        }
    
            // Al recibir datos.
            private void Recepcion_Evento(object sender, SerialDataReceivedEventArgs e)
            {
                // Acumula los caracteres recibidos a nuestro 'buffer' (string).
                Recibidos += Puerto_serie.ReadExisting();
    
                // Invocar o llamar al proceso de tramas.
                //Invoke(new EventHandler(Actualizar));
    delegadomensaje.Invoke(Recibidos);
            }
    
    //        // Procesar los datos recibidos en el bufer y extraer tramas completas.
    //        private void Actualizar(object sender, EventArgs e)// Creo que no tiene por que ser un evento
            //{
              //  Console.WriteLine(Recibidos);
           // }
    static void Actualizar(string mensaje) // Mejor un metodo
            {
                System.Console.WriteLine(mensaje);
            }
        }
    }



    Es de buena educación dar las gracias cuando te ayudan, si alguna respuesta te ha sido útil agradécelo marcándola como útil.

    jueves, 10 de diciembre de 2015 9:23
  • Hola:

    Ignorando la variabnle que no se usa por lo que veo.

    //string Recepcion; // Variable recepción de datos.

    Tu código me da este error.

    Gravedad    Código    Descripción    Proyecto    Archivo    Línea
    Error    CS0120    Se requiere una referencia de objeto para el campo, método o propiedad 'Program.Recepcion_Evento(object, SerialDataReceivedEventArgs)' no estáticos    Puerto_serie_consola_CS    C:\Users\Usuario\Documents\Visual Studio 2015\Projects\Puerto_serie_consola_CS\Puerto_serie_consola_CS\Program.cs    47

    Si lo que he programado no funciona, pues hacerlo mejor en el sentido que de funciona, tanto enviar mensajes de texto como recibirlos.

    Parece que falta menos para llegar al funcionamiento final.

    Saludos.


    http://electronica-pic.blogspot.com

    jueves, 10 de diciembre de 2015 15:34
  • Hola

     private void Recepcion_Evento(object sender, SerialDataReceivedEventArgs e)

    por

     static void Recepcion_Evento(object sender, SerialDataReceivedEventArgs e)

    al estar en el main que es estatico creo que es así.


    Es de buena educación dar las gracias cuando te ayudan, si alguna respuesta te ha sido útil agradécelo marcandola como útil.

    BLOG


    • Editado Rodripelto jueves, 10 de diciembre de 2015 16:55
    jueves, 10 de diciembre de 2015 16:53
  • Sale este error.

    Gravedad    Código    Descripción    Proyecto    Archivo    Línea
    Error    CS0120    Se requiere una referencia de objeto para el campo, método o propiedad 'Program.Recibidos' no estáticos    Puerto_serie_consola_CS    C:\Users\Usuario\Documents\Visual Studio 2015\Projects\Puerto_serie_consola_CS\Puerto_serie_consola_CS\Program.cs    62

    Señalando en la variable Recibidos.


    http://electronica-pic.blogspot.com

    jueves, 10 de diciembre de 2015 18:42
  • Hola:

    Antes que nada, ya que es modo consola, lo pongo en español bien español.

    Enviar datos:

    1. Configuración del puerto serie.

    2. Abrir puerto.

    3. La consola espera que introduza datos.

    4. Al introducir datos, lo guarda en una variable string, da igual lo que escribas, letras, números o símbolos.

    5. Si pulsas Enter envía datos al puerto serie.

    Recibir datos:

    1. La Consola está en espera de recibir algún dato.

    2. Lo guarda en una variable string.

    3. La Consola muestra en pantalla los datos recibidos.

    4. Si cierra la consola o palicación, cierra el puerto.

    El código de enviar datos que he hecho paso a paso es este.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using System.IO.Ports; // No olvidar.
    using System.Threading;
    
    namespace Puerto_serie_consola_CS
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.Title = "Puerto serie C#";
    
                string Enviar_datos = "";
               
                SerialPort Puerto_serie;
    
                // Crear un nuevo objeto SerialPort con la configuración predeterminada.
                Puerto_serie = new SerialPort();
    
                // Configuración.
                Puerto_serie.PortName = "COM4"; // 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;
    
                while (true)
                {
                    Console.WriteLine("Introduce comandos:"); // Muestra texto en pantalla.
                    Enviar_datos = Console.ReadLine(); // Almacena los datos introducidos en consola a la variable.
    
                    switch (Enviar_datos)
                    {
                        case "Led_ON":
                            Puerto_serie.Open(); // Abrir puerto serie.
                            byte[] miBuffer = Encoding.ASCII.GetBytes(Enviar_datos); // Guarda un array los datos y codificado en ASCII.
                            Puerto_serie.Write(miBuffer, 0, miBuffer.Length); // Envía al puerto el array almacenado del buffer.
                            Console.WriteLine(); // Salto de línea.
    
                            //Puerto_serie.Write(Enviar_datos); // Con solo esta línea también vale pero no está codificado.
    
                            Puerto_serie.Close(); // Cerrar puerto serie.
                            break;
    
                        case "Led_OFF":
                            Puerto_serie.Open(); // Abrir puerto serie.
                            byte[] miBuffer2 = Encoding.ASCII.GetBytes(Enviar_datos); // Guarda un array los datos y codificado en ASCII.
                            Puerto_serie.Write(miBuffer2, 0, miBuffer2.Length); // Envía al puerto el array almacenado del buffer.
                            Console.WriteLine(); // Salto de línea.
    
                            //Puerto_serie.Write(Enviar_datos); // Con solo esta línea también vale pero no está codificado.
    
                            Puerto_serie.Close(); // Cerrar puerto serie.
                            break;
                    }
                }
            }
        }
    }


    Antes de empezar con la parte de recibir datos. Quiero que me aconsejen si así está bien programado o se puede mejorar con más fundamento y estilo.

    Un cordial saludo.


    http://electronica-pic.blogspot.com




    • Editado Metaconta viernes, 11 de diciembre de 2015 5:19
    viernes, 11 de diciembre de 2015 4:27
  • Buenos días

    En primer lugar, escribir el programa en el método main no es una buena idea, como habrás visto es un método estático y por ello requiere declarar cosas estáticas cuando no deberían de ser estáticas. Por ejemplo

    static void Recepcion_Evento(object sender, SerialDataReceivedEventArgs e)

    que no tiene que ser estático, por lo tanto lo que tendrías que hacer es encapsular toda la parte de comunicación en una clase a parte, esta clase tendría que tener propiedades  de lectura y escritura para la parte configurable del puerto como, com, baudios y el resto de configuración del puerto y todas las que se te ocurran susceptibles de configuración, también un método encargado de tratar los datos, quizá un método encargado de abrir y cerrar el puerto, un método encargado de escribir el dato recibido en consola o que lo exponga públicamente para poder acceder a él como por ejemplo.

    static void Actualizar(string mensaje) // Mejor un metodo
            {
                System.Console.WriteLine(mensaje);
            }

    este método ya no debería de ser estático.

    Por otro lado en tu código en la parte del case, en un principio no veo diferencia alguna entre Led_On y Led_Off, por lo tanto creo que sobra el case.

    Y de momento no se me ocurre mas, espero que lo comentado te sea de utilidad.

    Un saludo.


    Es de buena educación dar las gracias cuando te ayudan, si alguna respuesta te ha sido de utilidad agradécelo marcandola como útil.




    • Editado Rodripelto viernes, 11 de diciembre de 2015 9:00
    viernes, 11 de diciembre de 2015 8:27
  • Hola:

    Por eso decía, que antes de continuar, hay que mejorar el código por si alguien sabe hacerlo como es debido, no al estilo chapuza que hice.

    El case, si hay diferencia en tre el Led_ON y el Lef_OFF, es enviar esos comandos hacia fuera, por el peurto serie que es lo que entiende el dispositivo externo y funciona.PAra que te hagas una idea, el código de este dispositivo llamado Arduino es este.

    int pinLed =  13;   // Declaramos la variable pin del Led.
    char caracter;
    String comando;
    
    void setup()
    {
      Serial.begin(115200);
    }
    
    void loop()
    {
      pinMode(pinLed, OUTPUT);  // Inicializa el pin del Led 1 como salida.
      /* Voy leyendo carácter a carácter lo que se recibe por el canal
       *  serie (mientras llegue algún dato allí), y los voy concatenando
       *  uno tras otro en una cadena. En la práctica, si usamos el
       *  "Serial monitor" el bucle while acabará cuando pulsemos Enter.
       *  El delay es conveniente para no saturar el canal serie y que la
       *  concatenación se haga de forma ordenada.
       */
      while (Serial.available() > 0)
      {
        caracter= Serial.read();
        comando.concat(caracter);
        delay(10);
      }
    
      /* Unavez ya tengo la cadena "acabada", compruebo su valor y hago
       * que la placa Arduino reaccione según sea este. Aquí podríamos
       * hacer lo que quiesiéramos: si el comando es "tal", enciende
       * un Led, si es cual, mueve un motor... y así.
       */
      if (comando.equals("Led_ON") == true)
      {
            digitalWrite(pinLed, HIGH); // Enciende el Led.
            Serial.println("Led 13 encendido.");
      }
            
      if (comando.equals("Led_OFF") == true)
      {
            digitalWrite(pinLed, LOW); // Apaga el Led.
            Serial.println("LEd 13 apagado.");
      } 
      
      // Limpiamos la cadena para volver a recibir el siguiente comando. 
      comando="";
    }

    Aquí abajo hay dos enlaces, son de Visual Basic pero no encuentro el de Visual C#, no se si lo habrán hecho, es bueno pero solo para este lenguaje.

    Cómo: Enviar cadenas a puertos serie en Visual Basic.

    Cómo: Recibir cadenas de puertos serie en Visual Basic.

    Repito, antes de continuar, quiero un buen código.

    Sludos.


    http://electronica-pic.blogspot.com

    viernes, 11 de diciembre de 2015 11:15
  • El case, si hay diferencia en tre el Led_ON y el Lef_OFF, es enviar esos comandos hacia fuera, por el peurto serie que es lo que entiende el dispositivo externo y funciona.PAra que te hagas una idea, el código de este dispositivo llamado Arduino es este.

    Pue lo siento mucho, pero sigo sin ver la diferencia en el codigo.

    Puerto_serie.Open(); // Abrir puerto serie.
    byte[] miBuffer = Encoding.ASCII.GetBytes(Enviar_datos); // En los dos codificas Enviar_datos
    Puerto_serie.Write(miBuffer, 0, miBuffer.Length); // Aquí envia los datos si Enviar_datos trae Led_On eviara Led_On y si trae Led_Off enviara Led_Off
    Console.WriteLine(); // Salto de línea.

    en los dos casos envias lo que trae Enviar_datos sin ninguna otra distinción, por lo tanto creo que no es necesario saber que contiene, lo envias y listo.

    En el codigo que has puesto si hay una pequeña diferencia

     if (comando.equals("Led_ON") == true)
      {
            digitalWrite(pinLed, HIGH); // Enciende el Led.
            Serial.println("Led 13 encendido.");
      }
            
      if (comando.equals("Led_OFF") == true)
      {
            digitalWrite(pinLed, LOW); // Apaga el Led.
            Serial.println("LEd 13 apagado.");
      } 

    la variable HIGH o LOW que contendran cosas distintas. Pero en el tuyo o almenos en el que has puesto no.



    Es de buena educación dar las gracias cuando te ayudan, si alguna respuesta te ha sido de utilidad agradécelo marcandola como útil.
    Blog


    • Editado Rodripelto viernes, 11 de diciembre de 2015 11:47
    viernes, 11 de diciembre de 2015 11:41
  • Aaaaaaaaaaaaaaaaaarrrrrrrrrrrrrrggggggg.

    Ya se que te refieres. No lo hice bien. Cuando escribe en la consola Led_ON o Led_OFF, se guarda en la variable llamada Enviar_datos.

    Código fuente Enviar datos:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using System.IO.Ports; // No olvidar.
    using System.Threading;
    
    namespace Puerto_serie_consola_CS
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.Title = "Puerto serie C#";
    
                string Enviar_datos = "";
               
                SerialPort Puerto_serie;
    
                // Crear un nuevo objeto SerialPort con la configuración predeterminada.
                Puerto_serie = new SerialPort();
    
                // Configuración.
                Puerto_serie.PortName = "COM4"; // 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;
    
                while (true)
                {
                    Console.WriteLine("Introduce comandos:"); // Muestra texto en pantalla.
                    Enviar_datos = Console.ReadLine(); // Almacena los datos introducidos en consola a la variable.
    
    
                            Puerto_serie.Open(); // Abrir puerto serie.
                            byte[] miBuffer = Encoding.ASCII.GetBytes(Enviar_datos); // Guarda un array los datos y codificado en ASCII.
                            Puerto_serie.Write(miBuffer, 0, miBuffer.Length); // Envía al puerto el array almacenado del buffer.
                            Console.WriteLine(); // Salto de línea.
    
                            //Puerto_serie.Write(Enviar_datos); // Con solo esta línea también vale pero no está codificado.
    
                            Puerto_serie.Close(); // Cerrar puerto serie.
                }
            }
        }
    }

    Parece ser que está acabdo la parte de enviar, ahora toca recibir datos.

    Recibir datos:

    1. La Consola está en espera de recibir algún dato.

    2. Lo guarda en una variable string.

    3. La Consola muestra en pantalla los datos recibidos.

    4. Si cierra la consola o palicación, cierra el puerto.

    Antes que nada, parece ser que siempre abro y cierro el puerto todo el rato. Esto habrá que modiciarlo al final.

    Sigo experimentando como hago lo de recibir datos in problemas, aquí muestra los datos recibidos desde el puerto serieo con Arduino y PIC.

    Por cierto, quiero saber cuando detecta los puertos que hay.

    Cómo: Mostrar los puertos serie disponibles en Visual Basic.

    En C# sería algo así.

    public void GetSerialPortNames()
    {
    	// Show all available COM ports.
    	foreach (string sp in My.Computer.Ports.SerialPortNames) {
    		ListBox1.Items.Add(sp);
    	}
    }

    Donde pone

    ListBox1.Items.Add(sp);

    Abrá que cambiarlo a Console.WriteLine(sp); me imagino.

    Gracias.


    http://electronica-pic.blogspot.com


    • Editado Metaconta viernes, 11 de diciembre de 2015 17:44
    viernes, 11 de diciembre de 2015 17:30