Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.94/18: Рейтинг темы: голосов - 18, средняя оценка - 4.94
2 / 2 / 2
Регистрация: 16.10.2011
Сообщений: 179
1

Приём данных компонентом TBComPort в отдельном потоке

18.08.2012, 14:06. Показов 3581. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день, возник следующий вопрос:

Имеется компонент для работы с COm портом, который принимает данные из UART по своему Event'у. Вопрос: как в отдельном потоке отслеживать event приёма данных компонента TBComPort и передавать полученные данные из отедльного потока в общий поток?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.08.2012, 14:06
Ответы с готовыми решениями:

Производительный приём данных в отдельном потоке
Как грамотно организовать приём данных от внешнего устройства? Внешнее устройство Cypress FX3...

Приём данных в цикле компонентом IdTCPServer
Всем доброго времени суток. Не могу решить проблему с передачей данных через Indy 10. На самом...

Отрисовка данных в отдельном потоке
Уважаемые гуру и простые хорошие ребята, подскажите как правильно реализовать отрисовку графики в...

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

19
Эксперт С++
8482 / 6149 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
18.08.2012, 15:28 2
Создавать компонент динамически в потоке.
0
10234 / 6612 / 498
Регистрация: 28.12.2010
Сообщений: 21,154
Записей в блоге: 1
18.08.2012, 16:41 3
Synchronize()
0
Эксперт С++
8482 / 6149 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
18.08.2012, 16:54 4
Synchronize() только для визуальных компонентов, в остальных случаях объектами синхронизации
0
10234 / 6612 / 498
Регистрация: 28.12.2010
Сообщений: 21,154
Записей в блоге: 1
18.08.2012, 17:24 5
...вообще при работе с компонентами.
0
Эксперт С++
8482 / 6149 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
18.08.2012, 17:25 6
Только с визуальными тобиш от TWinControl
0
10234 / 6612 / 498
Регистрация: 28.12.2010
Сообщений: 21,154
Записей в блоге: 1
18.08.2012, 17:35 7
согласен.
0
2 / 2 / 2
Регистрация: 16.10.2011
Сообщений: 179
18.08.2012, 19:00  [ТС] 8
Спасибо за ответы, а можете привести пример такой реализации на примере обработки нажатия кнопки ButtonClick?
0
Эксперт С++
8482 / 6149 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
18.08.2012, 19:39 9
Вообще то сильно много кода...

Пример есть в книге Архангельского 7-издании ищите там класс TThread

Что касается динамического создания- так это зависит от реализации программы в общем.

Добавлено через 36 минут
Что касается синхронизации Объекты синхронизации
1
2 / 2 / 2
Регистрация: 16.10.2011
Сообщений: 179
19.08.2012, 22:30  [ТС] 10
По поводу синхронизации визуальных компонентов: столкнулся с проблемой невозможности скомпилировать код при синхронизации для вывода строки в Label

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class NewThread : public TThread  //заголовочный файл
{
private:
protected:
    void __fastcall Execute();
    void __fastcall DisplayLabel();
public:
    __fastcall NewThread(bool CreateSuspended);
 
    bool start;
    int count;
};
 
// cpp файл
 
void __fastcall DisplayLabel()
{
  Form1->Label1->Caption=random(100);
}
//---------------------------------------------------------------------------
void __fastcall NewThread::Execute()
{
FreeOnTerminate=true;
while (!Terminated)
{
if (count==1)
 {Synchronize(&DisplayLabel);}
Sleep(1);
}
}
Компилятор пишет Unresolved external __fastcall NewThread:isplayLabel()
В чём тут проблема?
0
Эксперт С++
8482 / 6149 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
19.08.2012, 23:03 11
C++
1
__fastcall NewThread::DisplayLabel()
Ну так я тоже тут не вижу определение метода

Добавлено через 1 минуту
C++
1
2
3
4
void __fastcall NewThread::DisplayLabel() /* NewThread::   !!!! */
{
  Form1->Label1->Caption= random(100);
}
1
2 / 2 / 2
Регистрация: 16.10.2011
Сообщений: 179
20.08.2012, 10:33  [ТС] 12
Спасибо за помощь! В итоге я примерно всё таки создал что хотел, однако код всё таки не работает =)

Разместил на главной форме компонент, по событию приёма сообщения с ком порта выставил
NewThread->Resume();

А в коде потока след код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void __fastcall ComThread::RXProc() //функция для изменения перем.
    {
Form1->BComPort1->ReadStr(Form1->St,100); //читаем порт
if (Form1->St=='x') Form1->temp=100; //если приняли символ x переменной темп присв. 100
}
 
void __fastcall ComThread::Execute()
{
FreeOnTerminate=true;
while(!Terminated)
{
RXProc();
Sleep(1);
}
}
Однако то, что работало на главной форме, неработает в потоке, пишет "Ошибка чтения из ком порта"
В чём здесь может быть дело?
0
Эксперт С++
8482 / 6149 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
20.08.2012, 13:36 13
По огрызку кода ничего не скажешь...тем более компонент нестандартный...как делается прием в обычном коде?
Кстати компонент визуальный ( всмысле от TWinControl ) ?

