Приём-отправка данных между МК и программой на ПК (RS-232)

После того, как вдоволь намигался светодиодом stm32 и посмотрев температуру с LM75, решил погонять данные между компом и демоплатой.
Что именно за данные?
1) Отправка — по тыканью на кнопку в программе зажигаем светодиоды;
2) Прием — в программу сливаем данные с АЦП.
Демоплата — STM32VL-Discovery + CooCox IDE
Для ПК пишу с использованием Qt, который можно выкачать отсюда http://qt.nokia.com/downloads

Disclaimer: я не профессиональный программист, и впервые познакомился с ООП. Да и вообще это моя первая статья. Так что баги/фичи/наставления приветствуются пирожком и конфеткой :)

Допустим мы на stm32 имеем переменную, в которую сливаются данные с АЦП. Так же настроен USART. Нам осталось только настроить вывод printf() в USART.
Для CooCox всё просто: подключаем библиотеку /Retarget printf/ и заменяем в файле stdio/printf.c функцию void PrintChar(char c) на эту:

void PrintChar(char c) {
   USART_SendData(USART1, (uint8_t) c); /* Loop until the end of transmission */
   while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){
      asm("nop");
   }
}


Естественно USART1 заменить на тот USART, который вы используете.
Главный цикл будет иметь вид:


int main(void) {
   SetupClock(); // Устанавливаем частоту ядра
   SetupUSART(); // Настраиваем USART1
   SetupADC(); // Настраиваем ADC на постоянное цикличное преобразование
   SetupLED(); // Порты для двух щтатных светодиодов
   int adc_value = 0; // тут хранится значение начение АЦП
   uint16_t usart_param = 0; // а это - команда, получаенная через USART
   while (1) {
   adc_value = ADC_GetConversionValue(ADC1); // Получаем значение АЦП
   long i = 0; // инициализация цикла постнадарту ISO C
   for (i = 0; i < 0xFFFFF; ++i) {
      asm("nop"); // Задержка. что бы небыло спама значения АЦП
   }
   printf("A %d\r\n", adc_value); // Отправляем данные. "<Команда> <Значение>"
   usart_param = USART_ReceiveData(USART1); // Зажигаем/гасим светодиод, в зависимоти от полученной команды
   switch (usart_param) {
      case 0x31: // ASCII: 1
         GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET); break;
      case 0x32: // ASCII: 2
         GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET); break;
      case 0x33: // ASCII: 3
         GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_SET); break;
      case 0x34: // ASCII: 4
         GPIO_WriteBit(GPIOC,GPIO_Pin_9,Bit_RESET); break;
      default:
         break;
   }
   usart_param = 0;
}

Всё обильно залито комментариями. Но вкраце: получаем значение АЦП, отправляем его, предварительно снабдив префиксом «А», что бы программа знала, что это именно значение АЦП. Затем смотрим содержимое буфера-приемника USART, и если там например ASCII код цифры «1», что включим синий светодиод на Discovery.
Полный листинг можно будет посмотреть или здесь или в архиве, приложенному к посту.

Прошив МК и подключившись терминалом к COM порту, проверили, что есть сообщения с текстом вида «А 4091».
Переходим к главной теме — программе для ПК.

Как я уже сказал, использую Qt. Базовый функционал обеспечивает библиотека QSerialDevice. У неё есть и альтернатива — QExtSerialPort, но с ней как-то не срослось.
Создаём новый Qt проект в Qt Creator (Qt widget -> GUI проект Qt). Скачиваем последнюю (Master) версию QSerialDevice https://gitorious.org/qserialdevice/qserialdevice/archive-tarball/master, и разархивируем её рядом с папкой нашего новосозданного проекта. Возможно понадобится её переименовать в qserialdevice.

Теперь вся работа в Qt Creator.
1) Подключаем статически библиотеку. В файл проекта .pro (у меня проект называется Focade, соотв. файл имеет имея Focade.pro) добавляем строки
unix:include(../qserialdevice/src/unix/ttylocker.pri)
include(../qserialdevice/src/qserialdeviceenumerator/qserialdeviceenumerator.pri)
include(../qserialdevice/src/qserialdevice/qserialdevice.pri) win32 { LIBS += -lsetupapi -luuid -ladvapi32 } unix:!macx { LIBS += -ludev }

Если папка с библиотекой qserialdevice расположена иначе, то корректируем пути.
Жмём Ctrl+R (Запуск) и проверяем, что проект успешно собрался и запустился, показав нам пустое окно формы.

2) Формируем GUI. Открываем форму (Формы-> .ui) и перетаскиваем в неё всё необходимое для счастья: кнопки (Push button), текстовые поля (Line Edit), тестовые метки (label), выпадающие списки (Combo box).
Даём им более понятные имена (objectName). Ниже показал примерно что я хотел сказать :)


Заранее создаём события при нажатии на кнопки. Тут всё просто — правой кнопкой мышки тыкаем на кнопку (во тавтология-то) и выбираем сигнал Clicked(). Повторяем сие действие для всех «тыкательных» органов нашей программы.

Лирическое отступление: что за слоты? А эта хитрая система сигнал-> слот аналогична системе прерываний. Определённое событие-сигнал (напр. Clicked() — нажатие на кнопку), вызывает прерывание-слот (напр. «void Focade::on_pbSendCmd_clicked()»).

3) Наконец-то пишем код :)
main.c мы не трогаем, сразу переходим к focade.h (или как вы там проект у себя обозвали), добавив заголовочный файл библиотеки:

#include <ABSTRACTSERIAL.H>


Парочку внутренних переменных/прототипов:
private:
   AbstractSerial *serial; // Здесь хранится наш порт
   QByteArray bytes; // байты, принятые через USART
   bool led_status[2]; // Храним текущее состояние светодиодов
   void initSerial(); // Инициализации посл. порта
   void deinitSerial(); // И деинициализация (закрытие) порта


Весь основной код помещаем в файлик <имя_проекта>.c (у меня focade.c). Постарался добавить максимальное кол-во комментариев :)
#include "focade.h"
#include "ui_focade.h"
#include <abstractserial.h>
#include <QDebug> // необходим для вывода отладочных сообщений

Focade::Focade(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Focade)
{
    ui->setupUi(this);
    this->initSerial(); // Первоначальная инициализация
}

Focade::~Focade()
{
    this->deinitSerial(); // Закрытие порта
    delete ui;
}

void Focade::initSerial()
{
    serial = new AbstractSerial(); // Новый экземпляр класса AbstractSerial
    connect(this->serial, SIGNAL(readyRead()), this, SLOT(serialRecieve())); // объявляем наше "прерывание" по получении данных
}

void Focade::deinitSerial()
{
    if (this->serial->isOpen()){
	this->serial->close();
    }
    delete serial;
}

/* "Прерывание". Сюда мы попадаем при наличии байтов в буфере USART*/
void Focade::serialRecieve() {
    QByteArray temp_data = serial->readLine(); // Заполняем массив данными
    if (temp_data.indexOf("\n") != -1) {
	// Получили переход на новую строку - значит приняли данные
	bytes += temp_data;

	// Грязная магия - парсим данные. Делим массив на две части: до пробела (команда) и после (параметры)
	// Затем очищаем параметры от \r\n, и преобразуем в unsigned int
	uint adc_value = bytes.split(' ').at(1).split('\r').at(0).toUInt();

	// Преобразуем данные АЦП в миливольты.
	// А за тем uint преобразовывается в строку, которую отображаем в тестовом поле leADC
	ui->leADC->setText(QString::number(adc_value / 1.365));
        bytes.clear();
    } else {
        bytes += temp_data;
    }
}

/* Кнопка открытия-закрытия порта. В зависимости от состояния порта или открывает его или закрывает */
void Focade::on_pbPortOpen_clicked()
{
    if (this->serial->isOpen()) {
	serial->close();

	// Делаем недоступными пользователю элементы управления
	ui->pbSendCmd->setEnabled(false);
	ui->pbLed1->setEnabled(false);
	ui->pbLed2->setEnabled(false);
	ui->leCommand->setEnabled(false);
	ui->cbBaud->setEnabled(true);
	ui->lePort->setEnabled(true);
	ui->pbPortOpen->setText("Open");
    } else {
	serial->setDeviceName(ui->lePort->text()); // Порт, который открываем - берём из поля lePort
	if (serial->open(AbstractSerial::ReadWrite)) { //
	    qDebug() << "Порт " << serial->deviceName() << " открыт в режиме " << serial->openMode();

	    // Классная штука - устанавливать параметры порта можно после открытия
	    serial->setBaudRate(ui->cbBaud->currentText()); // Скорость выбираем из выпадающего списка cbBaud
	    serial->setDataBits(AbstractSerial::DataBits8);
	    serial->setParity(AbstractSerial::ParityNone);
	    serial->setStopBits(AbstractSerial::StopBits1);
	    serial->setFlowControl(AbstractSerial::FlowControlOff);

	    // разрешаем пользователю тыкать на кнопочки управления
	    ui->pbSendCmd->setEnabled(true);
	    ui->pbLed1->setEnabled(true);
	    ui->pbLed2->setEnabled(true);
	    ui->leCommand->setEnabled(true);
	    ui->cbBaud->setEnabled(false);
	    ui->lePort->setEnabled(false);
	    ui->pbPortOpen->setText("Close");
	} else {
	    qDebug() << "Error opened serial device " << serial->deviceName();
	}
    }
}

