Search code examples
c++qtcan-bus

How to parse CAN Frames from a DBC using QT and C++?


so I have this code here :

#include "qcanbusframe.h"
#include <QCoreApplication>
#include <QCanDbcFileParser>
#include <QCanFrameProcessor>
#include <QCanUniqueIdDescription>
#include <QCanMessageDescription>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QCanDbcFileParser dbcParser;

    // Step 2: Load DBC file
    QString dbcFilePath = "C:\\Users\\HP\\Documents\\TAMEPOWER_HMI\\TestDBCParser\\dob.dbc";
    if (dbcParser.parse(dbcFilePath)) {
        qDebug() << "DBC file parsed successfully.";
    } else {
        qDebug() << "Failed to parse DBC file.";
        return 1;
    }

    QCanDbcFileParser::MessageValueDescriptions msgDesc = dbcParser.messageValueDescriptions();

    QCanFrameProcessor frameProcessor;
    frameProcessor.setUniqueIdDescription(dbcParser.uniqueIdDescription());
    frameProcessor.setMessageDescriptions(dbcParser.messageDescriptions());

    QCanBusFrame frameEncoded;

    frameEncoded.setExtendedFrameFormat(true);
    frameEncoded.setFrameId(0x10000000);

    char data[7] = {1,0,0,0,1,0,1};
    frameEncoded.setPayload(QByteArray::fromRawData(data, 7));
    qDebug()<< frameEncoded.isValid();
    qDebug() << frameEncoded.toString();

    QCanFrameProcessor::ParseResult result = frameProcessor.parseFrame(frameEncoded);

    qDebug()<<result.uniqueId;
    qDebug()<<result.signalValues.keys();
    return a.exec();
}

and this is my DBC :

BO_ 2148532224 DCDC_Control: 7 PC
 SG_ currentLimitReq : 40|16@1+ (0.1,0) [0|6553.5] "A"  DCDC
 SG_ setpointReq : 8|32@1+ (1,0) [0|4294967295] ""  DCDC
 SG_ startCommand : 0|8@1+ (1,0) [0|1] ""  DCDC

all I'm trying to do is to parse the file and using the FrameProcessor to parse a Frame I want.

here is the output i get :

DBC file parsed successfully.
true
"10000000   [7]  01 00 00 00 01 00 01"
0
QList()

What I'm expecting to get is :

DBC file parsed successfully.
true
"10000000   [7]  01 00 00 00 01 00 01"
10000000
QList(currentLimitReq, setpointReq, startCommand)

But the problem is IDK why it's not working ?

I thought the problem is the frame ID so i tried the littel endian and i used 0x00000010 but still not working, I still believe that the frame ID is the what causing this, so how can I make this code work and how to parse a CAN frame using QT and C++?


Solution

  • I had to go through each Message Description and get the Unique ID of it and apply a mask for it and set the masked ID to the Message Description.

    '''

        QCanDbcFileParser dbcParser;
    
        QString dbcFilePath = "C:\\Users\\HP\\Documents\\TAMEPOWER_HMI\\TestDBCParser\\dob.dbc";
        if (dbcParser.parse(dbcFilePath)) {
            qDebug() << "DBC file parsed successfully.";
        } else {
            qDebug() << "Failed to parse DBC file.";
            return 1;
        }
    
        QCanFrameProcessor frameProcessor;
        QCanUniqueIdDescription idDes;
        idDes.setEndian(QSysInfo::LittleEndian);
        idDes.setSource(QtCanBus::DataSource::FrameId);
        idDes.setBitLength(29);
        idDes.setStartBit(0);
    
        QList<QCanMessageDescription> desscs;
        QtCanBus::UniqueId uId;
        quint32 iId;
        foreach (auto md, dbcParser.messageDescriptions()) {
            iId = static_cast<quint32>(md.uniqueId());
            uId = static_cast<QtCanBus::UniqueId>(0x1FFFFFFF & iId);
            md.setUniqueId(uId);
            desscs.append(md);
        }
    
        frameProcessor.setUniqueIdDescription(idDes);
        frameProcessor.setMessageDescriptions(desscs);
    
        qDebug() << "id des validity : " << frameProcessor.uniqueIdDescription().isValid();
        qDebug() << "id des endianness : " << frameProcessor.uniqueIdDescription().endian();
        qDebug() << "id des source : " << frameProcessor.uniqueIdDescription().source();
        qDebug() << "id des bit lenght : " << frameProcessor.uniqueIdDescription().bitLength();
        qDebug() << "id des bit start : " << frameProcessor.uniqueIdDescription().startBit();
    
        QCanBusFrame frameEncoded,framePrepared;
    
        frameEncoded.setExtendedFrameFormat(true);
        quint32 idEncoded = 0x06F00000;
        frameEncoded.setFrameId(idEncoded);
    
        qDebug() << "id Frame : " << frameEncoded.frameId();
        char data[7] = {1,1,0,0,0,1,1};
        frameEncoded.setPayload(QByteArray::fromRawData(data, 7));
    
        qDebug()<< "is frame valid : " << frameEncoded.isValid();
        qDebug() << frameEncoded.toString();
    
        QCanFrameProcessor::ParseResult result = frameProcessor.parseFrame(frameEncoded);
        qDebug()<<result.uniqueId;
        qDebug()<<result.signalValues;
    
        QVariantMap signalValue;
    
        signalValue["clampStatus"]= 1;
        signalValue["softwareMode"]= 2;
        signalValue["limitationType"]= 3;
        signalValue["setpoint"]= 4;
    
        QtCanBus::UniqueId id = static_cast<QtCanBus::UniqueId>(116391936);
        framePrepared = frameProcessor.prepareFrame(id,signalValue);
        qDebug()<<framePrepared.toString();
    

    '''