How can i let a loop for reading data from embedded device usually actif
-
@dziko147 in your other topic, that you now apparently deleted, I suggested to go away from an invite loop to a QTimer.
I think you misunderstood me if you explicitly changed to a while loop
I had something like this in mind:
class MyCanBusClass : public QObject { Q_OBJECT public: MyCanBusClass(QObject *parent = nullptr) : QObject(parent), m_fetchFrameTimer(this){ connect(&m_fetchFrameTimer, & QTimer::timeout, this, &MyCanBusClass::fetchNextDataFrame); m_fetchFrameTimer.setSingleShot(true); m_canDevice = QCanBus::instance()->createDevice(QStringLiteral("socketcan"), QStringLiteral("can0")); connect(m_canDevice, &QCanBusDevice::framesReceived, this, &MyCanBusClass::onFramesReceived); connect(m_canDevice, &QCanBusDevice::framesWritten, this, &MyCanBusClass::onFramesWritten); } signals: void signalForUiUpdate(QStringList Outputs); private slots: void onFramesReceived(){ QStringList list; // .... // .... emit signalForUiUpdate(list); } void onFramesWritten(){ m_fetchFrameTimer.start(10000); // 10000 ms } private: void fetchNextDataFrame(){ QCanBusFrame firstframetosend; } private: QCanBusDevice *m_canDevice; QTimer m_fetchFrameTimer; };
signalForUiUpdate
than connected to a slot in your UI class, to update the Ui -
@J-Hilk said in How can i let a loop for reading data from embedded device usually actif:
private slots:
void onFramesReceived(){
QStringList list;
// ....
// ....
emit signalForUiUpdate(list);
}@J-Hilk Hello :)
here what should I do ?
Just I call my variable like this .list << variable1 << variable2 ........ ;
Or I must set putt here the function which fill the data . ?
I mean this code :
for(size_t i=0;i<Inputs.size();i++){ //Envoie de la commande upload qDebug() << "Input type" << Inputs[i]; if(Inputs[i]=="double") { frameupload.setFrameId(frameId); frameupload.setPayload(payloadupload8byte); qDebug() << "type is double : upload commande is" << payloadupload8byte; device->writeFrame(frameupload); } else{ frameupload.setFrameId(frameId); frameupload.setPayload(payloadupload); qDebug() << "type is not double : upload commande is" << payloadupload; device->writeFrame(frameupload); } // fin de la commande upload device->waitForFramesReceived(3000); QCanBusFrame framereceived = device->readFrame(); // Reception 1ére données QByteArray data = QByteArray::fromHex(framereceived.payload()); qDebug() << QByteArray::fromHex(framereceived.payload()) << " Data Data&size" << QByteArray::fromHex(framereceived.payload()).size(); // QByteArray data = QByteArray::fromHex("FF42480000"); QDataStream stream(data); qDebug() << data.size() << " Data Data&size" ; if (data.size()== 5){ stream.setFloatingPointPrecision(QDataStream::SinglePrecision); }else { stream.setFloatingPointPrecision(QDataStream::DoublePrecision); } quint8 byte; stream >> byte; // skip first byte stream >> myData; // read data qDebug() << "this is data"<< myData ; QString DatatoString =QString::number(myData); Outputs[i]=DatatoString; qDebug() << "In outputs data" << Outputs[i]; //fin récuperation } m_Valuespeed=Outputs[0].toDouble(); m_ValueId=Outputs[1].toFloat(); m_ValueIQ=Outputs[2].toFloat(); m_ValueIdRef=Outputs[3].toFloat(); m_ValueIQRef=Outputs[4].toFloat(); m_ValueVD=Outputs[5].toFloat(); m_ValueVQ=Outputs[6].toFloat(); m_ValueVDRef=Outputs[7].toFloat(); m_ValueVQRef=Outputs[8].toFloat(); m_valueDCvolt=Outputs[9].toFloat(); m_ValueCPU1=Outputs[10].toFloat(); m_ValueCPU2=Outputs[11].toFloat(); m_ValueCPU3=Outputs[12].toFloat(); m_ValueCPU4=Outputs[13].toFloat(); m_ValueCPU5=Outputs[14].toFloat(); m_ValueCPU6=Outputs[15].toFloat(); m_ValueCPU7=Outputs[16].toFloat(); m_ValueCPU8=Outputs[17].toFloat(); m_ValueTorque=Outputs[18].toFloat(); m_ValueTorqueMax=Outputs[19].toFloat(); m_directiontext=Outputs[20]; m_motiontext=Outputs[21]; m_nbrevoltext=Outputs[22]; m_degradedtext=Outputs[23]; m_dischtext=Outputs[24]; }
thank you
-
well,
QStringList list
is a, substitution for yourOutputs
variablethe slot that receives the signal would than update the ui
void updateUiWithFrameData(QStringList Outputs)
{
m_Valuespeed=Outputs[0].toDouble();
m_ValueId=Outputs[1].toFloat();
m_ValueIQ=Outputs[2].toFloat();
m_ValueIdRef=Outputs[3].toFloat();
m_ValueIQRef=Outputs[4].toFloat();
m_ValueVD=Outputs[5].toFloat();
m_ValueVQ=Outputs[6].toFloat();
m_ValueVDRef=Outputs[7].toFloat();
m_ValueVQRef=Outputs[8].toFloat();
m_valueDCvolt=Outputs[9].toFloat();
m_ValueCPU1=Outputs[10].toFloat();
m_ValueCPU2=Outputs[11].toFloat();
m_ValueCPU3=Outputs[12].toFloat();
m_ValueCPU4=Outputs[13].toFloat();
m_ValueCPU5=Outputs[14].toFloat();
m_ValueCPU6=Outputs[15].toFloat();
m_ValueCPU7=Outputs[16].toFloat();
m_ValueCPU8=Outputs[17].toFloat();
m_ValueTorque=Outputs[18].toFloat();
m_ValueTorqueMax=Outputs[19].toFloat();
m_directiontext=Outputs[20];
m_motiontext=Outputs[21];
m_nbrevoltext=Outputs[22];
m_degradedtext=Outputs[23];
m_dischtext=Outputs[24];}
-
@J-Hilk So if understand .
I don't need to change my function which fill data :void Backend::statuspican() { float myDatafloat; double myDatadouble; bool ok; std::array<QString,25> Inputs{"real","double","double","double","double","double","double","double","double","double" ,"real","real","real","real","real","real","real","real","double","double","boolean","double" ,"uint32","boolean","boolean"}; QByteArray payloadupload= QByteArray::fromHex("F504"); QByteArray payloadupload8byte= QByteArray::fromHex("F508"); QByteArray Testsend= QByteArray::fromHex("FF"); // réponse static QByteArray payloadrpm= QByteArray::fromHex("F600000000180010"); // Rpm @ QString ID = "101"; const uint frameId = ID.toUInt(nullptr, 16); QCanBusFrame firstframetosend; QCanBusFrame frameupload; QCanBusDevice *device = QCanBus::instance()->createDevice( QStringLiteral("socketcan"), QStringLiteral("can0")); if(device->connectDevice()){ //changer avant la validation //Récuperation de Rpm //Envoie de l'@ Rpm firstframetosend.setFrameId(frameId); firstframetosend.setPayload(payloadrpm); device->writeFrame(firstframetosend); // fin @Rpm device->waitForFramesReceived(3000); QCanBusFrame rpmreponse= device->readFrame(); QByteArray Testreponse = rpmreponse.payload(); if(Testreponse==Testsend){ //test de la reponse for(size_t i=0;i<Inputs.size();i++){ //Envoie de la commande upload qDebug() << "Input type" << Inputs[i]; if(Inputs[i]=="double") { frameupload.setFrameId(frameId); frameupload.setPayload(payloadupload8byte); qDebug() << "type is double : upload commande is" << payloadupload8byte; device->writeFrame(frameupload); } else{ frameupload.setFrameId(frameId); frameupload.setPayload(payloadupload); qDebug() << "type is not double : upload commande is" << payloadupload; device->writeFrame(frameupload); } // fin de la commande upload device->waitForFramesReceived(3000); QCanBusFrame framereceived = device->readFrame(); // Reception 1ére données QByteArray data = framereceived.payload(); qDebug() << data<< " this is frame data" ; qDebug() << data.size() << " Data Data&size" ; if (data.size()==5){ data.remove(0,1); QByteArray byte1 =data.left(1); QByteArray byte2nonpret =data.left(2); QByteArray byte2 =byte2nonpret.right(1); QByteArray byte3nonpret =data.left(3); QByteArray byte3 =byte3nonpret.right(1); QByteArray byte4 =data.right(1); QByteArray Datareversed = byte4+byte3+byte2+byte1; QDataStream stream(Datareversed); // quint8 byte; // stream >> byte; // skip first byte stream.setFloatingPointPrecision(QDataStream::SinglePrecision); stream >> myDatafloat; // read data QString DatatoString =QString::number(myDatafloat); Outputs[i]=DatatoString; } if(data.size()==8){ data.remove(0,1); qDebug() << data << " data remove FF" ; QByteArray byte1 =data.left(1); QByteArray byte2nonpret =data.left(2); QByteArray byte2 =byte2nonpret.right(1); QByteArray byte3nonpret =data.left(3); QByteArray byte3 =byte3nonpret.right(1); QByteArray byte4nonpret =data.left(4); QByteArray byte4 =byte4nonpret.right(1); QByteArray byte0 =QByteArray::fromHex("00000000"); QByteArray Datareversed2 = byte4+byte3+byte2+byte1+byte0; qDebug() << Datareversed2<< "data 8Byte reversed" ; QDataStream stream2(Datareversed2); stream2.setFloatingPointPrecision(QDataStream::DoublePrecision); stream2 >> myDatadouble; // read data QString DatatoString =QString::number(myDatadouble); Outputs[i]=DatatoString; } /* quint8 byte; stream >> byte; // skip first byte stream >> myData; // read data qDebug() << "this is data"<< myData ; QString DatatoString =QString::number(myData); Outputs[i]=DatatoString; qDebug() << "In outputs data" << Outputs[i];*/ //fin récuperation } m_Valuespeed=Outputs[0].toFloat(&ok); m_ValueId=Outputs[1].toDouble(&ok); m_ValueIQ=Outputs[2].toDouble(&ok); m_ValueIdRef=Outputs[3].toDouble(&ok); m_ValueIQRef=Outputs[4].toDouble(&ok); m_ValueVD=Outputs[5].toDouble(&ok); m_ValueVQ=Outputs[6].toDouble(&ok); m_ValueVDRef=Outputs[7].toDouble(&ok); m_ValueVQRef=Outputs[8].toDouble(&ok); m_valueDCvolt=Outputs[9].toDouble(&ok); m_ValueCPU1=Outputs[10].toFloat(&ok); m_ValueCPU2=Outputs[11].toFloat(&ok); m_ValueCPU3=Outputs[12].toFloat(&ok); m_ValueCPU4=Outputs[13].toFloat(&ok); m_ValueCPU5=Outputs[14].toFloat(&ok); m_ValueCPU6=Outputs[15].toFloat(&ok); m_ValueCPU7=Outputs[16].toFloat(&ok); m_ValueCPU8=Outputs[17].toFloat(&ok); m_ValueTorque=Outputs[18].toDouble(&ok); m_ValueTorqueMax=Outputs[19].toDouble(&ok); m_directiontext=Outputs[20]; m_motiontext=Outputs[21]; m_nbrevoltext=Outputs[22]; m_degradedtext=Outputs[23]; m_dischtext=Outputs[24]; for (size_t k=0;k<Outputs.size() ; k++) { qDebug() << "Data after convert " << Outputs[k]; } } } }
Just I need to redefine my constructor :
Backend::Backend(QObject *parent ) :QObject(parent), m_fetchFrameTimer(this) { std::array<QString,25> Outputs; m_directiontext="null"; m_motiontext="null"; m_nbrevoltext="null"; m_degradedtext="null"; m_dischtext="null"; m_Valuespeed=0; m_ValueTorque=0; m_ValueTorqueMax=0; m_ValueCPU1=0; m_ValueCPU2=0; m_ValueCPU3=0; m_ValueCPU4=0; m_ValueCPU5=0; m_ValueCPU6=0; m_ValueCPU7=0; m_ValueCPU8=0; m_ValueId=0; m_ValueIdRef=0; m_ValueIQ=0; m_ValueIQRef=0; m_ValueVD=0; m_ValueVQ=0; m_ValueVDRef=0; m_ValueVQRef=0; m_valueDCvolt=0; }
And Add your code to Backend.h
-
@dziko147 Hey, great you made it :D
You're example was a bit to complex for me to simply restructure in a couple of lines, and I hadn't hat the time to actually tackle it.
All the better that you managed to restructure it yourself with only a few abstract tips! Kudos!
I can post my code if anyone need it
If you want to, do it, no-one is gonna judge :D but some may be grateful and some may offer tips/suggestions still :D
thank you bro :D
-
Dear Reader if you want to display simultaneously your c++ data to Qml .
you can try my solution . :DUsually we can do better but the most important things is that solution works very well :D
So :
First of all we must prepare the app design : try to use this https://doc.qt.io/qt-5/qtqml-cppintegration-topic.html .
then use a Qtimer to make a repetitive read of data.Finally , Use Setters to update your data .
Definition of Qobject class which fill and update data :
In Backend.hQTimer m_fetchFrameTimer;
Backend.cpp
Backend::Backend(QObject *parent ) :QObject(parent),m_fetchFrameTimer(new QTimer(this)) { connect(&m_fetchFrameTimer, & QTimer::timeout, this, &Backend::statuspican); m_fetchFrameTimer.start(1000); //Statuspican : function for fill data
statuspican :
void Backend::statuspican() { //Some code to fetch data setValue(yourvalue);