Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Spanish
  4. Enviar carácteres con un botón por el puerto serial
Forum Update on Monday, May 27th 2025

Enviar carácteres con un botón por el puerto serial

Scheduled Pinned Locked Moved Unsolved Spanish
5 Posts 3 Posters 5.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Alan_641A Offline
    Alan_641A Offline
    Alan_641
    wrote on last edited by
    #1

    Buen día, estoy intentando enviar simples carácteres por el puerto serial presionando botones en una GUI pero no sé como programar el puerto serial, ya revisé los pocos ejemplos que incluye la IDE pero son algo rebuscados para lo que necesito.
    Alguien me podría dar un código de ejemplo para mandar la letra "a" con un botón al puerto "COM3".
    Gracias.

    1 Reply Last reply
    0
    • J Offline
      J Offline
      Jonathan77
      wrote on last edited by Jonathan77
      #2

      Si vas a usar una GUI a la par que el puerto serie puedes tener problemas. El puerto serie te va a bloquear la interfaz de usuario mientras esté recibiendo o enviando datos.

      No es un problema si envías o recibes pocos datos o con grandes intervalos de tiempo. En ese caso puedes tenerlo todo junto.

      Si no quieres que te pase eso, la programación de la GUI y la del puerto la separas. Ejecuta el puerto serie en un hilo diferente y comunica ambos (GUI y puerto serie) mediante señales y slots.

      Es muy sencillo. Cuando pulses el botón haz que se lance una señal con la cadena que quieras enviar como argumento. Esa señal debe estar conectada al slot de la clase que maneja el puerto serie y que se ejecuta en un hilo diferente.

      El slot llama al método enviar datos por el puerto serie y le pasa la cadena. Esperas a recibir respuesta si quieres y cuando la recibas o se supere el tiempo de espera, lanzas otrá señal con los datos recibidos como respesta. Esta señal la conectas a un slot de la clase que maneja la GUI. Cuando se ejecute este ultimo slot, muestras en la interfaz gráfica la respuesta que has recibido por el puerto serie.

            |   ----> EnviaEsto("miCadena") ------->    |
      GUI   |                                           |  PUERTO_SERIE
            |  <----- HeRecibido("estaRespuesta") <---- |
      hilo principal                                      segundo hilo
      
         /* 
          * Para configurar el puerto serie. Tendrás que meterlo en la clase que crees para ejecutarlo en
          *  un hilo diferente al de la GUI
          */
          portSerial = new QSerialPort;
          portSerial->setPortName(comUART);
      
          if(!portSerial->open(QIODevice::ReadWrite))
          {
              qDebug() << " Error al abrir en modo lectura y escritura";
              return;
          }
      
          if(!portSerial->setBaudRate(baudrate))
          {
              qDebug() << " Error al establecer la velocidad de transmisión";
          }
      
          if(!portSerial->setDataBits(QSerialPort::Data8))
          {
              qDebug() << " Error al establecer el tamaño de los datos";
          }
      
          if(!portSerial->setStopBits(QSerialPort::OneStop))
          {
              qDebug() << " Error al establecer el bit/s de parada";
          }
      
          if(!portSerial->setParity(QSerialPort::EvenParity))
          {
              qDebug() << " Error al establecer la paridad";
          }
      
          if(!portSerial->setFlowControl(QSerialPort::NoFlowControl))
          {
              qDebug() << " Error al configurar el control de flujo";
          }
      
          // Código para enviar datos. Tan simple como esto:
      
         bytesWritten = portSerial->write("datos_a_enviar"); // Mira la documentación para ver el tipo de datos
      
         // Código para leer datos. Igual de simple:
        
         if (portSerial->waitForReadyRead(timeofwait))
         {
                buffer = portSerial->readAll();
         }
      
      

      El código que te acabo de poner tendrás que meterlo en los métodos correspondientes que crees. No hace falta configurar el puerto serie cada vez que quieras eviar algún dato... por ejemplo.

      Para más información de todas las opciones que tiene QSerialPort mira la documentación oficial.

      Espero que te ayude

      Alan_641A 1 Reply Last reply
      0
      • J Jonathan77

        Si vas a usar una GUI a la par que el puerto serie puedes tener problemas. El puerto serie te va a bloquear la interfaz de usuario mientras esté recibiendo o enviando datos.

        No es un problema si envías o recibes pocos datos o con grandes intervalos de tiempo. En ese caso puedes tenerlo todo junto.

        Si no quieres que te pase eso, la programación de la GUI y la del puerto la separas. Ejecuta el puerto serie en un hilo diferente y comunica ambos (GUI y puerto serie) mediante señales y slots.

        Es muy sencillo. Cuando pulses el botón haz que se lance una señal con la cadena que quieras enviar como argumento. Esa señal debe estar conectada al slot de la clase que maneja el puerto serie y que se ejecuta en un hilo diferente.

        El slot llama al método enviar datos por el puerto serie y le pasa la cadena. Esperas a recibir respuesta si quieres y cuando la recibas o se supere el tiempo de espera, lanzas otrá señal con los datos recibidos como respesta. Esta señal la conectas a un slot de la clase que maneja la GUI. Cuando se ejecute este ultimo slot, muestras en la interfaz gráfica la respuesta que has recibido por el puerto serie.

              |   ----> EnviaEsto("miCadena") ------->    |
        GUI   |                                           |  PUERTO_SERIE
              |  <----- HeRecibido("estaRespuesta") <---- |
        hilo principal                                      segundo hilo
        
           /* 
            * Para configurar el puerto serie. Tendrás que meterlo en la clase que crees para ejecutarlo en
            *  un hilo diferente al de la GUI
            */
            portSerial = new QSerialPort;
            portSerial->setPortName(comUART);
        
            if(!portSerial->open(QIODevice::ReadWrite))
            {
                qDebug() << " Error al abrir en modo lectura y escritura";
                return;
            }
        
            if(!portSerial->setBaudRate(baudrate))
            {
                qDebug() << " Error al establecer la velocidad de transmisión";
            }
        
            if(!portSerial->setDataBits(QSerialPort::Data8))
            {
                qDebug() << " Error al establecer el tamaño de los datos";
            }
        
            if(!portSerial->setStopBits(QSerialPort::OneStop))
            {
                qDebug() << " Error al establecer el bit/s de parada";
            }
        
            if(!portSerial->setParity(QSerialPort::EvenParity))
            {
                qDebug() << " Error al establecer la paridad";
            }
        
            if(!portSerial->setFlowControl(QSerialPort::NoFlowControl))
            {
                qDebug() << " Error al configurar el control de flujo";
            }
        
            // Código para enviar datos. Tan simple como esto:
        
           bytesWritten = portSerial->write("datos_a_enviar"); // Mira la documentación para ver el tipo de datos
        
           // Código para leer datos. Igual de simple:
          
           if (portSerial->waitForReadyRead(timeofwait))
           {
                  buffer = portSerial->readAll();
           }
        
        

        El código que te acabo de poner tendrás que meterlo en los métodos correspondientes que crees. No hace falta configurar el puerto serie cada vez que quieras eviar algún dato... por ejemplo.

        Para más información de todas las opciones que tiene QSerialPort mira la documentación oficial.

        Espero que te ayude

        Alan_641A Offline
        Alan_641A Offline
        Alan_641
        wrote on last edited by
        #3

        @Jonathan77 Hola, tengo otras pequeñas dudas con el programa,¿ donde debo configurar el puerto serial en el main.cpp o en el mainwindow.cpp? si lo configuro en el main.cpp como conecto los datos que mande con los botones que estan en el mainwindow.cpp con el puerto que esta en main.cpp.
        Es decir si en el mainwindow.cpp pongo;

        void MainWindow::boton_clicked()
        {
        serial->write ("hola");
        }
        

        lo mande al main.cpp que es donde esta configurado el serial

        #include "mainwindow.h"
        #include <QApplication>
        #include <QTextStream>
        #include <QCoreApplicatio>
        #include <QtCore>
        #include <QStringList>
        #include <QIODevice>
        #include <iostream>
        #include <QtSerialPort/QSerialPort>
        #include <QElapsedTimer>
        
        QT_USE_NAMESPACE
        
        int main(int argc, char *argv[])
        {
            QElapsedTimer timer;
        
            QApplication a(argc, argv);
        
            MainWindow w;
            
            QSerialPort serial;
        
            serial.setPortName ("COM3");
            serial.open (QIODevice::ReadWrite);
            serial.setBaudRate (QSerialPort::Baud9600);
            serial.setDataBits (QSerialPort::Data8);
            serial.setParity(QSerialPort::NoParity);
            serial.setStopBits (QSerialPort::OneStop);
            serial.setFlowControl (QSerialPort::NoFlowControl);
        
            QByteArray output;
        
        
        
            return a.exec();
        }
        
        

        ya intente configurar el puerto serial en el mainwindow.cpp pero no lo compila
        me podrias dar un ejemplo que haga esto por favor

        1 Reply Last reply
        0
        • J Offline
          J Offline
          Jonathan77
          wrote on last edited by
          #4

          Yo personalmente, cada cual lo puede hacer de forma diferente, lo que haría sería crearme una clase que contenga la configuración y los métodos del puerto serie.

          Se puede hacer en archivos diferentes si quieres. Así en el futuro podrás reutilizarlo.

          Por ejemplo:

          class mySerial:public QObject {
              Q_OBJECT
          
          public:
              mySerial();
              ~mySerial();
          public slots:
               void sendData(QString data);
          signals:
              void receibedData(QString data);
          private:
             // los métodos privados que quieras
          };
          

          En el mainwindow.cpp en el constructor o en alguna función que se vaya ejecutar antes de usar el puerto serie por primera vez (con ejecutarla una vez basta):

          QThread *miOtroHilo = new QThread;
          mySerial *serie = new mySerial;
          
          // Movemos el objeto 'serie' al "otro" hilo de ejecución
          mySerial->moveToThread(miOtroHilo);
          
          // Señales que conectan tu interfaz gráfica con el objeto "puerto serie"
          connect(this, SIGNAL(botonPulsado(QString), serie, SLOT(sendData(QString));
          connect(serie, SIGNAL(receibedData(QString), this, SLOT(receptorGUI(QString));
          
          // Las otras señales que necesites para manejar el otro hilo.
          
          miOtroHilo->start(); // inicio del hilo que ejecuta el puerto serie
          

          Más o menos es lo que necesitas hacer a groso modo.

          En la documentación oficial puedes encontrar toda la información sobre los hilos tal. Hay unos cuantos ejemplos. Lo que te puesto de ejemplo también se puede hacer de otras no te limites solo a este ejemplo.

          Lo complicado de la programación no es aprender un lenguaje o "framework" concreto sino el saber cómo hacer las cosas... yo sigo aprendiendo cada día.

          Suerte! y ya nos cuentas como te va.

          R 1 Reply Last reply
          0
          • J Jonathan77

            Yo personalmente, cada cual lo puede hacer de forma diferente, lo que haría sería crearme una clase que contenga la configuración y los métodos del puerto serie.

            Se puede hacer en archivos diferentes si quieres. Así en el futuro podrás reutilizarlo.

            Por ejemplo:

            class mySerial:public QObject {
                Q_OBJECT
            
            public:
                mySerial();
                ~mySerial();
            public slots:
                 void sendData(QString data);
            signals:
                void receibedData(QString data);
            private:
               // los métodos privados que quieras
            };
            

            En el mainwindow.cpp en el constructor o en alguna función que se vaya ejecutar antes de usar el puerto serie por primera vez (con ejecutarla una vez basta):

            QThread *miOtroHilo = new QThread;
            mySerial *serie = new mySerial;
            
            // Movemos el objeto 'serie' al "otro" hilo de ejecución
            mySerial->moveToThread(miOtroHilo);
            
            // Señales que conectan tu interfaz gráfica con el objeto "puerto serie"
            connect(this, SIGNAL(botonPulsado(QString), serie, SLOT(sendData(QString));
            connect(serie, SIGNAL(receibedData(QString), this, SLOT(receptorGUI(QString));
            
            // Las otras señales que necesites para manejar el otro hilo.
            
            miOtroHilo->start(); // inicio del hilo que ejecuta el puerto serie
            

            Más o menos es lo que necesitas hacer a groso modo.

            En la documentación oficial puedes encontrar toda la información sobre los hilos tal. Hay unos cuantos ejemplos. Lo que te puesto de ejemplo también se puede hacer de otras no te limites solo a este ejemplo.

            Lo complicado de la programación no es aprender un lenguaje o "framework" concreto sino el saber cómo hacer las cosas... yo sigo aprendiendo cada día.

            Suerte! y ya nos cuentas como te va.

            R Offline
            R Offline
            riken7
            wrote on last edited by
            #5

            @Jonathan77 Buenas la verdad que estoy muy interesado en lo que has puesto, pero no entiendo muy bien el significado, no se si el hilo secundario se actualiza cíclicamente o por el contrario solo cuando enviamos o recibimos datos. Esto es lo que mas me interesa pues estoy desarrollando una interfaz gráfica para un programa de control.
            Lo que querría es que leyera continuamente los puertos para actualizar la información de los sensores y del control en la GUI. Y solo envíar datos al micro cada vez que pulsaramos la interfaz.

            Para ello había pensado tener unos timer que fueran leyendo el puerto en el hilo secundario(para así poder monitorizar la interfaz en el primario) y poder refrescar la comunicación continuamente. Pero nose si el hilo secundario es cíclico o tengo que hacerlo yo ciclico con los timer.
            El bucle de control se realizará en un PLC de arduino. También habia pensado en comunicar un inversor con el Qt mediante Modbus TCP, pero creo que no hay librerias en Qt que lo permitan.

            Nose si me he explicado bien.

            Muchas gracias

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved