Russian Qt Forum
Ноябрь 25, 2024, 06:08 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QML Serialport  (Прочитано 10801 раз)
reanon
Гость
« : Октябрь 15, 2017, 18:38 »

всем добрый день .
Подскажите, как в QML получить данные из ком порта?
https://github.com/ncp1402/ql-serial
что то с ней не выходит.
Задача такая. программа по таймеру отсылает запрос контроллеру, контроллер на него отвечает массивом байт, программа парсит массив и выводит инфу , давление жыдкости, время работы насоса , температуру насоса, и сколько жидкости было перекачано.
приложение написал в qt widget. но хочу в qml.
в общем помогите )
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #1 : Октябрь 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, просто
нужно ее почитать и не лениться. Мне добавить больше нечего.
« Последнее редактирование: Октябрь 15, 2017, 19:00 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
reanon
Гость
« Ответ #2 : Октябрь 15, 2017, 19:13 »

спасибо. Но если учесть что я только начинаю учится ). в С++  написал с большим трудом ) чтоб понять как работает хотелось бы увидеть на наглядном примере.
могу выложить исходник приложения в qwidget
может покажете как убрать форму ui и заменить ее на  qml ?
и зачем температуру в дабл? если на температуру прилетает один байт?
« Последнее редактирование: Октябрь 15, 2017, 19:16 от reanon » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #3 : Октябрь 15, 2017, 21:35 »

Цитировать
спасибо. Но если учесть что я только начинаю учится ). в С++  написал с большим трудом ) чтоб понять как работает хотелось бы увидеть на наглядном примере.

Ну, тут я не помошник, см. примеры, разбирайся сам.

Цитировать
могу выложить исходник приложения в qwidget

Я не буду ничего смотреть.

Цитировать
может покажете как убрать форму ui и заменить ее на  qml ?

См. примеры quick/qml в Qt/examples, читай документацию.

Цитировать
и зачем температуру в дабл? если на температуру прилетает один байт?

Я понятия не имею в чем там что прилетает. Один байт - это то что на "нижнем уровне"
это по сути обычно - неких код, но на верхнем обычно этот код пересчитывается в
реальное значение.

Если в итоге температура должна отображаться с запятой (десятые, сотые и пр. градуса),
то тут на верхнем уровне это будет double/float, если целое число - то int и никаких
"одних байтов".
Записан

ArchLinux x86_64 / Win10 64 bit
reanon
Гость
« Ответ #4 : Октябрь 16, 2017, 13:59 »

вот так же можно записать ?
Код:
Q_PROPERTY(quint8 fu READ fu NOTIFY fuChanged)
« Последнее редактирование: Октябрь 16, 2017, 14:01 от reanon » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #5 : Октябрь 16, 2017, 14:51 »

Можно, но нет смысла и проще int
Записан

ArchLinux x86_64 / Win10 64 bit
reanon
Гость
« Ответ #6 : Октябрь 16, 2017, 15:46 »

закончу переписывать это ))
потом задам вопросов еще )))
Если вы не против )_
Записан
reanon
Гость
« Ответ #7 : Октябрь 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 не вьеду ))


на атмеге прошивку управления станком написал за два дня, а тут в полном ступоре че делать )))
там все в одном файле и все работает а тут     ,,,,,,
вобщем помогите пожалуйста )
 
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #8 : Октябрь 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);
}
 
 
Записан

ArchLinux x86_64 / Win10 64 bit
reanon
Гость
« Ответ #9 : Октябрь 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;
 
« Последнее редактирование: Октябрь 17, 2017, 21:10 от reanon » Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #10 : Октябрь 17, 2017, 21:22 »

Цитировать
Подскажите, зачем эта проверка

А самому подумать? И так все на "блюдечке расписал".

Цитировать
то настройки порта правильно писать так?

Смотри документацию и примеры и пробуй сам.

Цитировать
а это штука сама посчитает сколько байт прилетело ? или можно задать какое нить условие с проверкой сколько байт прилетело?

См. документацию...  Злой
Записан

ArchLinux x86_64 / Win10 64 bit
reanon
Гость
« Ответ #11 : Октябрь 17, 2017, 21:52 »

вам Агромнейшее спасибо!
я только начинаю никать.
Поймите, я, железячник. я могу с железа зделать что угодно, а вот программирование дается туговато. с контроллирами я быстро вьехал, и программа первая была в processing. Но на плате с линух арм тормозит жутко. Даже линух арм под себя собрал и qt тудаже скомпилил с нужными мне модулями. вот и решил перейти на Qt. вот как то так. не серчайте)
Записан
reanon
Гость
« Ответ #12 : Октябрь 18, 2017, 16:35 »

вроде получается. 
надо теперь пробовать подключать к контроллеру
Записан
reanon
Гость
« Ответ #13 : Октябрь 18, 2017, 22:49 »

Я, прошу прощения.   
отправляю запрос 1 байт  char
в контроллер прилетает но все таки не то что надо
отправляю так
Код
C++ (Qt)
   char pt = 'A';
    m_uart->putChar(pt);

если отправляю с терминала или любой другой проги то прилетает 'А' как положено и контроллер отвечает пакетом байт
а тут нет
Записан
reanon
Гость
« Ответ #14 : Октябрь 19, 2017, 21:11 »

спасибо большое!!! все у меня получилось. не много поправил прошивку в контроллере и в qt и все заработало
скажите, если для парсинга и и отправки пакетов если использовать структуры будет правильнее ?
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.274 секунд. Запросов: 22.