Search code examples
c++qtqmlcan-bus

Invalid value while PeakCAN canbus frame printing QT C++


I'm trying to read and print the frame from canbus using the peakcan plugin with QT, but I think I'm making a mistake somewhere.

This is my code :

          qDebug() << "connectCanDevice";
           if (QCanBus::instance()->plugins().contains(QStringLiteral("peakcan"))) {
               // plugin available
               QString errorString;
               QCanBusDevice *device = QCanBus::instance()->createDevice(
                   QStringLiteral("peakcan"), QStringLiteral("usb0"), &errorString);
               if (!device) {
                   // Error handling goes here
                   qDebug() << "Device cannot be created";
               } else {
                   qDebug() << "Bit Rate Configration";
                   device->setConfigurationParameter(QCanBusDevice::BitRateKey, 250000);
                   device->setConfigurationParameter(QCanBusDevice::DataBitRateKey, 100000);
                   device->errorOccurred(QCanBusDevice::ReadError);
                   if(device->connectDevice()) {
                       qDebug() << SIGNAL (framesReceived());
                        qDebug() << device->framesAvailable();

                       while(device->framesAvailable()) {
                         QCanBusFrame frame = device->readFrame();
                           QString test = frame.toString();
                           std::string text = test.toUtf8().constData();
                           qDebug()<<test;
                           std::cout<<text<<std::endl;

                       }
                   }
               }
           }

Here is the output :

connectCanDevice qt.canbus.plugins.peakcan: Using PCAN-API version: 4.6.1.728 Bit Rate Configration qt.canbus.plugins.peakcan: Unsupported data bitrate value: 100000 2framesReceived() 0

As a beginner, I couldn't understand much from the qt documents. I can see the frame with Pcanview. There is no problem with canbus.


Solution

  • OK, I see you're missing some points here, this is an simple code example that do the work:

    if (QCanBus::instance()->plugins().contains(QStringLiteral("socketcan")))
    {
        QString errorString;
        QCanBusDevice *device = QCanBus::instance()->createDevice(
                    QStringLiteral("socketcan"), QStringLiteral("can0"), &errorString);
        if (!device)
        {
            qDebug() << errorString;
        }
        else
        {
            bool retval = device->connectDevice();
            if(retval == false)
            {
                qDebug() << "cannot open CAN interface";
            }
            else
            {
                QObject::connect(device, &QCanBusDevice::framesReceived, [=] () {
                    while(device->framesAvailable() > 0)
                    {
                        auto frame = device->readFrame();
                        
                        QString d = QString("%1 # ").arg(frame.frameId(), 3, 16, QChar('0'));
    
                        for(int i = 0;i < frame.payload().length();i ++)
                        {
                            d += QString("%1 ").arg(static_cast<uint8_t>(frame.payload().at(i)), 2, 16, QChar('0'));
                        }
    
                        qInfo() << d;
                    }
                });
            }
        }
    }
    

    I've used a lambda function here to be short, but you can use other options as you want. I also tested it with socketcan since pcan driver is used by that. Short explanation: I connect QCanBusDevice::framesReceived signal to my function that will be called when a frame(s) has received. then I read all available frames and print it out.
    You can read more about Qt signal/slot mechanism here