/* Кнопка Send */
void Focade::on_pbSendCmd_clicked()
{
    QByteArray data; //Отсылаемые данные
    data.clear(); // Паранойя - на всякий случай очистить массив
    data.append(ui->leCommand->text());
    serial->write(data);
}

/* Кнопка LED1 */
void Focade::on_pbLed1_clicked()
{
    // Зажигаем/гасим светодиод, в завсисимости от его текущего состояния
    if (led_status[0] == false) {
	serial->write("2");
	led_status[0] = true;
    } else {
	serial->write("1");
	led_status[0] = false;
    }
}

/* Кнопка LED2 */
void Focade::on_pbLed2_clicked()
{
    if (led_status[1] == false) {
	serial->write("3");
	led_status[1] = true;
    } else {
	serial->write("4");
	led_status[1] = false;
    }
}


Собираем (Ctrl+B), запускаем (Ctrl+R) и думаем к чему полезному прикрутить :)
Видео, как всё работает:
  • +2
  • 26 октября 2011, 19:37
  • ursadon
  • 2
Файлы в топике: stm32 project.zip, Qt project.zip

Комментарии (137)

RSS свернуть / развернуть
неплохой пример, все понятно.
из замечаний (неглобальных):
в конструкции

while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{
      asm("nop");   
}

можно убрать

{
      asm("nop");   
}

и оставить

while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);

компилятор сам все правильно сделает.
0
и оставить
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);

обращаю внимание на точку с запятой в конце строки. так же можно оставить пустые фигурные скобки.
0
Автор молодец!

OFF: Блин, кругом современные веянья, эх… Интересно, я один до сих пор на делфях все пишу (даже весь свой «умный дом» на них крутится)? :)
0
Qt — не модное веянье, а довольно старый аналог VCL для плюсов. Кроссплатформенный.
0
Qt довольно динамично развивается. И если сравнивать с VCL для Delphi7 — то Qt нааамного лучше.
0
Где-то лучше, где-то хуже (например, крайне мало сред способны как дельфи устанавливать компоненты — без написания дополнительного кода, даже без перезапуска среды). Но назначение схожее — гуи-тулкит.
0
Qt как раз модное веянье.
Когда нужно сделать что-то c GUI, что будет работать на Win, MacOS, UNIX и Linux. Альтернатив просто не существует (не надо вспоминать ужасы GTK+).
0
>> Альтернатив просто не существует
Ну зачем же так категорично? А чем плох wxWidgets? Он проще в освоении, требует меньше ресурсов, имеет нативный ЛукЫнФил под разными операционками и никаких костылей типа moc. Ну разве что отстаёт в плане современных технологий, но глядя на Qt я всё больше задумываюсь на тему, а оно вообще надо?
Да и GTK, на самом деле, не так уж и страшен. А есть и другие фреймворки.

Кстати, тот же дельфи тоже бывает кросс-платформенным — есть ведь его открытый клон Lazarus. Правда ничего конкретного про него сказать не могу, так как само дельфи, да и паскаль в целом, терпеть не могу, но знаю как минимум одно приложение на нём написанное — торрент клиент transmission remote GUI — постоянно пользуюсь в виндах и линухе, выглядит нормально, работает стабильно.
0
Ну лазарус игрушка из несколько иной оперы, да и использует не дельфи, а фри паскаль — все же несколько разные диалекты.
Кроме того, аналог Qt в Delphi — это VCL. Он, вообще говоря, не кроссплатформенный. Кроссплатформенны его поднабор CLX (впрочем, Kylix нечто странное и мертворожденное) и частично совместимый с ним по API LCL (аналог VCL из Lazarus).

А вот насчет wxWidgets плюсую, вполне альтернатива.

Qt как раз модное веянье.
Алсо это как раз в посте и не обосновано. Qt мощный инструмент и популярен довольно давно. Особенно среди тех, кого не напрягала его цена (ну и среди GPL, где он довольно давно доступен бесплатно).
0
Последним абзацем — просто порвал.
А кого у нас напрягает стоимость Delphi? Или каких других программ(библиотек)? :-)
0
Ну, допустим, мир пиратскими Россией и Китаем не ограничивается.
А в тех кругах, где актуален кьют лицензионная чистота (большие компании) и GPL'ность (линух) имеют большее значение. Под виндой у инди-девелоперов он популярен стал относительно недавно.
Да, и кстати, CLX был натянут поверх Qt
Угу. И что?
0
Да, и кстати, CLX был натянут поверх Qt, по крайней мере в Kilix
0
Ага, таких подробностей не знал, спасибо.
0
На wxWidgets я не видел ни одного большого проекта. Класса KDE или GNome.

А вот moc, как раз не костыль. Фактически существует два подхода к функциональным языкам програмирования — стек и сообщения. С/С++ изначально являются стековыми языками. Но вот незадача — для оконных систем лучше языки с передачей сообщений.
Например Objective-C, Smalltalk и так далее.
moc является расширением C++ для передачи сообщений. В идеале было бы прекрастно скрестить C++ и Objective-C. Но к сожалению это невозможно без потери совместимости.

По поводу простоты. Никаких GUI тулкитов, проще в освоении чем Qt несуществует.
Если конечно вы програмист, а не веб-дезигнер.

PS Посмотрите на рынок. Кто сейчас востребован? С# + .net, Java в разных вариациях, C++ + Qt, Objective-C + iOS/Mac OS. Где GTK? Где wxWidgets?

За 20 лет что я занимаюсь програмированием, Qt первый и единственный _логично_ построеный кросплатформенный Gui тулкит.

GTK — Не имеет комерческой поддержки. Внутри очень много недоделок, которых никогда недоведут до ума.

wxWidgets — хоть пристрелите, не помню ни одного большого продукта написаного на нем. Насколько я помню финансируется единствнным меценатом. Возможно имеет смысл для чего-то легкого и мелкого.

EFL — написан на C. Переносим, но страшен. Бухали с его создателем, после чего мы шутки ради спортировали его на ThreadX (это ОСь такая)… Что прикольно — получилось и даже вроде работает. Возможно даже где-то есть на прилавках.
Для больших вещей я бы его тоже не брал. Нет объектности. Нет плюсов.
0
На wxWidgets я не видел ни одного большого проекта.
Зато не очень большие — не редкость.
А вот moc, как раз не костыль.
Таки костыль для генерации нормального RTTI.
По поводу простоты. Никаких GUI тулкитов, проще в освоении чем Qt несуществует.
VCL. Он настолько прост, что создал дельфи репутацию быдлоязыка, т.к. из-за его простоты развелось более 9000 быдлокодеров на Delphi. Правда, он не кроссплатформенный.
0
А что можно по Qt почитать? А то периодическ возникает нужда накалякать утилитку какую для компа. Да только из всего что знаю помню только Дельфи древней какой то версии :)
0
1) Макс Шлее — Qt. Профессиональное программирование на C++.
2) Qt 4.5 Программирование GUI на С++.

В первой автор использует Qt версии 4.2/4.3
0
Там оригинально документации хватает + гугл.
Последовательность чтения — signal/slot, потом QObject, QString и многоязычность. После это читаем исходноик найболее подходящего example. Там все очень просто. Единственная проблема с которой я сталкивался, это точто GUI-ей нельзя рулить из разных потоков. Т.е. в начале нужно все события аккумулировать в одном потоке, и из него уже передавать GUI.
0
Delphi — весьма неплохая и удобная IDE, пусть и не без недостатков и быстро устаревающая. Пишу много на чём, но Дельфи остаются самыми любимыми. Кстати, DipTrace написана на Дельфи. Так что рано их хоронить :)
+2
ну конечно устаревающая. с делфями целые энтерпрайзные студии выходят по крутости в стопицот раз круче всяких мс студий. делфя сейчас намного лучше развивается, чем куте. но она и денег стоит серьезных. хватит уже фантазировать.
0
Лучше сказать «дельфи наконец-то развиваться начала». Правда, вопрос не поздно ли.
с делфями целые энтерпрайзные студии выходят по крутости в стопицот раз круче всяких мс студий.
Я надеюсь это не про IDE? IDE у BDS/RAD Studio (Galileo) и новых MSVS сравнимы по развитости, да и Galileo (IDE борланда, начиная с Delphi 8) явно с MSVS срисована. Только глючна до ужаса.
0
Делфи рулит
достаточно глянуть на кучу кода выше
для реализации элементарных(казалось бы) вещей.
пара тройка строк на делфи и никакого гемора))))
0
а не))) в коде выше всё тоже компактно просто невнимательно позырил
но тем не менее делфи както роднее
на крайняк VB
0
Гм… А Вы можете сказать, какой код в дельфи или VB отвечает за действие «создать формочку», или «обработать событие»? Да там всё описание гуя сводится к паре файлов с непонятными буковками, а уж что там в потрохах… Нет уж, спасибо, я уж буду иметь кучу кода (который, кстати, вполне может IDE за меня написать), но я буду точно знать что и в каком порядке он делает.
И да, кстати, а в Дельфи сайзеры есть? В VB, когда мне пришлось на нём писать, ничего такого и в помине небыло и при изменении размера окна все размеры/координаты контролов приходилось пересчитывать руками…
0
А Вы можете сказать, какой код в дельфи или VB отвечает за действие «создать формочку», или «обработать событие»?
Да, разумеется. Форму создает вызов Application.CreateForm(Form, TForm). При этом форма динамически создается по файлу описания .dfm (Qt кстати тоже так умеет, но когда я его щупал, основным методом там была автогенерация кода вида new QButton(blablabla), динамическая загрузка была опцией).
По событию не совсем ясно, про какие это события? Если OnClick и прочие — это, по сути, обычный callback, если виндовые — там довольно хитрый механизм их раздачи через механизм динамических методов.
Проще говоря, ты просто не знаешь дельфи, поэтому у тебя и возникают такие вопросы) С другой стороны, это не так уж и нужно, чтобы на дельфи писать. Достаточно знать, как оно себя ведет.

С сайзерами хуже, их в VCL нет (хотя мона и написать). Есть правда свойства Align и Anchor, не так круто, но в 90% случаев хватает, чтобы форма корректно себя вела при ресайзе без написания кода.

Плюсы у VCL тоже есть. Она маленькая (от 400кб, кьют на порядок больше), очень простая в освоении, но при этом мощная и гибкая (вообще, надо отметить, API VCL спроектирован очень хорошо), работает через нативные интерфейсы и не требует различных пререквизитов (Qt, .net, VB Runtime и прочая). Плюс очень удобный редактор форм, поддерживающий установку компонентов на лету — эту фишку я вообще больше нигде не видел, в дотнете разве что может есть что-то подобное.
0
Да, дельфи я не знаю, но приходилось писать на VB и щупал C++ Builder. Так вот, меня откровенно напрягало то, что я не вижу половину кода. А в билдере ещё отпугнуло ещё наличие толпы нестандартных типов данных на каждый чих. В wx весь код я могу писать сам и, соответственно, изменять что угодно, видеть что куда передаётся и тд. Лично мне такой подход гораздо приятнее.
0
А что, в wx ты видишь скрытый в его потрохах код? Или, быть может, ты видишь код, скрытый в недрах WinAPI? Или тебя напрягает отсутствие файлика с сгенеренными new QButton(...)?
VCL — фреймворк. Он для того и нужен, чтобы скрыть особенности платформы под удобным интерфейсом. И по большей части им можно успешно пользоваться, не вдаваясь в подробности внутренней организации.

Что до нестандартных типов билдера — VCL невозможно сделать на C++, она жестко завязана на возможности Delphi. Поэтому даже для ее привязывания к плюсам (сама VCL в билдере написана на дельфи) требуется куча расширений языка и прочих костылей.
0
спс за инфу!
0
Да, в wx я вижу код его потрахов (в отличии от Qt, кстати, там разобраться весьма просто, ибо там нет никаких костылей, если не считать оными толпу макросов). В недра WinAPI я, конечно, залезть не могу, но, обычно, внутренностей wx вполне достаточно для отладки. Отсутствие файлика с сгенеренными new QButton(...) меня тоже сильно напрягает, так как в коде ориентироваться заметно проще, чем в xml и иже с ними.
0
Ну а что мешает заглянуть в $(DELPHI)\Sources\VCL и покопаться в его потрохах?
В форме ориентироваться вообще незачем, это визуальный ресурс и для него есть визуальный редактор.
В общем, информация о внутренностях VCL/Qt не нужнее, чем о внутренностях WinAPI. Достаточно знать как оно работает снаружи. А задокументированы они отлично.
0
в Делфи и вроде в СБилдере можно очень бисто и легко взглянуть на потроха(на какой тип ссилается, где объявлен, что аз процедура) удерживая кнопку Ctrl и нажимая левой кнопкой миши на нужном слове, типе, процедуре, функции. И так Ти попадеш в дебри откуда ето слово взялось. Очень полезный функционал, постоянно етим пользуюсь!
+1
Самый крутой редактор форм (и, параллельно, кода) был в VA Smalltalk (ну и в VA C++, но несколько похуже). Ни одна современная IDE (по крайней мере из тех, что я видел) так и не смогла дотянуться до него. Софтинка, кстати, весьма старая, я первый раз с ней игрался в 95-м.
0
Можешь поподробнее? Что за зверь такой?
0
Было (не знаю как сейчас) целое семейство IBM-овских инструментов VisualAge. В том числе VisualAge Smalltalk. Собственно, это центральный продукт, остальные пользовались IDE написанными на VA ST.
Подробнее можно рассказывать долго, но центральная идея, вобщем, достаточно проста — накидываем компоненты (не только гуевые) на форму и потом в гуе описываем реакцию на события (типа «если нажали эту кнопку, то вот эти контролы должны заэнейблится»), причем для этого не нужно (хотя, при необходимости, можно) писать код.
0
По данным википедии, Делфи появился в 1995, а Qt в 1992, хотя полностью свободным он стал в 2005 году. :)
0
1) функция
deinitSerial()
— не нужна.
Надо при создании экземпляра AbstractSerial() указать его родителем форму ->
serial = new AbstractSerial(this); // Новый экземпляр класса AbstractSerial
. И все, при уничтожении главного окна будет вызван деструктор
~AbstractSerial()
а в деструкторе закроется порт.

2) У порта есть замичательная функция —
QStringList AbstractSerial::listBaudRate() const;
.
Соответственно инициализация списка сокростей может быть выполнета так
ui->cbBaud->addItems(serial->listBaudRate());
.

3) В состав библиотеки SerialDevice входит замечательный класс
SerialDeviceEnumerator
.
Поэтому если заменить тип
lePort
с
QLineEdin
на
QComboBox
можно легко и элегантно проинициализировать список доступных в системе портов:
ui->lePort->addItems(SerialDeviceEnumerator::instance()->devicesAvailable());

Прочитать имя выбранного порта можно так:
ui->lePort->currentText()
+1
1) Ок, примем к сведению :)
2) Полностью довериться ::listBaudRate() нельзя, ибо если приспичит выставить нестандартное значение скорости… Ну тут уже дело вкуса и дополнительного поля.
3) Уху не зря же мы подключали
include(../qserialdevice/src/qserialdeviceenumerator/qserialdeviceenumerator.pri)
:)
Изначально я проводил энумерацию портов, но при тесте в *nix он помимо нужного мне /dev/ttyUSB0, выводил в комбобокс все 32 /dev/ttyS**. А так класс очень удобный.

Возьми конфетку и пирожок :)
0
Возьму только конфетку.
А по поводу скорости — стандартные драйвера работают со стандартными скоростями.
По поводу энумератора портов. Сам не пробовал — но думаю стоит смотреть на характеристики порта которые предоставляет SerialEnumerator, и по этим характеристикам фильтровать полный список.

Р.S. Таки на видео линух, а в арxиве *.exe. Я тихо диссонировал :)
0
Don't panic! This is «World of crossplatform!» :)
Qt няшная штуко ^_^
0
Что есть «стандартные драйвера»? В виндах стандартные драйвера позволяют использовать почти любую скорость.
0
Еще, я бы Вам посоветовал всегда «валидировать» любые данные полученные «извне» (пользовательский ввод, чтений из файла/порта и т. д.). Я понимаю, что в данном случен это «тестовый» код, приведенный для примера, но (раз хотите критики):
1. Если устройство будет, по какой либо причине, слать мусор – любые символы кроме '\\n', то весь этот мусор будет накапливаться в массиве bytes до тех пор, пока на ПК не кончится память.
2. Аналогично,
uint adc_value = bytes.split(' ').at(1).split('\r').at(0).toUInt();
не проверяет строку на соответствие ожидаемому формату представления данных.
0
Не отрицаю, можно было бы много чего реализовать, но я боялся за размер статьи.
А так можно мысль развить вплоть до 100% покрытия кода юнит-тестами :)
0
ui->lePort->addItems(SerialDeviceEnumerator::instance()->devicesAvailable());
Не видит у меня виртуальных сом-портов. Так должно быть? =)
0
нет, что-то не так.
0
хм Что же например...?
0
void MainWindow::initSerial()
{
    this->serialport = new AbstractSerial(); // Новый экземпляр класса AbstractSerial
    connect(this->serialport, SIGNAL(readyRead()), this, SLOT(serialReceive())); // объявляем наше "прерывание" по получении данных

    this->enumerator = SerialDeviceEnumerator::instance();

    ui->cbSerialPort->addItems(this->enumerator->devicesAvailable());
    ui->cbBaudRate->addItems(this->serialport->listBaudRate());

    connect(this->enumerator, SIGNAL(hasChanged(QStringList)), this, SLOT(procEnumerate(QStringList)));

}


void MainWindow::procEnumerate(const QStringList &l)
{
    ui->cbSerialPort->clear();
    ui->cbSerialPort->addItems(l);
}



class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    
private slots:
    void on_pbOpenPort_clicked();
    void serialReceive();
    void procEnumerate(const QStringList &l);
.....


и все прекрасно видится
0
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include #include <abstractserial.h>
#include <serialdeviceenumerator.h>

#include // необходим для вывода отладочных сообщений

