QCanBusDevice and CanOpen device



  • Hello. I'm looking for a way to get the name and identification number of CanOpen device connected to my PC via a systeccan plugin. The QCanBusDevice class is only available for systec,tinycan,socketCan...
    Anyone got an idea ?


  • Qt Champions 2018

    Hi @Babs,

    can you elaborate more about your device? how is it connected to your PC? Which vendor is it? Any links to product information?

    Regards



  • @aha_1980 Hello. I use a Systeccan USBCan Module 1 described in that link:https://www.systec-electronic.com/en/products-technologies/interfaces-gateways/sysworxx-usb-canmodul1/

    I already made a qt application that implements CanOpen protocol. I connect several CanOpen devices throught this systeccan. Each devices represents a node of my Can network. And for each device i have to load the EDS file that describes object dictionary entries.
    Th0_1554275081246_can.PNG e following describes my network:![0_1554275027868_imageCan.jpg](Uploading 100%)



  • @aha_1980 I want to be able to scan my devices and get their name or vendor ID in order to load corresponding EDS file.


  • Qt Champions 2018

    Hi @Babs,

    Ok, thanks for the picture, that makes things more clear.

    Well, in Qt we currently don't have support for higher-level CAN protocols. A QCanBusDevice is the interface between the PC and the CAN bus. Your "devices" are CAN nodes, so there is no builtin support to get any information out of them yet.

    You will need to use CAN commands to query the needed information and process in your program.

    Regards



  • @aha_1980 Thanks for your response. I will try alternative solutions. May be you know open source projects similar to mine? My final goal is to command motors with that protocol


  • Qt Champions 2018

    @Babs Unfortunately, no. You will need to read the CANopen standard to get more information.

    As every CANopen device get's an unique vendor ID assigned, I'm pretty sure what you want to do is possible. I just cannot tell you how... :)



  • @aha_1980 Thanks you . I will try to get more information from CANOpen standard documentations.



  • @aha_1980 I'm encountering an error related to QCanBusDevice. May be you can help. As you know i work with systec plugin.
    I send my Object Dictionary subEntry values to the systec device. The problem is i get the following configuration error:"Cannot configure TxEcho for open device"

    Here is the function i use to write to Can Device:

    void CanOpenDevice::dataToCan(QCanBusDevice *device,QString entry)
    {
        QStringList subEntries=getSubEntries(entry);
    
        foreach(const QString &subEntry,subEntries){
            ObjDicIndex index=subEntry.left(4).toUShort(nullptr,16);
            ObjDicSubIndex sub=static_cast<quint8>(subEntry.right(1).toUShort(nullptr,16));
            QByteArray payload=m_obd->getEntry(index)->getSubEntry(sub)->readToQtByteArray();
    //        QByteArray payload=QByteArray::number(var);
            QCanBusFrame frame(quint32(index),payload);
            qDebug()<<frame.payload();
            qDebug()<<device->writeFrame(frame);
    
    
        }
        qDebug()<<device->state();
        qDebug()<<device->errorString();
    
    }
    

  • Qt Champions 2018

    @Babs said in QCanBusDevice and CanOpen device:

    The problem is i get the following configuration error:"Cannot configure TxEcho for open device"

    But I don't see how you can get that warning from the code you posted here.

    You may get it when calling setConfigurationParameter() after opening your Systec device (most likely QCanBusDevice::LoopbackKey or QCanBusDevice::ReceiveOwnKey). If you want to configure that, do so before opening.



  • @aha_1980 i call setConfiguration parameter in my class constructor.
    Here is my class header

    #ifndef CANOPENDEVICE_H
    #define CANOPENDEVICE_H
    #include <QObject>
    #include <QSettings>
    #include <QQmlEngine>
    
    #include "protocolmanager.h"
    #include "ByteArrayQmlWrapper.h"
    #include "objectdictionary.h"
    #include "TypesQmlWrapper.h"
    #include "QQmlVarPropertyHelpers.h"
    #include "QQmlConstRefPropertyHelpers.h"
    #include "QQmlPtrPropertyHelpers.h"
    #include "edsreader.h"
    
    #include "QQmlEnumClassHelper.h"
    #include "QQmlObjectListModel.h"
    #include "QQmlListPropertyHelper.h"
    
    
    
    QML_ENUM_CLASS (CanOpenNmtCmd,
                    StartNode = 0x01,
                    StopNode  = 0x02,
                    SetPreOp  = 0x80,
                    ResetNode = 0x81,
                    ResetComm = 0x82,
                    NB_CMDS)
    
    QML_ENUM_CLASS (CanOpenLssCommands,
                    SwitchState   = 0x04,
                    ChangeNodeId  = 0x11,
                    ChangeBitrate = 0x13,
                    StoreConfig   = 0x17,
                    NB_CMDS)
    
    
    
    class CanOpenDevice: public QObject
    {
        Q_OBJECT
        QML_WRITABLE_VAR_PROPERTY(CanOpenNodeId,nodeId)
        QML_WRITABLE_VAR_PROPERTY (bool, isMaster)
        QML_WRITABLE_PTR_PROPERTY (QCanBusDevice, device)
        QML_WRITABLE_PTR_PROPERTY(ProtocolManager,protocolManager)
        QML_WRITABLE_VAR_PROPERTY (QString, edsFileName)
        QML_WRITABLE_VAR_PROPERTY(QString,deviceName)
        QML_WRITABLE_VAR_PROPERTY(QStringList,deviceInfo)
        QML_WRITABLE_VAR_PROPERTY(QStringList,subEntriesList)
        QML_WRITABLE_VAR_PROPERTY(QStringList,entries)
        QML_WRITABLE_VAR_PROPERTY(QString, deviceProfile)
    
    
    
    public:
        explicit CanOpenDevice(QObject *parent=Q_NULLPTR);
        CanOpenDevice(const CanOpenNodeId &nodeId,const QString &identNumber,QObject *parent=nullptr);
        void init(void);
        void start();
        void stop(void);
        void reset(void);
        void createDevice(QString plugin,QString interface);
        void setConfiguration(int key);
        ProtocolManager * getProtocolManger();
        ObjectDictionary * getObjectDictionary();
    
    
        Q_INVOKABLE ByteArrayWrapper * createBufferFromInt8   (const QmlBiggestInt value);
        Q_INVOKABLE ByteArrayWrapper * createBufferFromInt16  (const QmlBiggestInt value);
        Q_INVOKABLE ByteArrayWrapper * createBufferFromInt32  (const QmlBiggestInt value);
        Q_INVOKABLE ByteArrayWrapper * createBufferFromUInt8  (const QmlBiggestInt value);
        Q_INVOKABLE ByteArrayWrapper * createBufferFromUInt16 (const QmlBiggestInt value);
        Q_INVOKABLE ByteArrayWrapper * createBufferFromUInt32 (const QmlBiggestInt value);
        Q_INVOKABLE ByteArrayWrapper * createBufferFromHex    (const QString & hex);
        Q_INVOKABLE ByteArrayWrapper * createBufferFromString (const QString & str);
    
        Q_INVOKABLE ByteArrayWrapper * readValue (const int index, const int subIndex);
    
        Q_INVOKABLE void changeValue (const int index, const int subIndex, ByteArrayWrapper * buffer);
    
        Q_INVOKABLE void sendNmtChangeRequest (const int nodeId, const CanOpenNmtCmd::Type state);
    
        Q_INVOKABLE void sendLssActionRequest (const CanOpenLssCommands::Type cmd, const int argument = 0);
    
        Q_INVOKABLE void sendSdoReadRequest  (const int nodeId, const int index, const int subIndex, const bool blockMode = false);
        Q_INVOKABLE void sendSdoWriteRequest (const int nodeId, const int index, const int subIndex, ByteArrayWrapper * buffer);
        Q_INVOKABLE void writeValuetoSubEntry(ObjDicIndex index,ObjDicSubIndex subIndex,QString value);
        Q_INVOKABLE QString getParameterNameforSubEntry(QString subEntry);
        void getWritableEntries();
        Q_INVOKABLE QString entryParamName(QString idxStr);
        Q_INVOKABLE QString getDefaultValue(QString subIdx);
        Q_INVOKABLE void modifyValue(QString val,QString subEntry);
        Q_INVOKABLE QStringList getSubEntries(QString entry);
        Q_INVOKABLE void dataToCan(QString entry);
    public slots:
        Q_INVOKABLE void loadObjectDictionary(QString edsFilePath);
        //Q_INVOKABLE bool writeValueToEntry();
    
    
    protected slots:
        //void onCanOpenParamChanged(void);
    
    
    signals:
        void initialized(quint32 bitRateKey,QString plugin="systeccan",QString interface = "can");
        void started(void);
        void stopped(void);
        void reseting(void);
        void EntryWritten();
        void loaded(QString edsFilePath);
    
    private:
        bool m_ready;
        bool m_running;
        QString m_interface;
        QString m_plugin;
        EdsReader *m_edsReader;
        QSettings *m_setting;
        ObjectDictionary *m_obd;
    };
    
    
    
    #endif // CANOPENDEVICE_H