Название: QML Serialport
Отправлено: reanon от Октябрь 15, 2017, 18:38
всем добрый день . Подскажите, как в QML получить данные из ком порта? https://github.com/ncp1402/ql-serial что то с ней не выходит. Задача такая. программа по таймеру отсылает запрос контроллеру, контроллер на него отвечает массивом байт, программа парсит массив и выводит инфу , давление жыдкости, время работы насоса , температуру насоса, и сколько жидкости было перекачано. приложение написал в qt widget. но хочу в qml. в общем помогите )
Название: Re: QML Serialport
Отправлено: kuzulis от Октябрь 15, 2017, 18:55
Делаешь класс типа: C++ (Qt) class Controller : public QObject { Q_OBJECT Q_PROPERTY(double temperature READ temperature NOTIFY temperatureChanged) .... public: explicit Controller(QObject *parent = nullptr); Q_INVOKABLE void start(); // открывает серийный порт и запускает таймер Q_INVOKABLE void stop(); // останавливает таймер и закрывает порт double temperature() const; // возвращает m_temperature signals: void temperatureChanged(double temperature); private: void processIncomingResponse(); // парсит ответ от контроллера и дергает setTemperature() и т.п. void setTemperature(double temperature); // просто меняет значение m_temperature и емитит сигнал temperatureChanged double m_temperature = 0.0; // температура, полученная от ответа контроллера QSerialPort *m_uart = nullptr; // серийый порт QTimer *m_timer = nullptr; // таймер, который шлет запросы к контроллеру }
Регистрируешь класс Controller в main.cpp для доступа из QML кода: C++ (Qt) int main(int argc, char *argv[]) { ... Controller controller; view.rootContext()->setContextProperty(QLatin1String("controller"), &controller); ...
B QML коде будет доступ к объекту контроллера по имени "controller", где можно прибиндиться на его св-ва типа "temperature" и прочие другие, чтобы их отображать.. C++ (Qt) Text { text: "Temperature: " + controller.temperature }
Все.. в чем проблема? Все это описано в документации по Qt Quick/QML, просто нужно ее почитать и не лениться. Мне добавить больше нечего.
Название: Re: QML Serialport
Отправлено: reanon от Октябрь 15, 2017, 19:13
спасибо. Но если учесть что я только начинаю учится ). в С++ написал с большим трудом ) чтоб понять как работает хотелось бы увидеть на наглядном примере. могу выложить исходник приложения в qwidget может покажете как убрать форму ui и заменить ее на qml ? и зачем температуру в дабл? если на температуру прилетает один байт?
Название: Re: QML Serialport
Отправлено: kuzulis от Октябрь 15, 2017, 21:35
спасибо. Но если учесть что я только начинаю учится ). в С++ написал с большим трудом ) чтоб понять как работает хотелось бы увидеть на наглядном примере. Ну, тут я не помошник, см. примеры, разбирайся сам. могу выложить исходник приложения в qwidget Я не буду ничего смотреть. может покажете как убрать форму ui и заменить ее на qml ? См. примеры quick/qml в Qt/examples, читай документацию. и зачем температуру в дабл? если на температуру прилетает один байт? Я понятия не имею в чем там что прилетает. Один байт - это то что на "нижнем уровне" это по сути обычно - неких код, но на верхнем обычно этот код пересчитывается в реальное значение. Если в итоге температура должна отображаться с запятой (десятые, сотые и пр. градуса), то тут на верхнем уровне это будет double/float, если целое число - то int и никаких "одних байтов".
Название: Re: QML Serialport
Отправлено: reanon от Октябрь 16, 2017, 13:59
вот так же можно записать ? Q_PROPERTY(quint8 fu READ fu NOTIFY fuChanged)
Название: Re: QML Serialport
Отправлено: kuzulis от Октябрь 16, 2017, 14:51
Можно, но нет смысла и проще int
Название: Re: QML Serialport
Отправлено: reanon от Октябрь 16, 2017, 15:46
закончу переписывать это )) потом задам вопросов еще ))) Если вы не против )_
Название: Re: QML Serialport
Отправлено: reanon от Октябрь 16, 2017, 22:38
раньше у меня были mainwindow.h и mainwindow.cpp теперь data.h и data.ccp data.h C++ (Qt) #ifndef GETDATA_H #define GETDATA_H #include <QObject> #include <QtSerialPort/QSerialPort> #include <QTimer> class Controller : public QObject { Q_OBJECT Q_PROPERTY(int sp READ sp NOTIFY spChanged) // skorost koretki Q_PROPERTY(int th READ th NOTIFY thChanged) // oboroty motora Q_PROPERTY(int analog1 READ analog1 NOTIFY analog1Changed) // temperatura masla Q_PROPERTY(int analog2 READ analog2 NOTIFY analog2Changed) // temperatura motora Q_PROPERTY(int incoming READ incoming NOTIFY incomingChanged) // byte do kakoy tochki doshla koretka Q_PROPERTY(int lamps_group_1 READ lamps_group_1 NOTIFY lamps_group_1Changed) // avariynie lampy 1 8 bit - 8 lamp Q_PROPERTY(int lamps_group_2 READ lamps_group_2 NOTIFY lamps_group_2Changed) // avariynie lampy 2 8 bit - 8 lamp Q_PROPERTY(int mapADC READ mapADC NOTIFY mapADCChanged) // davlenie pnevmo nasosa Q_PROPERTY(int batADC READ batADC NOTIFY batADCChanged) // naprizhenie akkuma pri rabote ot akkuma Q_PROPERTY(int rpmVHR READ rpmVHR NOTIFY rpmVHRChanged) // scorost shpindelya Q_PROPERTY(int adjust0 READ adjust0 NOTIFY adjust0Changed) // rezervnie vhody Q_PROPERTY(int adjust1 READ adjust1 NOTIFY adjust1Changed) Q_PROPERTY(int adjust2 READ adjust2 NOTIFY adjust2Changed) Q_PROPERTY(int adjust3 READ adjust3 NOTIFY adjust3Changed) public: explicit Controller(QObject *parent = nullptr); Q_INVOKABLE void start(); // открывает серийный порт и запускает таймер int sp() const; int th() const; int analog1() const; int analog2() const; int incoming() const; int lamps_group_1() const; int lamps_group_2() const; int mapADC() const; int batADC() const; int rpmVHR() const; int adjust0() const; int adjust1() const; int adjust2() const; signals: void spChanget(int sp); void thCChanget(int th); void analog1Changed(int analog1); void analog2Changed(int analog2); void incomingChanged(int incoming); void lamps_group_1Changed(int lamps_group_1); void lamps_group_2Changed(int lamps_group_2); void mapADCChanged(int mapADC); void batADCChanged(int batADC); void rpmVHRChanged(int rpmVHR); void adjust0Changed(int adjust0); void adjust1Changed(int adjust1); void adjust2Changed(int adjust2); void adjust3Changed(int adjust3); private: void parsIn(); void setSp(int sp); void setTh(int th); void setAnalog1(int analog1); void setAnalog2(int analog2); void setIncoming(int incoming); void setLamps_group1(int lamps_group_1); void setLamps_group2(int lamps_group_2); void setMapADC(int mapADC); void setBatADC(int batADC); void setRpmHRV(int rpmVHR); void setAdjust0(int adjust0); void setAdjust1(int adjust1); void setAdjust2(int adjust2); void setAdjust3(int adjust3); int m_sp = 0; QSerialPort *m_uart = nullptr; QTimer *m_timer = nullptr; }; #endif // GETDATA_H
в mainwindow.cpp было так C++ (Qt) #include "mainwindow.h" #include "ui_mainwindow.h" #include "receiver.h" #include <QMessageBox> #include <QPixmap> #include <QPainter> #include <QMatrix> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); initSerialPort(m_serialPort, consComPortName); connect(&m_recvTimer, SIGNAL(timeout()), this, SLOT(getData())); m_recvTimer.start(50); } MainWindow::~MainWindow() { delete ui; } void MainWindow::getData() { // prepare tx buffer STxPacket txPkt; txPkt.req = 'A'; //declare rx buffer const SRxPacket* rx_ptr = NULL; rxBuff.clear(); //calculated data SViewPacket view; m_serialPort.write((const char*)&txPkt, sizeof(txPkt)); rxBuff.append(m_serialPort.readAll()); // check packet size if (rxBuff.size() >= constPacketLen) { rx_ptr = (SRxPacket*)rxBuff.data(); if (CalcRxPacket(rx_ptr, &view)) { } } rxBuff.clear(); }
что теперь писать в data.cpp не вьеду )) на атмеге прошивку управления станком написал за два дня, а тут в полном ступоре че делать ))) там все в одном файле и все работает а тут ,,,,,, вобщем помогите пожалуйста )
Название: Re: QML Serialport
Отправлено: kuzulis от Октябрь 17, 2017, 08:27
что теперь писать в data.cpp не вьеду )) C++ (Qt) Controller::Controller(QObject *parent) : QObject(parent) , m_uart(new QSerialPort(this)) , m_timer(new QTimer(this)) { connect(m_uart, &QSerialPort::readyRead, this, &Controller::processResponse); m_uart->setPortName(...); m_uart->setBaudRate(...); ... connect(m_timer, &QTimer::timeout, this, &Controller::sendRequest); m_timer->setInterval(500); } void Controller::start() { if (!m_uart->open(ReadWrite)) return; m_timer->start(); } void Controller::stop() { m_timer->stop(); m_uart->close(); } int Controller::th() const { return m_th; } void Controller::setTh(int th) { if (m_th == th) return; m_th = th; emit thChanged(m_th); } void Controller::processResponse() { for (;;) { const auto bytesAvailable = m_uart->bytesAvailable(); if (bytesAvailable == 0) return; // Читаем из порта и парсим все что нужно, извлекаем все значения. const int newTh = ...; // распарсили из принятых данных setTh(newTh); // Также по аналогии и для других сигналов/пропертей. ... ... } } void Controller::sendRequest() { // Готовим запрос в порт const QByteArray request = ....; m_uart->write(request); }
Название: Re: QML Serialport
Отправлено: reanon от Октябрь 17, 2017, 20:58
Подскажите, зачем эта проверка C++ (Qt) void Controller::setTh(int th) { if (m_th == th) return; m_th = th; emit thChanged(m_th); }
и если я правильно понял, то настройки порта правильно писать так? C++ (Qt) connect(m_uart, &QSerialPort::readyRead, this, &Controller:: processIncomingResponse); m_uart->setPortName("/dev/ttyACM0"); m_uart->setBaudRate(QSerialPort::Baud19200); m_uart->setDataBits(QSerialPort::Data8); m_uart->setParity(QSerialPort::NoParity); m_uart->setStopBits(QSerialPort::OneStop); m_uart->setFlowControl(QSerialPort::NoFlowControl); m_uart->open(QSerialPort::ReadWrite);
а это штука сама посчитает сколько байт прилетело ? или можно задать какое нить условие с проверкой сколько байт прилетело? C++ (Qt) for (;;) { const auto bytesAvailable = m_uart->bytesAvailable(); if (bytesAvailable == 0) return;
Название: Re: QML Serialport
Отправлено: kuzulis от Октябрь 17, 2017, 21:22
Подскажите, зачем эта проверка А самому подумать? И так все на "блюдечке расписал". то настройки порта правильно писать так? Смотри документацию и примеры и пробуй сам. а это штука сама посчитает сколько байт прилетело ? или можно задать какое нить условие с проверкой сколько байт прилетело? См. документацию... >:(
Название: Re: QML Serialport
Отправлено: reanon от Октябрь 17, 2017, 21:52
вам Агромнейшее спасибо! я только начинаю никать. Поймите, я, железячник. я могу с железа зделать что угодно, а вот программирование дается туговато. с контроллирами я быстро вьехал, и программа первая была в processing. Но на плате с линух арм тормозит жутко. Даже линух арм под себя собрал и qt тудаже скомпилил с нужными мне модулями. вот и решил перейти на Qt. вот как то так. не серчайте)
Название: Re: QML Serialport
Отправлено: reanon от Октябрь 18, 2017, 16:35
вроде получается. надо теперь пробовать подключать к контроллеру
Название: Re: QML Serialport
Отправлено: reanon от Октябрь 18, 2017, 22:49
Я, прошу прощения. отправляю запрос 1 байт char в контроллер прилетает но все таки не то что надо отправляю так C++ (Qt) char pt = 'A'; m_uart->putChar(pt); если отправляю с терминала или любой другой проги то прилетает 'А' как положено и контроллер отвечает пакетом байт а тут нет
Название: Re: QML Serialport
Отправлено: reanon от Октябрь 19, 2017, 21:11
спасибо большое!!! все у меня получилось. не много поправил прошивку в контроллере и в qt и все заработало скажите, если для парсинга и и отправки пакетов если использовать структуры будет правильнее ?
Название: Re: QML Serialport
Отправлено: reanon от Ноябрь 17, 2017, 00:49
C++ (Qt) Controller::Controller(QObject *parent) : QObject(parent) , m_uart(new QSerialPort(this)) , m_timer(new QTimer(this)) { m_uart->setPortName("/dev/ttyAMA0"); m_uart->setBaudRate(QSerialPort::Baud115200); m_uart->setDataBits(QSerialPort::Data8); m_uart->setParity(QSerialPort::NoParity); m_uart->setStopBits(QSerialPort::OneStop); m_uart->setFlowControl(QSerialPort::NoFlowControl); { // if (!m_uart->open(QSerialPort::ReadWrite)) // return; // m_uart->open(QSerialPort::ReadWrite); } start(); connect(m_uart, &QSerialPort::readyRead, this, &Controller:: getStartPkt); connect(m_timer, &QTimer::timeout, this, &Controller::sendStartRequest); m_timer->setInterval(500); connect(m_uart, &QSerialPort::readyRead, this, &Controller:: getPkt); connect(m_timer, &QTimer::timeout, this, &Controller::sendRequest); m_timer->setInterval(50); }
Здравствуйте! подскажите, мне надо разово отправить запрос на один пакет байт с настройками и потом постоянно получать по другому запросу другой пакет. подскажите как правильно это сделать и что почитать. Зарание спасибо
|