Непонятно что делает RXProc()
0
2 / 2 / 2
Регистрация: 16.10.2011
Сообщений: 179
20.08.2012, 14:00  [ТС] 14
В обычном коде в общей форме приём данных осуществляется по событию BComPort1RxChar

C++
1
2
3
4
5
6
void __fastcall TForm1::BComPort1RxChar(TObject *Sender, int Count)
{
String St;
 Form1->BComPort1->ReadStr(St,100); //принимаем
Label1->Caption=St;  //выводим на экран
}
Компонент не визуальный, RXProc в данном случае присваивает переменной temp какое то значение при приёме определённого символа
0
Эксперт С++
8482 / 6149 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
20.08.2012, 14:45 15
Ну так в коде с потоком этот обработчик тоже должен быть определен...

Добавлено через 14 минут
Возможно стоит сделать что-то вроде этого.
C++
1
2
3
4
5
6
7
8
9
void __fastcall ComThread::Execute()
{
FreeOnTerminate=true;
while(!Terminated)
  {
   if( Received ) {  RXProc(); Received= false; }
   Sleep(1);
  }
}
C++
1
2
3
4
void __fastcall TForm1::BComPort1RxChar(TObject *Sender, int Count)
{
 Received= true;
}
0
Практикантроп
4840 / 2725 / 533
Регистрация: 23.09.2011
Сообщений: 5,795
20.08.2012, 15:26 16
Цитата Сообщение от mappy89 Посмотреть сообщение
приём данных осуществляется по событию BComPort1RxChar
Событие BComPort1RxChar возникает при приеме очередного байта данных; при этом Count указывает общее количество принятых байтов в буфере, размер которого в параметрах компонента. После выполнения операций чтения (Read(), ReadStr()) или очистки (ClearBuffer()) Count обнуляется.
Потоки..., синхронизация... - как-то вы себе все усложнили. Я, возможно, не прав, но, помнится, с этим компонентом у меня сразу все получилось; и ось не огрызалась, как было с некоторыми другими компонентами обмена по rs232.
0
2 / 2 / 2
Регистрация: 16.10.2011
Сообщений: 179
20.08.2012, 15:53  [ТС] 17
Читать данные в отдельном потоке изначально хотел потому, что рассчитывал на уменьшение потерьб данных. Работая с компонентом в общей форме некоторые данные иногда не принимались, однако и в отдельном потоке (по крайней мере с моей реализацией) ситуация та же - где то половина данных принимается от случая к случаю =(
0
Практикантроп
4840 / 2725 / 533
Регистрация: 23.09.2011
Сообщений: 5,795
20.08.2012, 16:01 18
Потерь данных вообще не должно быть, если скорость обмена выставлена верно (этим служба занимается). Вот только вы считываете из буфера после каждого пришедшего байта и Count не учитываете вообще. Я иногда поступаю так (для определения конца передачи) - по таймеру сравниваю значение счетчика с предыдущим сохраненным и если перестал изменяться, то считаю, что передача закончена и перехожу с чтению буфера. Если идет непрерывный поток, то считываю порциями, скажем по 500 б. Комп все равно быстрее обработает порцию, прежде чем "наполнится" новая.
1
2 / 2 / 2
Регистрация: 16.10.2011
Сообщений: 179
20.08.2012, 16:24  [ТС] 19
Nick42, приведите, пожалуйста, пример реализации

Спасибо
0
Практикантроп
4840 / 2725 / 533
Регистрация: 23.09.2011
Сообщений: 5,795
20.08.2012, 16:59 20
Цитата Сообщение от mappy89 Посмотреть сообщение
приведите, пожалуйста, пример реализации
Я же в личку давал ссылку на проект (как пример реализации)... . Сейчас под рукой нет простенького шаблона под этот компонент. А готовая программа чересчур запутанная; только усложнит все.
Могу сказать, что я обхожусь такими командами: ->Close(), ->Open(), ->SetDTR(0) ->SetRTS(0) (иногда), ->ClearBuffer(1,1), ->Read(), ->Write() и анализирую if(comm->Connected). Ну, еще ->BaudRate, если скорости меняются.
0
20.08.2012, 16:59
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.08.2012, 16:59
Помогаю со студенческими работами здесь

Отправка данных по таймеру в отдельном потоке
Добрый день, интересует такая вещь, нужно сделать передачу файла с данными каждые 5 секунд. При...

Принятие сетевых данных NetworkStream в отдельном потоке
Написал простенький сервак-приёмник данных и еще более простой клиент к нему, сервер запускается и...

Обновление данных на форме созданной в отдельном потоке
Есть поток который мониторит данные, если появились необходимые данные он создает и открывает форму...

Dispatcher.BeginInvoke: обновление данных в ListView в отдельном потоке
При нажатии на кнопку "Refresh" пытаюсь сделать так, чтобы информация для отображения в ListView,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru