реклама на сайте
подробности

 
 
> Рисование из потока
hadrov
сообщение Nov 11 2008, 14:18
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 11-11-08
Пользователь №: 41 540



Есть устройство, обменивающееся с компьютером по UART. Протокол вида: компьютер запросил - прибор померил и отдал результат. Для компьютера написана программа на Дельфи. Там в потоке принимается результат, и по факту приема выводится на экран в виде графика с помощью компонента TChart. Программа иногда зависает, иногда бывают аксес виалейшен.

Я хочу переписать программу на С, компилятор возьму MSVS C++.
Как следует организовывать работу с графикой и ком-портом? Мне видится, что нужно по событию от таймера проверять состояние флага приема информации, и тогда принимающий поток будет передавать точки графика тому, кто будет рисовать на форме...
Как я понял, программа часто зависала из-за того, что графика была "тяжелой", и пока что-то рисовалось в поток успевало придти несколько значений и данные терялись... Возможно, там дело обстояло несколько иначе, но мне кажется, что рисовать прямо из потока не очень хорошо.
Интересно было бы увидеть как поступают другие в подобных случаях.
И еще вопрос по графике. Есть ли что-то типа TChart в C++, уж очень там удобное масштабирование.
Читал, что рисование в DC медленное, но может кто-то пробовал его? По сути мне нужно несколько кривых выводить, правда шкала времени (ось Х) довольно длинная, около суток и более, т.е. ничего хитрого. Но с DC придется отказаться от удобностей типа масштабирования.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
hadrov
сообщение Nov 12 2008, 08:37
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 15
Регистрация: 11-11-08
Пользователь №: 41 540



Цитата
В Си ошибок только прибавится. Причем, на порядок.

Программу хотят еще и на КПК перенести для работы в полевых условиях. Это одна из причин перехода на Си.

Цитата
А всего делов - запихивать данные из УАРТа в кольцевой буфер. А рисующий поток из этого кольцевого буфера изымает по мере возможности. И никто не страдает.

Надо было мне сразу кусочек кода дать.
Вот как у меня сейчас сделано:

Поток приема из УАРТа.
Код
    data := buf;
    SetEvent(Event_new_data);

В переменной buf (dword) содержится данные из УАРТа, которые мы копируем в промежуточный буфер.


Поток обработки информации.
Код
    WaitForSingleObject(MainForm.Event_new_data, INFINITE);
    ResetEvent(MainForm.Event_new_k);

    Array_data[counter] := MainForm.data;
    inc(counter);
    SetLength(Array_data, counter + 1);

    // далее сама обработка

Ждем новых данных, запихиваем их в массив и выделяем новую ячейку под следующие данные.
Массив не кольцевой по причине того, что для данной версии программы нужно хранить всю накопленные данные в памяти. Но это тестовый вариант, поэтому для конечного варианта программы будет сделано что-то типа буфера FIFO.
Вообще, предположение о потере пакетов это лишь догадка... Просто когда я отключаю рисование графики, то программа работает стабильно.


Цитата
В Borland C++ Builder есть TChart.
Был бы Билдер для КПК - не знал бы я проблем.

Цитата
Еще вариант видел: в дополнительном потоке идет работа с com-портом, а приложению постится (WM_USER + x) сообщение с принятыми данными (при этом выделялась память, передавался указатель на буфер с данными; обработчик сообщения данные обрабатывал и память обязательно освобождал).
Попробую разобраться с сообщениями в Windows.

Цитата
Стандартный драйвер Windows умеет организовывать софтверные буферы большого объема на отправку\прием. Этого обычно хвататет чтобы ничего не терять.
Забыл вчера написать, что чаще всего виснет сама графика, а обработка данных происходит нормально. Рисование происходит простым добавлением новой точки, например, MainForm.Series1.AddY(high_border[i]). И зависнуть это дело может как на 10 точке добавление, так и на 10000.
Go to the top of the page
 
+Quote Post
XVR
сообщение Nov 12 2008, 11:31
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(hadrov @ Nov 12 2008, 11:37) *
Программу хотят еще и на КПК перенести для работы в полевых условиях. Это одна из причин перехода на Си.


