QSerialPort to USB CDC PIC



  • I'm trying something simple, to send and recieve data to an arduino like board (the "Pinguino" generic one using a microchip 18f2550 PIC) over USB CDC transfer mode. So i can open the serial port monitor from the arduino IDE, send data and turn a led ON and OFF, get some strings from the board and so on, but i can't get the same thing done on this board using a simple Qt app and some push buttons, in my arduino UNO the Qt app works just fine using the serial class.... plus, can someone explain me why using GUI's and the serial class from python and processing on this board works like a charm?

    from the board side

    char data;  
    char receivedbyte;  
    char buff[64];  
    
    #define led 7 
    
    void setup(){   
        pinMode(led, OUTPUT);
        digitalWrite(led,LOW);  
    }  
    
    void loop() {        
        while((receivedbyte = CDC.read(buff)) == 0);  
    
        CDC.printf("Check! \r\n");   
    
        if(receivedbyte > 0){          
            data = buff[0];                         
            if(data == '1'){  
                digitalWrite(led,HIGH);  
                CDC.printf("Led ON \r\n");  
    
            } else if (data == '2'){  
                digitalWrite(led,LOW);  
                CDC.printf("Led OFF \r\n");  
            }         
        }  
    } 
    

    Qt side - .pro:

    QT       += core gui\
                serialport
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = pinguino_CDC
    TEMPLATE = app
    
    
    SOURCES += main.cpp\
            mainwindow.cpp
    
    HEADERS  += mainwindow.h
    
    FORMS    += mainwindow.u
    

    Qt side - mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow {
        Q_OBJECT
    
        public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    public slots :
        void turnOn();
        void turnOff();
    private slots:
        void on_on_clicked();
    
        void on_off_clicked();
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    

    Qt side - main.cpp

    #include "mainwindow.h"
    #include <QApplication>
    
    int main(int argc, char *argv[]){
        QApplication a(argc, argv);
        a.setStyle("fusion");
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    

    Qt side - mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QMessageBox>
    #include <QtSerialPort/QSerialPort>
    
    QSerialPort *pinguino;
    QString nameport = "/COM4";
    MainWindow::MainWindow(QWidget *parent) :  QMainWindow(parent),
        ui(new Ui::MainWindow){
        ui->setupUi(this);
    
        pinguino = new QSerialPort(this);
    
        pinguino->setPortName(nameport);
        pinguino->open(QIODevice::ReadWrite);
        pinguino->setBaudRate(QSerialPort::Baud9600);
        pinguino->setStopBits(QSerialPort::OneStop);
        pinguino->setParity(QSerialPort::NoParity);
        pinguino->setDataBits(QSerialPort::Data8);
        pinguino->setFlowControl(QSerialPort::NoFlowControl);
    
        if(pinguino->isOpen() == true){
            QMessageBox::information(this, "Info", "Port Open: " + nameport);
        } else {
            QMessageBox::information(this, "Info", "Error on Port: " + nameport);       
        }
    
        connect(ui->on, SIGNAL(clicked()), this, SLOT(turnOn()));
        connect(ui->off, SIGNAL(clicked()), this, SLOT(turnOff()));
    }
    
    void MainWindow::turnOn(){
        QByteArray outbyte;
        char x = '1';
        outbyte.append(x);
        pinguino->write(outbyte);
    }
    
    void MainWindow::turnOff(){
        QByteArray outbyte;
        char x = '2';
        outbyte.append(x);
        pinguino->write(outbyte);
    }
    
    MainWindow::~MainWindow(){
        delete ui;
    }
    
    void MainWindow::on_on_clicked(){
        turnOn();
    }
    
    void MainWindow::on_off_clicked(){
        turnOff();
    }
    

  • Lifetime Qt Champion

    Hi,

    I'd rather to the setup like proposed in the Terminal Example:

    pinguino->setPortName(nameport);
    pinguino->setBaudRate(QSerialPort::Baud9600);
    pinguino->setStopBits(QSerialPort::OneStop);
    pinguino->setParity(QSerialPort::NoParity);
    pinguino->setDataBits(QSerialPort::Data8);
    pinguino->setFlowControl(QSerialPort::NoFlowControl);
    if (pinguino->open(QIODevice::ReadWrite)) {
        QMessageBox::information(this, "Info", "Port Open: " + nameport);
    } else {
        QMessageBox::information(this, "Info", "Error on Port: " + nameport);
    }
    

    Next "/COM4" looks like a strange name, are you working on Windows ?



  • Hello SGaist, I am. Win7 32 bit


  • Lifetime Qt Champion

    Then the name should rather be COM4.

    You can check that by printing all the available ports with QSerialPortInfo::availableSerialPorts



  • ok by removing the slash on the name of the port the app still works on arduino, but nothing on the other board. I just have a question, what is QSerialPort doing different from the serial class of processing and python?


  • Lifetime Qt Champion

    I don't know the internals of python serial port module so I can't comment on that.

    Did you check that you are using the correct parameters for the communication ? Are you using the same serial port to communicate with both ?



  • im just using COM3 / COM 4, i have both boards connected, whenever i want to use one i just set the COM i want, same thing for the serial port monitor from arduino IDE, i just choose the COM port. My trouble here is, why such a powerful tool like Qt don't specify something for CDC devices?. To start, it is a fact that QSerialPort can handle USB HID/CDC devices? and if it does how can i do that? i've been searching for months, and trust me i dont want to use python or processing.


  • Lifetime Qt Champion

    QSerialPort communicates with serial ports which might be USB-RS232 converters which is generally a specialized CDC device.



  • @SGaist so, there is no CDC communication from QSerialPort "per se" i must understand? like a 18f2550 / 4550 in CDC mode, i do know that Arduino uses a FTDI chip, wich is a specialized CDC device.


  • Lifetime Qt Champion

    Exact, QSerialPort doesn't call the USB stack directly. Typically for FTDI devices, you would install the FTDI Virtual Com Port driver and then you have a "classic" com port. AFAIK the ARDUINO uses RS232 so it should act also like a serial device.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.