namespace Ui {
class MainWindow;
}

class MainWindow: public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pbOpenPort_clicked();
void serialReceive();
void procEnumerate(const QStringList &l);

private:
Ui::MainWindow *ui;

AbstractSerial *serialport; /
SerialDeviceEnumerator *enumerator;
QByteArray packet;

void initSerial();
};

#endif // MAINWINDOW_
0
эх… у меня сейчас тоже ломка. Прихордится отказываться от делфей и пересаживаться на qt. По началу — воротит, потом привыкаешь… потом наверное будет нравиться))
0
Здорово, очень кстати, спасибо. Единственое, чего не понимаю, зачем int передавать в виде строки? Можно обойтись двумя байтами вместо четырех. Но тогда непонятно как парсить. Я делал посылки пятибайтовые — «sXXXp», где s — старт пакета а р — его окончание. ХХХ — три байта, первый из которых адрес в памяти слейва, а два следующих — значения двух адресов, начиная с указанного. Но вот парсить по-человечески я так и не научился. Выгребал это все в QByteArray, а дальше была чудовищная свистопляска. И все держалось на том, что данные не теряются. Потеряли байт — уронили коммуникацию. Все искал/ищу как правильно по уму распарсить входной сырой поток, но что-то ничего толкового не нахожу.
0
Ну в этом вопросе я долго копался. Мне не удавалось нормально получить и сменить систему счисления. При парсинге данных из приёмника, из-за ошибки передачи (всё-таки 0.1% ошибок на скорости 115.2к это много) вывод в LineEdit происходил или криво, или вообще в Segfault всё выпадало.
Не долго думая, решил получать данные сразу строкой через ReadLine(). Вообщем надо реализовывать CRC,

Кстати, в linux'e (kubuntu) если верхнюю строку меню в форме оставить пустой (не создавать меню), то при нажатии на Alt приложение экстренно завершается. Винда к этому подходу более толерантна :)
0
Вот читал я этот коммент, читал.
И никак у меня не вяжутся ошибки передачи и Segfault.
0
Про строчку — неправда. Возможно вы создли меню, но без компонентов.
0
У меня тоже подобная задача есть — сливать данные с нескольких каналов АЦП. Я делал так: брал некий старт байт, например 0xAB и n байтов данных и циклически фигачил их в порт. На компе читал n+1 байт и если первый из них не 0xAB, то искал его во входном массиве, исходя из того, каким по счёту он оказался, вычислял, сколько мне ещё надо считать байт, считывал их в пустоту, после чего снова считывал n+1 байт. Работает стабильно. Данные передавал либо в сыром виде, либо упаковывал. Если хватало времени, добавлял ещё тупую контрольную сумму (byte[n+1] = byte[0] + byte[1] +… + byte[n]).
0
А где гарантия что в какой-то момент ADC не покажет значение 0xAB???
0
Какая ещё гарантия? Он же АЦП, он что намерил, то и покажет, и, конечно, там может встретиться 0xAB. Другой вопрос «когда?». Если когда поток синхронизирован — то и пофиг. Если в момент синхронизации, да ещё и в её хвосте (то есть после того байта, с которого мы начали читать), тогда хуже — один пакет прохлебаем. В худшем случае он прилетит в тот момент когда начали читать, тогда пакет будет порченным. Если важно не допустить невалидных данных добавляем «тупую контрольную сумму». Если 0xAB встречается постоянно, что маловероятно, значит надо чесать репу и, либо выбирать другой стартбайт, либо добавлять избыточную информацию. Избыточной информацией может быть либо увеличение старт-байта до двух байт ( =) когда организовывал радиоканал на среднетупых радио модулях использовал вообще байт 6 где-то), либо экранировать имеющийся стартбайт в потоке данных (если данные не упакованы, добавляем один битик в незначащий разряд АЦП, с которым, например, ксорим младший байт, пологая, что старший принципиально не может совпасть со стартбайтом).
0
Для таких целей существует байт-стаффинг.
Передача данных осуществляется в двоичном виде, т.е. используются все возможные значения байта (00h...FFh). Для передачи служебной информации зарезервированы два кода: FEND = C0h (Frame End) и FESC = DBh (Frame Escape). Управляющий код FEND служит для обозначения начала посылки, а код FESC служит для передачи ESC-последовательностей. Если в потоке данных встречаются байты, значения которых совпадают с управляющими кодами, производится подмена этих байт ESC-последовательностями. Такой механизм называют байт-стаффингом (byte stuffing). Код FEND заменяется последовательностью , , а код FESC — последовательностью , , где TFEND = DCh (Transposed FEND), TFESC = DDh (Transposed FESC). Коды TFEND и TFESC являются управляющими только в ESC-последовательностях, поэтому при передаче данных они в подмене не нуждаются.

Полный пример здесь www.digit-el.com/files/open/wake/wake.html
0
Код FEND заменяется последовательностью «FESC,TFEND», а код FESC — последовательностью «FESC, TFESC»
0
Да… писал я с полгода назад подобную штуку на Qt. Только не использовал готовую библиотеку COM-порта, а реализовывал весь функционал с нуля, на WinAPI. Дело в том, что данные библиотеки не поддерживают нестандартные скорости порта, а мне нужна была именно нестандартная, для конвертера USB-RS232. До реализации на Linux дело так и не дошло, а жаль…
0
Для нищебродов вроде меня — вот мой способ передачи данных из excel в контроллер.
minilabmaster.com/cgi-bin/yabb2/YaBB.pl?num=1319123403
Контролер — AVR, код там тривиальный, если хотите — выложу.
0
  • avatar
  • Omul
  • 31 октября 2011, 02:58
Буквально пару недель назад сделал аналогичный проект. Только разговаривал с AVR'кой =)
И ещё полученные данные визуализировались в виде графика от времени с помощью Qwt.
Может есть в сообществе люди, разбирающиеся в высокоуровневом программировании, и готовые написать цикл статей об обработке данных на ПК? Хочется повысить свой уровень быдлокодинга, глядя на разумный код по коррелирующим проектам.
0
А как Qt работает с несколькими ком портами? просто вижуал студия работу с двумя компортами уже не поддерживает. Приходится собственный класс ком порта писать, используя винапи средства. Нормальный сишный класс, хорошо работающий с несколькими ком портами есть только под билдер, но на Qt интерфейсы более красивые получаются.
0
  • avatar
  • saxel
  • 31 октября 2011, 12:52
2 порта одновременно работает точно (проверено лично). Думаю и больше будут работать.
0
просто вижуал студия работу с двумя компортами уже не поддерживает
Вы чего-то недопонимаете. VS – это среда разработки, с портами она не работает :) Для работы с портами используются функции Win32API. Работать одновременно с 2 (и более) портами – не проблема, открываем один порт, получаем хендл, открываем второй, получаем другой хендл. Дальше используем эти хендлы для чтения/записи в конкретный порт. В чем проблема?
0
Проблема, наверное, в хорошей и практичной «обертке» над этими хендлами.
0
Проблема в том, что с одним хендлом VS работает, а с двумя уже нет, встроенный класс в вижуал студии кривой, надо писать свой, вот к чему я клоню.
0
А вы не пробовали создавать 2(и более) экземпляра классов. Да, кстати, что за класс?
0
Начиная с 2005 студии там есть встроенный компонент SerialPort.
0
Вы чего-то недопонимаете.
А вы с пробовали с двумя и более последовательными портами работать в вижуал студии? Создаю два экземпляра класса сериал порт, настраиваю их одинаково(на разные СОМ порты), начинаю прием данных, по одному ком порту, данные продолжают идти, обмен идет нормально, по второму принимаю максимум 5 байтов и он затыкается. Полазив по форумам, выяснил, что такая проблема не только у меня, так что на кривизну рук прошу не валить. Метода решения этой проблемы, кроме как написать свой класс, я не нашел. Для билдера есть хороший класс называется UART-modem, с ним программа ведет обмен по обоим последовательным портам стабильно. Собственно, потому и интересуюсь, как с этим обстоит дело у Qt?
0
Как я уже писал, я работал с несколькими портами через Win32API. С SerialPort не работал – я избегаю использования .NET компонент в С++.
0
всю жизнь пользовался вот этим, всё прекрасно работает и с двумя и более портами.
единственная проблема была с какими-то USB-COM переходниками под 64 разрядной XP при неправильном завершении программы без закрытия портов иногда винда валилась в синний экран, но это уже проблемы кривых драйверов.
вдруг еще кому пригодится:
pastebin.com/twP7vHre
0
У неё есть и альтернатива — QExtSerialPort, но с ней как-то не срослось.
А что именно не срослось?
В своем приложении использую именно QExtSerialPort и очень удобно.
0
Здравствуйте, не могли бы вы пояснить почему у меня косяки выплывают на первом же этапе создания обертки.
Подключаю библиотеки в файл pro, появляются нужные подпроекты, но при сборке валится куча ошибок, при всем этом ваша версия проекта собирается без проблем.
0
Скорее всего несовпадение фазы луны и марса. :)

Текст ошибок или скриншоты покажите. Разберёмся.
0
In file included from qserialdevice\abstractserialnotifier.cpp:2:
qserialdevice\/nativeserialnotifier.h:8:50: error: QtCore/private/qwineventnotifier_p.h: No such file or directory
In file included from qserialdevice\abstractserialnotifier.cpp:2:
qserialdevice\/nativeserialnotifier.h:18: error: expected class-name before ',' token
qserialdevice\/nativeserialnotifier.h:37: error: 'OVERLAPPED' in namespace '::' does not name a type
qserialdevice\/nativeserialnotifier.h:38: error: 'DWORD' in namespace '::' does not name a type
qserialdevice\/nativeserialnotifier.h:39: error: 'DWORD' in namespace '::' does not name a type
mingw32-make[2]: *** [build/obj/abstractserialnotifier.o] Error 1
mingw32-make[1]: *** [debug] Error 2
mingw32-make: *** [sub-src-make_default] Error 2
Процесс «C:\QtSDK\mingw\bin\mingw32-make.exe» завершился с кодом 2.
Возникла ошибка при сборке проекта BuildLibrary (цель: Desktop)
Во время выполнения сборки на этапе «Сборка»


зы. обычные проектики небольшие я собираю без проблем в нем
0
черт, сори, не те сообщения скинул, а пост не могу понять как удалить, вот правильные:
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:27:48: error: QtCore/private/qwineventnotifier_p.h: No such file or directory
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp: In destructor 'virtual SerialDeviceEnumeratorPrivate::~SerialDeviceEnumeratorPrivate()':
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:78: error: invalid use of incomplete type 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\/serialdeviceenumerator_p.h:101: error: forward declaration of 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:79: warning: possible problem detected in invocation of delete operator:
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:79: warning: invalid use of incomplete type 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\/serialdeviceenumerator_p.h:101: warning: forward declaration of 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:79: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp: In member function 'void SerialDeviceEnumeratorPrivate::setEnabled(bool)':
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:96: error: invalid use of incomplete type 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\/serialdeviceenumerator_p.h:101: error: forward declaration of 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:97: error: no matching function for call to 'SerialDeviceEnumerator::connect(QWinEventNotifier*&, const char*, SerialDeviceEnumerator* const&, const char*)'
..\..\Desktop\Qt\4.7.4\mingw\include/QtCore/qobject.h:198: note: candidates are: static bool QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType)
..\..\Desktop\Qt\4.7.4\mingw\include/QtCore/qobject.h:313: note: bool QObject::connect(const QObject*, const char*, const char*, Qt::ConnectionType) const
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:103: error: invalid use of incomplete type 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\/serialdeviceenumerator_p.h:101: error: forward declaration of 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp: In member function 'bool SerialDeviceEnumeratorPrivate::isEnabled() const':
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:111: error: invalid use of incomplete type 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\/serialdeviceenumerator_p.h:101: error: forward declaration of 'struct QWinEventNotifier'
mingw32-make[1]: Leaving directory `C:/QtSDK/Qt project(1)/comport'
mingw32-make[1]: *** [debug/serialdeviceenumerator_p_win.o] Error 1
mingw32-make: *** [debug] Error 2
Процесс «C:\QtSDK\mingw\bin\mingw32-make.exe» завершился с кодом 2.
Возникла ошибка при сборке проекта comport (цель: Desktop)
Во время выполнения сборки на этапе «Сборка»
0
а вот и собственно мой проект webfile.ru/5652496
0
заметил еще фишку: ваш проект тоже перестает собираться, после того как я нажимаю пересобрать все
0
Короче, если вдруг тут есть такие же больные, для вас решение проблемы:
Оказывается в новой версии qtsdk отсутствуют два файла qwineventnotifier_p.h и qwineventnotifier_p.cpp

их можно вытянуть из исходников qt.gitorious.org/qt/qt/trees/4.7/src/corelib/kernel

и положить вот сюда \QtSDK\Desktop\Qt\4.7.4\mingw\include\QtCore\private\

после этого все работает (пока что :))
0
Уху, всё верно :)
В приложенном проекте просто qserialdevice уже откомпилирован, поэтому при простой сборке, компилятор Qt его пропускает.
qwineventnotifier_p.cpp для сборки проекта ненужен, нужен только заголовочник .h
0
Привет.

Использую Prolific USB-to-Serial Comm Port и библиотеку qserialdevice. Проблема в том, что после создания виртуального порта, пока я любым терминалом не открою/закрою нужный COM, данные не передаются, хотя порт открывается нормально. После этого, моя программа работает как надо, могу отправлять и принимать данные.

Подскажите, в чём может быть проблема?
0
Та-же фигня, правда FT232RL и qextserialport. Хотел переползать на qserialdevice, но значит дело не в этом. Буду снифать обмен и смотреть, что не так.

Прозреваю, что почему-то не выставляются настройки порта, т.к. на устройстве мигает индикатор RX.
0
Баг убит, докладываю.

Вопреки документации выставляй настройки порта после его открытия!

Вот так (чуть позже весь проект — универсальный кроссплатформенный бутлоадер — выложу):

this->port.setPortName(this->portname.portName); //Название порта

//Открываем порт
this->port.open(QIODevice::ReadWrite);
this->port_in_use = true;

this->port.setBaudRate(this->portsettings.BaudRate); //Параметры порта
this->port.setDataBits(this->portsettings.DataBits);
this->port.setFlowControl(this->portsettings.FlowControl);
this->port.setParity(this->portsettings.Parity);
this->port.setStopBits(this->portsettings.StopBits);
this->port.setTimeout(this->portsettings.Timeout_Millisec);
0
И ещё вопрос — нет таких же простых примеров для QMobility. Т.е. для работы с Bluetooth, WiFi, GPS? Официальные примеры для меня слишком сложные. Спасибо.
0
unix:include(../qserialdevice/src/unix/ttylocker.pri)
include(../qserialdevice/src/qserialdeviceenumerator/qserialdeviceenumerator.pri)
include(../qserialdevice/src/qserialdevice/qserialdevice.pri) win32 { LIBS += -lsetupapi -luuid -ladvapi32 } unix:!macx { LIBS += -ludev }

Для винды все то же самое?
0
Пробовал со своим примером, не компилится. Вываливает дохрена ошибок.

Закинул твой пример — запускается. Но дай ка думаю удалю всякие компиленые обьектники. Удалил все из папки Debug запускаю и опа:

06:00:55: Выполняется сборка проекта Focade...
06:00:55: Настройки не изменились, этап qmake пропускается.
06:00:55: Запускается: «D:\QtSDK\mingw\bin\mingw32-make.exe» 
D:/QtSDK/mingw/bin/mingw32-make.exe -f Makefile.Debug
mingw32-make.exe[1]: Entering directory `D:/Coding/Qt/Focade'
g++ -c -g -frtti -fexceptions -mthreads -Wall -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NEEDS_QMAIN -I"..\..\..\QtSDK\Desktop\Qt\4.8.0\mingw\include\QtCore" -I"..\..\..\QtSDK\Desktop\Qt\4.8.0\mingw\include\QtGui" -I"..\..\..\QtSDK\Desktop\Qt\4.8.0\mingw\include" -I"..\qserialdevice\src\qserialdeviceenumerator" -I"..\qserialdevice\src\qserialdevice" -I"..\..\..\QtSDK\Desktop\Qt\4.8.0\mingw\include\ActiveQt" -I"debug" -I"." -I"..\..\..\QtSDK\Desktop\Qt\4.8.0\mingw\mkspecs\win32-g++" -o debug\serialdeviceenumerator_p_win.o ..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp
In file included from ..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:27:
..\..\..\QtSDK\Desktop\Qt\4.8.0\mingw\include/QtCore/private/qwineventnotifier_p.h:1:61: error: ../../../src/corelib/kernel/qwineventnotifier_p.h: No such file or directory
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp: In destructor 'virtual SerialDeviceEnumeratorPrivate::~SerialDeviceEnumeratorPrivate()':
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:78: error: invalid use of incomplete type 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\/serialdeviceenumerator_p.h:101: error: forward declaration of 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:79: warning: possible problem detected in invocation of delete operator:
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:79: warning: invalid use of incomplete type 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\/serialdeviceenumerator_p.h:101: warning: forward declaration of 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:79: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp: In member function 'void SerialDeviceEnumeratorPrivate::setEnabled(bool)':
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:96: error: invalid use of incomplete type 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\/serialdeviceenumerator_p.h:101: error: forward declaration of 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:97: error: no matching function for call to 'SerialDeviceEnumerator::connect(QWinEventNotifier*&, const char*, SerialDeviceEnumerator* const&, const char*)'
..\..\..\QtSDK\Desktop\Qt\4.8.0\mingw\include/QtCore/qobject.h:204: note: candidates are: static bool QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType)
..\..\..\QtSDK\Desktop\Qt\4.8.0\mingw\include/QtCore/qobject.h:217: note:                 static bool QObject::connect(const QObject*, const QMetaMethod&, const QObject*, const QMetaMethod&, Qt::ConnectionType)
..\..\..\QtSDK\Desktop\Qt\4.8.0\mingw\include/QtCore/qobject.h:337: note:                 bool QObject::connect(const QObject*, const char*, const char*, Qt::ConnectionType) const
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:103: error: invalid use of incomplete type 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\/serialdeviceenumerator_p.h:101: error: forward declaration of 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp: In member function 'bool SerialDeviceEnumeratorPrivate::isEnabled() const':
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:111: error: invalid use of incomplete type 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\/serialdeviceenumerator_p.h:101: error: forward declaration of 'struct QWinEventNotifier'
mingw32-make.exe[1]: Leaving directory `D:/Coding/Qt/Focade'
mingw32-make.exe[1]: *** [debug/serialdeviceenumerator_p_win.o] Error 1
mingw32-make.exe: *** [debug] Error 2
06:00:55: Процесс «D:\QtSDK\mingw\bin\mingw32-make.exe» завершился с кодом 2.
Возникла ошибка при сборке проекта Focade (цель: Desktop)
Во время выполнения сборки на этапе «Сборка»


Что за нафиг, че ей не хватает?
0
Не может найти qwineventnotifier_p.h
0
Хм. В либе его нет. И в примере его тоже не было. Т.е. раньше видимо не требовался. Т.е. внезапно стало надо?
0
Вроде выше уже писали как раз об этом.
0
Очень полезная статья! Спасибо! Только вот с таким парсингом данных
uint adc_value = bytes.split(' ').at(1).split('\r').at(0).toUInt();
в отладочном режиме у меня прога вылетает… ошибку с рантаймом выдаёт… а в режими релиза всё ОК… интересно почему? =)
0
Разобрался… вылетает, разумеется, когда не то что хотелось бы приходит=) Сделал валидацию с помощью регулярных выражений… может и парсинг с помощью их делать.
0
Вчера начал осваивать STM32, роюсь по Сообществу, вот и наткнулся на эту статью. А здесь, оказывается, инфо, которая мне очень нужна. Почему пишу об STM32? Да потому что позавчера я бы после прочтения первой строки статьи закрыл бы и не узнал много полезного :)
За статью большое спасибо! Очень доходчиво и живо написано. Не верю, что первая :)
Ну, подробности (способ передачи данных, парсинг) я не обсуждаю, здесь можно все делать на свой вкус. Для меня ценно было увидеть, как живой человек собирает проект на компе, в котором тыканье мышкой взрывает МК. Класс!
0
Мля, а плюсики уже поздно ставить… А как можно налить пива автору старой статьи?
0
В профиле. Но только один раз.
0
Возникла проблема. Делал все как было описано в статье. Но при сборке проекта возникают ошибки:
In file included from main.cpp:2:
abstractserial.h: No such file or directory
In file included from main.cpp:2:
expected unqualified-id before 'private'

Windows Vista, Qt Creator 2.4.1
В чем может быть проблема?
0
Очень мощный инструмент для парсинга принятых данных — регулярные выражения. в Qt это QRegExp. позволяет выполнять поиск и замену и многое другое выражений по заданному шаблону.
пример поиск в тексте дефайнов вида #define name1 1,255,95 и вывод имени и значения:

QString parseQssFile(QString str)
{
    QString name,value;
    QRegExp rx("(?:#define\\s+)([\\w-]+)(?:\\s+)(\\d\\d?\\d?,\\d\\d?\\d?,\\d\\d?\\d?)(?:\\s*)");
    int pos = 0;
    while ( (pos = rx.indexIn(str, pos)) != -1 )
    {
        name = rx.cap(1);
        value = rx.cap(2);
       
    }

    return name + value  ;
}
0
Регэкспы — круто, но медленно и нечитаемо. При возможности от них лучше воздержаться.
0
нечитаемо — это да)) а вот медленно ли? думаю скорости хватит чтоб обработать уарт и может даже лоуспид усб
0
Медленнее альтернатив, скажем так. Так что по возможности стоит применить другие средства. Для парсинга сложных файлов, вроде исходников, например — стоит глянуть в сторону yacc/bison.
0
Пролистал по диагонали.
Все бы хорошо, но вот отсутствие более-менее стандартизированного протокола обмена — большой жирный минус.
Что я имею в виду?
А очень простую вещь. Допустим, я первым делом после SystenInit() и HardwareInit() в программе мк имплементирую стек Modbus (бесплатный freemodbus). Всё! Я могу свободно обмениваться с помощью готовых и стандартизированных средств. Библиотек, тулкитов, ОРС-серверов итд. Вместо того, чтобы тратить время и силы на разработку разнообразных велосипедиков собственной конструкции. Также, не возникнет проблем при передаче изделия третьим лицам. Достаточно приложить карту регистров modbus и основные настройки.
Это все можете воспринимать как старческое брюзжание, но поверьте, оно не на пустом месте, а исходя из конкретного опыта и конкретных граблей.
0
но поверьте, оно не на пустом месте, а исходя из конкретного опыта и конкретных граблей.
Но оно и применимо только для конкретного опыта. Впрочем, где подходит — вариант хороший.
0
Я говорю не о конкретном решении, а о применении стандартных протоколов. Необязательно modbus, можно SLIP, Wake, что угодно. Но только не самодельные костыли.
Описанный вариант с выводом через printf годится разве что для автологгирования, то есть устройство просто валит в порт данные в виде таблицы csv, а прием можно осуществлять любым стандартным терминалом прямо в файл.
Но область применения такого решения очень узкая, в основном черновая отладка на этапе прототипирования (когда ещё сам не знаешь, что должно получиться). Хотя сейчас я применяю для того же самого связку modbus-OPC-MasterSCADA. Ну честно, лень мне возиться с рисованием графиков и сохранением данных в файл, когда это все можно сконфигурировать за полчаса.
0
Ну, стандартные протоколы тоже не всегда применимы.
0
Привет всем, помогите пожалуйста откомпилировать проект кутэ для линукса, у меня пишет что нету фаила libudev.h, я не знаю где его наити (
0
не знаю где его наити
В зависимости от религии, либо в йандексе, либо в гугле :)
Вот кое-что
0
Если не знаешь что такое кутэ зачем писать)))
Я просто всю жизнь писал на си шарп, а тут появилась нужда писать под линукс и кутэ а я про то и про то ничего не знаю, нашел этот фаил libudev.h но теперь та же фигня не компилирует, может автор поможет (
0
MrYuran вам дал правильную ссылку. Вам нужно установить пакет libudev-dev. libudev.h (и многое другое входит в этот пакет). Что именно вы компилируете – сам Qt?..
0
при попытке компилирования пустого проекта выдаются следующие ошибки:

13:53:27: Выполняются этапы для проекта timeslice...
13:53:27: Настройки не изменились, этап qmake пропускается.
13:53:27: Запускается: «/usr/bin/make» -w
make: Entering directory `/home/dima/timeslice-build-Desktop-______'
/usr/bin/qmake -spec /usr/share/qt/mkspecs/linux-g++ -o Makefile ../timeslice/timeslice.pro
make: Leaving directory `/home/dima/timeslice-build-Desktop-______'
make: Entering directory `/home/dima/timeslice-build-Desktop-______'
g++ -Wl,-O1,--sort-common,--as-needed,-z,relro -Wl,-O1 -o timeslice main.o mainwindow.o ttylocker.o serialdeviceenumerator.o serialdeviceenumerator_p_unix.o abstractserial.o abstractserialengine.o nativeserialengine.o abstractserialnotifier.o nativeserialengine_unix.o nativeserialnotifier_unix.o moc_mainwindow.o    -L/usr/lib -lQtGui -lQtCore -lpthread 
serialdeviceenumerator_p_unix.o: In function `SerialDeviceEnumeratorPrivate::~SerialDeviceEnumeratorPrivate()':
serialdeviceenumerator_p_unix.cpp:(.text+0x838): undefined reference to `udev_monitor_unref'
serialdeviceenumerator_p_unix.cpp:(.text+0x847): undefined reference to `udev_unref'
serialdeviceenumerator_p_unix.o: In function `SerialDeviceEnumeratorPrivate::updateInfo() const':
serialdeviceenumerator_p_unix.cpp:(.text+0xbff): undefined reference to `udev_enumerate_new'
serialdeviceenumerator_p_unix.cpp:(.text+0xc1b): undefined reference to `udev_enumerate_add_match_subsystem'
serialdeviceenumerator_p_unix.cpp:(.text+0xc27): undefined reference to `udev_enumerate_scan_devices'
serialdeviceenumerator_p_unix.cpp:(.text+0xc33): undefined reference to `udev_enumerate_get_list_entry'
serialdeviceenumerator_p_unix.cpp:(.text+0xc4b): undefined reference to `udev_list_entry_get_name'
serialdeviceenumerator_p_unix.cpp:(.text+0xc61): undefined reference to `udev_device_new_from_syspath'
serialdeviceenumerator_p_unix.cpp:(.text+0xd9f): undefined reference to `udev_device_get_devnode'
serialdeviceenumerator_p_unix.cpp:(.text+0x13ec): undefined reference to `udev_device_get_property_value'
serialdeviceenumerator_p_unix.cpp:(.text+0x144b): undefined reference to `udev_device_get_property_value'
serialdeviceenumerator_p_unix.cpp:(.text+0x14aa): undefined reference to `udev_device_get_property_value'
serialdeviceenumerator_p_unix.cpp:(.text+0x1543): undefined reference to `udev_device_get_property_value'
serialdeviceenumerator_p_unix.cpp:(.text+0x1659): undefined reference to `udev_device_get_property_value'
serialdeviceenumerator_p_unix.o:serialdeviceenumerator_p_unix.cpp:(.text+0x16fd): more undefined references to `udev_device_get_property_value' follow
serialdeviceenumerator_p_unix.o: In function `SerialDeviceEnumeratorPrivate::updateInfo() const':
serialdeviceenumerator_p_unix.cpp:(.text+0x17ee): undefined reference to `udev_device_get_syspath'
serialdeviceenumerator_p_unix.cpp:(.text+0x184d): undefined reference to `udev_device_get_property_value'
serialdeviceenumerator_p_unix.cpp:(.text+0x18ac): undefined reference to `udev_device_get_property_value'
serialdeviceenumerator_p_unix.cpp:(.text+0x190b): undefined reference to `udev_device_get_property_value'
serialdeviceenumerator_p_unix.cpp:(.text+0x1b0f): undefined reference to `udev_device_unref'
serialdeviceenumerator_p_unix.cpp:(.text+0x1c4d): undefined reference to `udev_list_entry_get_next'
serialdeviceenumerator_p_unix.cpp:(.text+0x1c65): undefined reference to `udev_enumerate_unref'
serialdeviceenumerator_p_unix.o: In function `SerialDeviceEnumeratorPrivate::_q_processWatcher()':
serialdeviceenumerator_p_unix.cpp:(.text+0x2869): undefined reference to `udev_monitor_receive_device'
serialdeviceenumerator_p_unix.cpp:(.text+0x2875): undefined reference to `udev_device_unref'
serialdeviceenumerator_p_unix.o: In function `SerialDeviceEnumeratorPrivate::SerialDeviceEnumeratorPrivate()':
serialdeviceenumerator_p_unix.cpp:(.text+0x2ec4): undefined reference to `udev_new'
serialdeviceenumerator_p_unix.cpp:(.text+0x2edf): undefined reference to `udev_monitor_new_from_netlink'
serialdeviceenumerator_p_unix.cpp:(.text+0x2f02): undefined reference to `udev_monitor_filter_add_match_subsystem_devtype'
serialdeviceenumerator_p_unix.cpp:(.text+0x2f0d): undefined reference to `udev_monitor_enable_receiving'
serialdeviceenumerator_p_unix.cpp:(.text+0x2f18): undefined reference to `udev_monitor_get_fd'
collect2: error: ld returned 1 exit status
make: *** [timeslice] Error 1
make: Leaving directory `/home/dima/timeslice-build-Desktop-______'
13:53:28: Процесс «/usr/bin/make» завершился с кодом 2.
Возникла ошибка при сборке/установке проекта timeslice (цель: Desktop)
Во время выполнения этапа «Сборка»
0
  • avatar
  • dmp
  • 03 декабря 2012, 15:48
Судя по виду ругани — нужно добавить библиотечку с udev_* в линковку.
0
Собираю проект под ArchLinux
К USB порту подключена FT232R
Вот в этом месте не открывается порт:
serialport->setDeviceName(ui->cbSerialPort->currentText()); // Порт, который открываем - берём из поля lePort
        if (serialport->open(AbstractSerial::ReadWrite)) { //

Порт определяется в системе как /dev/ttyUSB0
Как определить причину нежелания открывать порт? Может есть какое-то подобие GetLastError?
0
  • avatar
  • dmp
  • 04 декабря 2012, 00:12
Доброго дня прошу помощи! Доброго дня, я Валерий, мы уже пересекались на просторах сети по 8 разрядкам Atmega и Си. время бежит по прежнему топчу Ваши ресурсы, столкнулся с проблемой на we.easyelectronics.ru/ закрылась регистрация. пытаюсь разобраться по теме «Приём-отправка данных между МК и программой на ПК (RS-232)», в Qt Creator SDK не проходит этап сборки все ошибки в serialdeviceenumerator_p_win.cpp. ну в общем прошу помощи. Здесь ссылка на материалы проекта: drive.google.com/folderview?id=0B0kcZZdbdD9OMzVfVXlUV0pxY28&usp=sharing Заранее благодарен, с уважением
0
Лог ошибок в студию.
0
Спасибо за быстрый ответ скрин лога ошибок лежит по ссылке из моего предыдушего поста: drive.google.com/folderview?id=0B0kcZZdbdD9OMzVfVXlUV0pxY28&usp=sharing, если нужен именно лог гляну как его в QT делать и перешлю. :))
0
Как просили лог ошибок (консоль сборки):
18:51:59: Выполняется сборка проекта focade…
18:51:59: Настройки не изменились, этап qmake пропускается.
18:51:59: Запускается: «C:\QtSDK\mingw\bin\mingw32-make.exe»
C:/QtSDK/mingw/bin/mingw32-make.exe -f Makefile.Debug
mingw32-make.exe[1]: Entering directory `C:/QT_work/QT_ff2/focade'
g++ -c -g -frtti -fexceptions -mthreads -Wall -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_GUI_LIB -DQT_CORE_LIB -DQT_HAVE_MMX -DQT_HAVE_3DNOW -DQT_HAVE_SSE -DQT_HAVE_MMXEXT -DQT_HAVE_SSE2 -DQT_THREAD_SUPPORT -DQT_NEEDS_QMAIN -I"..\..\..\QtSDK\Desktop\Qt\4.8.1\mingw\include\QtCore" -I"..\..\..\QtSDK\Desktop\Qt\4.8.1\mingw\include\QtGui" -I"..\..\..\QtSDK\Desktop\Qt\4.8.1\mingw\include" -I"..\qserialdevice\src\qserialdeviceenumerator" -I"..\qserialdevice\src\qserialdevice" -I"..\..\..\QtSDK\Desktop\Qt\4.8.1\mingw\include\ActiveQt" -I«debug» -I"." -I"..\..\..\QtSDK\Desktop\Qt\4.8.1\mingw\mkspecs\win32-g++" -o debug\serialdeviceenumerator_p_win.o ..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:27:48: error: QtCore/private/qwineventnotifier_p.h: No such file or directory
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp: In destructor 'virtual SerialDeviceEnumeratorPrivate::~SerialDeviceEnumeratorPrivate()':
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:78: error: invalid use of incomplete type 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\/serialdeviceenumerator_p.h:101: error: forward declaration of 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:79: warning: possible problem detected in invocation of delete operator:
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:79: warning: invalid use of incomplete type 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\/serialdeviceenumerator_p.h:101: warning: forward declaration of 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:79: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp: In member function 'void SerialDeviceEnumeratorPrivate::setEnabled(bool)':
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:96: error: invalid use of incomplete type 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\/serialdeviceenumerator_p.h:101: error: forward declaration of 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:97: error: no matching function for call to 'SerialDeviceEnumerator::connect(QWinEventNotifier*&, const char*, SerialDeviceEnumerator* const&, const char*)'
..\..\..\QtSDK\Desktop\Qt\4.8.1\mingw\include/QtCore/qobject.h:204: note: candidates are: static bool QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType)
..\..\..\QtSDK\Desktop\Qt\4.8.1\mingw\include/QtCore/qobject.h:217: note: static bool QObject::connect(const QObject*, const QMetaMethod&, const QObject*, const QMetaMethod&, Qt::ConnectionType)
..\..\..\QtSDK\Desktop\Qt\4.8.1\mingw\include/QtCore/qobject.h:337: note: bool QObject::connect(const QObject*, const char*, const char*, Qt::ConnectionType) const
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:103: error: invalid use of incomplete type 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\/serialdeviceenumerator_p.h:101: error: forward declaration of 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp: In member function 'bool SerialDeviceEnumeratorPrivate::isEnabled() const':
..\qserialdevice\src\qserialdeviceenumerator\serialdeviceenumerator_p_win.cpp:111: error: invalid use of incomplete type 'struct QWinEventNotifier'
..\qserialdevice\src\qserialdeviceenumerator\/serialdeviceenumerator_p.h:101: error: forward declaration of 'struct QWinEventNotifier'
mingw32-make.exe[1]: Leaving directory `C:/QT_work/QT_ff2/focade'
mingw32-make.exe[1]: *** [debug/serialdeviceenumerator_p_win.o] Error 1
mingw32-make.exe: *** [debug] Error 2
18:52:10: Процесс «C:\QtSDK\mingw\bin\mingw32-make.exe» завершился с кодом 2.
Возникла ошибка при сборке проекта focade (цель: Desktop)
Во время выполнения сборки на этапе «Сборка»

ссылка в файле: https://docs.google.com/file/d/0B0kcZZdbdD9OS0V2RXo0MlFobDA/edit?usp=sharing
С уважением Валерий :))
0
Огромное спасибо автору за статью!
Благодаря статье узнал о существовании QT, и смог написать первое в жизни приложение для ПК.
Для новичков таких как хочу рассказать как я устранил «баги».
Не зная как «стартовать» с нуля.
Скачал c qt-project.org/downloads Qt 5.1.1 for Windows 32-bit (MinGW 4.8, OpenGL, 667мб).
Установил. Создал проект в QT Creator, перенес пример из данной статьи в него, начал запускать, посыпались ошибки, которые приводят в комментариях.
Вобщем в итоге почему то программа не принимала данные от устройства.
Потом нашел это:
habrahabr.ru/post/191902/
Cобрал проект, и все заработало с первого раза! Ура!!!)))
Я так понял тут используется какая то другая библиотека для работы с serial, которая есть в Qt и не требует чего то докачивания, и каких то еще файлов.
Моя программа (проект называется Control) передает данные, принимает ответ от устройства и выводит его на экран, настройка порта 38400.
Привожу исходный код:
Файл Control.pro
#-------------------------------------------------
#
# Project created by QtCreator 2013-08-31T09:10:08
#
#-------------------------------------------------

QT       += core gui serialport

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Control
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp

HEADERS  += mainwindow.h

FORMS    += mainwindow.ui


Файл mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QScrollBar>
#include <QDebug>
#include <QSerialPort>
#include <QSerialPortInfo>




namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

public slots:
    //void sendData();
   // void readData();
    void serialRecieve();
    
private slots:

    void on_openPort_clicked();


//    void on_plainTextEdit_textChanged();

    void on_comandSend_clicked();

private:
    Ui::MainWindow *ui;
    QSerialPort *serial;
    void initSerial(); // Инициализации посл. порта
    void deinitSerial(); // И деинициализация (закрытие) порта
};

#endif // MAINWINDOW_H

Файл mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->initSerial(); // Первоначальная инициализация

}

MainWindow::~MainWindow()
{
    this->deinitSerial(); // Закрытие порта
    delete ui;
}


void MainWindow::initSerial()
{

     // connect(port, SIGNAL(readyRead()), this, SLOT(readData()));
      //connect(ui->btnSend, SIGNAL(clicked()),this,SLOT(sendData()));

    serial = new QSerialPort(); // Новый экземпляр класса AbstractSerial
    connect(this->serial, SIGNAL(readyRead()), this, SLOT(serialRecieve())); // объявляем наше "прерывание" по получении данных
}

void MainWindow::deinitSerial()
{
    if (this->serial->isOpen()){
        this->serial->close();
    }
    delete serial;
}




void MainWindow::on_openPort_clicked()
{
    if (this->serial->isOpen()) {
           serial->close();
       }
    else
    {

                  serial->setPortName(ui->comNomber->text());

           if (serial->open(QIODevice::ReadWrite))
            {
                //Настройка порта
                serial->setBaudRate(38400); // Скорость выбираем из выпадающего списка cbBaud
                serial->setDataBits(QSerialPort::Data8);
                serial->setParity(QSerialPort::NoParity);
                serial->setStopBits(QSerialPort::OneStop);
                serial->setFlowControl(QSerialPort::NoFlowControl);

                //Вывод отладочных сообщений
                qDebug() << "Порт " << serial->portName()<< " открыт в режиме " << serial->openMode();
                qDebug() << "Baud rate:" << serial->baudRate();
                qDebug() << "Data bits:" << serial->dataBits();
                qDebug() << "Stop bits:" << serial->stopBits();
                qDebug() << "Parity:" << serial->parity();
                qDebug() << "Flow control:" << serial->flowControl();
                qDebug() << "Read buffer size:" << serial->readBufferSize();

                ui->openPort->setText("Close");




                    } else {
                        qDebug() << "Unable to open port, error code" << serial->error();
                    }

  }
}




void MainWindow::on_comandSend_clicked()
{
    serial->write(QByteArray().append(ui->command->text()));
    serial->waitForBytesWritten(100);
}


void MainWindow::serialRecieve()
{

    QByteArray data = serial->readAll();
      QString str=QString(data);

       ui->screen->insertPlainText(str);



}

В main.cpp нечего не менял.

В дизайне окна, следующие элементы «QPushButton» name=«openPort», «QPushButton» name=«comandSend»,«QLineEdit» name=«comNomber»,«QLineEdit» name=«command», окно вывода того что ответило устройтво -«QPlainTextEdit» name=«screen».
0
Помогите пожалуйста. Как можно из программы, которую я пишу для фирмы в Qt4.8 сделать так, чтобы она (программа)создавала модемное сетевое подключение в системе WIN XP,7, а потом его запускала т.е. делала коннект (имитировало нажатие кнопки «Вызов») и прерывало его когда необходимо (кнопка «Отмена»)? Можно посмотреть примеры такого приложения на Qt?
Возможно это делается не так, а по другому — подскажите пожалуйста.
P.S. Используется виртуальный COM порт на PС. Мне поставили задачу, добавить в мою программу что то наподобие примитивного коннект менеджера 3G модема, подключенного через USB виртуальный COM порт.
0
она (программа)создавала модемное сетевое подключение в системе WIN XP,7, а потом его запускала т.е. делала коннект (имитировало нажатие кнопки «Вызов») и прерывало его когда необходимо (кнопка «Отмена»)? 

Для управления модемными сетевыми подключениями (а так же VPN и прочим, что в Windows относиться к «Подключению к удаленной сети» отвечает RAS API.
ЕМНИП, готовой обертки вокруг этих функций в QT нет. Поэтому, скорее всего Вам придется пользоваться нативным Win32API интерфейсом.
0
Упс, забыл дать ссылку на описание  RAS API.
0
Поэтому я хочу вариант с созданием модемного соединения средствами WIN из непосредсвенно программы на Qt и управлять им — жать кнопку «Вызов» из самой проги Qt — Такое возможно?
0
Такое возможно?

Если я правильно понял (что Вы хотите настроить и запускать/обрывать модемное сетевое соединение ) – то да. Выше я сбросил описание API. Глянь пример RasDialDlg. По сути, нужно сделать аналогичное из QT. Только использовать RasDial(), т к. RasDialDlg() показывает стандартный диалог перед тем, как установить соединение.
0
В большинстве своих проектов для визуализации данных использую LabView. Давно задался найти компоненты для (С#, C, C+) которые строят такие же красивые графики как выше названный софт (ищу бесплатные компоненты, а нахожу пока только за деньги. Может плохо ищу?) Как будут найдены или в конце концов написан компонент отображающий графики обязательно напишу аналогичный софт. Для вывода текстовой информации меня полностью устраивает Terminal.
0
Я то же пользуюсь этой программой, но не нашел как сохранить настройки для COM порта, шрифта, режимов, а при каждом запуске приходится настраивать заново. Когда виснет обмен, приходится выходить из программы. Программа не умеет сканировать порты принудительно, а только после запуска. Еще она на имеет ввод редактирования строки символов перед выводом и работа с буфером обмена по клавишам Ctrl + C. Выводит посимвольно. Удобно было бы — быстрый набор по первым введенным символам.
Но в моем случае нужно сбацать спец. прогу + свои специализированные функции
0
Labview тяжелый вариант и бесплатность сомнительна. Ы LabWindows работали?
0
Не осилил.
0
Если для Qt — то QCustomPlot! сам использую и Вам советую=))
0
zedgraph.sourceforge.net/samples.html
не подходит?
0
  • avatar
  • x893
  • 31 августа 2014, 21:32
Спасибо тебе добрый человек. То что нужно. Значит я плохо искал. Сделаю ещё один шаг в сторону Open Source.
0
Вообще этого добра в том числе кнопок, стрелок, ледов и так далее для Qt в сети дофига, только воспользоваться гуглоскателем ;)
Могу поделиться моим способом поиска — набираете Qt LED Knobs Display и ищете Images — картинки, а потом по картинке переходите на сайт нужный вам.
0
Вдогонку — поройтесь там qt-apps.org/content/show.php/AnalogWidgets?content=87780
0
1) Кто-нибудь QtSerialport собирал в статик lib для 5 или 4 версии?
2) Подскажите проверенную рабочую инструкцию по сборке static Qt 4 и 5 пожалуйста.
0
Что действительно никто Qt не собирал для работы в статик?
0
Не так уж и много народу тут его используют… Я когда-то пытался… ничего внятного не получилось, сам кьют в Статик не хотел пересобираться… плюнул и таскаю дллки с программами в случае надобности, разницей практически никакой…
0
Если получится у меня собрать — расскажу здесь последовательность, заморочек по стат либе действительно много.
Есть еще идея как то скрыть упаковать длл-ки, а именно упаковать UPX-ом и распаковывать в память = виртуальный диск например или что аналогичное, но и тут хитрости нужны
0
кстаит кто то знает упаковщики в exe, чтобы ставился небольшой виртуальный диск в RAM и потом распаковывались ту да же?
0
Зачем этот изврат? Даже у обычных ехе-пакеров достаточно недостатков, чтобы не рекомендовать их применение.
0
Я ради интереса собирал Qt5.2 в статической версии, но инструкцию найти не могу. Но там никаких особых проблем не было. Ключики для конфигурации брал из файла windows-build-qt-static.ps1, который в этой инструкции.
0
Попробуйте sigrok.org/wiki/Libserialport в отличии от QtSerialport библиотека стабильная, работают скорости больше 115200. Обёртка с QThread и сигналами пишется за 15 минут.

Под static собирал c mxe.cc
0
Спасибо!
Но так как чайник я в этом пока еще, можно вас попросить пример рабочий проекта с Libserialport?
И вдогонку по поводу mxe — с какой стороны к нему подойти, пожалуйста дайте простенькую инструкцию как собирать
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.