Надо было мне сразу кусочек кода дать.
Вот как у меня сейчас сделано:

Поток приема из УАРТа.
Код
    data := buf;
    SetEvent(Event_new_data);

В переменной buf (dword) содержится данные из УАРТа, которые мы копируем в промежуточный буфер.


Поток обработки информации.
Код
    WaitForSingleObject(MainForm.Event_new_data, INFINITE);
    ResetEvent(MainForm.Event_new_k);

    Array_data[counter] := MainForm.data;
    inc(counter);
    SetLength(Array_data, counter + 1);

    // далее сама обработка

Ждем новых данных, запихиваем их в массив и выделяем новую ячейку под следующие данные.
Неправильно. Во первых необходим хотя бы небольшой буфер под принимаемый байт. Если поток обработки информации не успеет обработать байт перед тем, как будет готов следующий, то байт потеряется

Во вторых, ручной сброс event'а (ResetEvent) может привести к потере одного события - нужно пользовать event с автоматическим сбросом

В третих, если 'поток обработки информации' это действительно отдельный поток, и он напрямую добавляет точки в TChart, то это и является источником зависаний - с объектами VCL можно работать ТОЛЬКО из главного потока приложения

И в последних - занесение и чтение данных из буфера, разделяемого между 2мя потоками, должно быть синхронизированно (например, критической секцией)
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- hadrov   Рисование из потока   Nov 11 2008, 14:18
- - DpInRock   В Си ошибок только прибавится. Причем, на порядок....   Nov 11 2008, 15:14
- - SysRq   В Borland C++ Builder есть TChart. Еще вариант ви...   Nov 11 2008, 19:45
- - Demeny   Цитата(hadrov @ Nov 11 2008, 17:18) Как с...   Nov 12 2008, 10:04
- - SysRq   Может стоит перейти на .NET? Оно относительно один...   Nov 12 2008, 10:36
- - hadrov   С учетом того, что потребуется версия для КПК, то,...   Nov 12 2008, 10:46
|- - Kopa   Цитата(hadrov @ Nov 12 2008, 13:46) С уче...   Nov 12 2008, 12:13
- - hadrov   Цитатанеобходим хотя бы небольшой буфер под приним...   Nov 12 2008, 11:55
|- - XVR   Цитата(hadrov @ Nov 12 2008, 14:55) Вы им...   Nov 13 2008, 07:47
||- - CSB   ...   Nov 17 2008, 23:00
|- - defunct   Цитата(hadrov @ Nov 12 2008, 13:55) Вот г...   Dec 23 2008, 02:09
- - hadrov   С Си знаком лучше всего. И я не знаю как быстро ра...   Nov 12 2008, 13:30
- - Олег Хохлов   Цитата(hadrov @ Nov 11 2008, 16:18) Есть ...   Nov 12 2008, 18:44
- - hadrov   ЦитатаВоспользоваться synchronized процедурой Ага,...   Nov 17 2008, 23:14
|- - XVR   Цитата(hadrov @ Nov 18 2008, 02:14) Ага, ...   Nov 18 2008, 06:45
|- - AHTOXA   Цитата(hadrov @ Nov 18 2008, 04:14) Поток...   Nov 18 2008, 07:40
|- - XVR   Цитата(AHTOXA @ Nov 18 2008, 10:40) Не та...   Nov 18 2008, 09:25
|- - AHTOXA   Цитата(XVR @ Nov 18 2008, 14:25) Частые з...   Nov 18 2008, 09:46
- - hadrov   Цитата(AHTOXA @ Nov 18 2008, 13:46) Ну а ...   Nov 18 2008, 10:32
|- - AHTOXA   Цитата(hadrov @ Nov 18 2008, 15:32) Я сей...   Nov 18 2008, 11:03
- - hadrov   ЦитатаНет, так нельзя.Теперь ясно. Я не так понял ...   Nov 18 2008, 11:20


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th June 2025 - 05:50
Рейтинг@Mail.ru


Страница сгенерированна за 0.01393 секунд с 7
ELECTRONIX ©2004-2016