Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.71/56: Рейтинг темы: голосов - 56, средняя оценка - 4.71
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712

И снова работа с COM портом

16.11.2016, 14:03. Показов 12376. Ответов 67
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую всех. Уже измучился и измаялся весь пытаясь написать функцию. Помогите, пожалуйста...

Описание задачи
Создается программа для работы с прибором. Соединение с прибором осуществляется посредством преобразователей, которые при подключении к компьютеру создают виртуальный COM порт. Преобразователь может подключаться к прибору посредством проводного (RS-485) или беспроводного (инфракрасный канал) соединения. Прибор всегда является ведущим, то есть информацию выдает только по запросу от компьютера (получил корректный запрос - выдал ответ). Целостность запросов и ответов определяется циклическим избыточным кодом в конце запроса или ответа.

Текущая реализация
На данный момент я создал класс для работы с прибором. Экземпляр этого класса будет создаваться и работать в отдельном потоке. В классе будут реализованы конкретные функции для работы с прибором (например - прочитать серийный номер прибора). Каждая из этих функций подготавливает соответствующий запрос прибору и вызывает внутреннюю функцию обмена данными SwapData. Указанная функция, по сути, выполняет основную работу класса: отправляет созданный запрос в COM порт и получает ответ из COM порта. Именно данную функцию я не могу написать. Начало функции SwapData выглядит примерно так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int SwapData()
{
 // COMHandle - хендл открытого COM порта
 // Data - вектор байт для запроса и ответа
 // eCOM... - константы ошибок обмена
 DWORD dw;
 
 /* Очистка буферов и очередей COM порта */
 if(!PurgeComm(COMHandle, 0x0F)) return eCOMPurge;                              // Не удается очистить буферы COM порта: возвращаю ошибку
 
 /* Отправка данных в COM порт */
 if(!WriteFile(COMHandle, &Data.front(), Data.size(), &dw, NULL) ||             // Не удается отправить данные в COM порт или
     dw != Data.size()) return eCOMWrite;                                       // отправлены не все данные: возвращаю ошибку
 
 /* Чтение данных из COM порта */
}
К приведенной части кода функции претензий нет: буферы очищаются, запрос отправляется (при этом функция WriteFile ждет пока не отправятся все данные, ибо синхронный режим). Проблема возникает с приемом ответа.

Описание проблемы
Прием ответа от прибора сопряжен с несколькими трудностями. Во первых, ответ необходимо принять максимально быстро. То есть, не должно быть простоев в работе функции SwapData. Во вторых, на один и тот же запрос прибор может ответить разным количеством байт (либо вообще не ответить). Это связано с тем, что прибор может получить некорректный запрос (например, ошибка при передаче). Тогда он, скорее всего, вообще не ответит. Так же в каком-то конкретном приборе может быть отключена какая-то функция и прибор на запрос, связанный с этой функцией, выдаст не ожидаемое количество байт, а другое, которое сигнализирует об ошибке. В связи со всем этим появилась попытка решения задачи приема данных.

Попытка реализации чтения данных
В нижеприведенном коде я реализовал алгоритм, когдаПривожу код, который отвечает за прием данных:
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
 // COMHandle - хендл открытого COM порта
 // COMSpeed - скорость COM порта в бит/с
 COMSTATE cs;
 DWORD dw;
 
 /* Цикл ожидания ответа от прибора */
 for(DWORD in = 0, vl = 0, st = GetTickCount();;)
  {
   /* Останавливаю программу на время приема одного байта */
   Sleep(10000 / COMSpeed);
 
   /*  В буфер COM порта поступили новые данные */
   if(ClearCommError(COMHandle, &dw, &cs) && !dw && cs.cbInQue > in)
    {
     in = cs.cbInQue; /* Сохраняю количество данных в буфере COM порта */
     vl = 0; /* Обнуляю количество "пустых циклов" (когда данные не поступили) */
     continue;
    }
 
   /* Прерываю цикл ожидания ответа от прибора если:
      - в буфере COM порта нет данных и время ожидания превысило 3 секунды;
      - в буфере COM порта есть данные и было более одного "пустого цикла" */
   if((!in && ((GetTickCount() - st) > 3000)) || (in && ++vl > 1)) break;
  }
 
 /* Выполняю чтение данных из буфера COM порта */
 if(!cs.cbInQue) return eNotData;
 Data.resize(cs.cbInQue);
 if(!ReadFile(COMHandle, &Data.front(), Data.size(), &dw, NULL) ||
     dw != Data.size())) return eCOMRead;
Данный код отлично работает на скорости 300 бит/с, но на скорости 9600 бит/с цикл приема завершается до приема всех данных.

Помогите советом как реализовать прием данных максимально быстро и полно.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.11.2016, 14:03
Ответы с готовыми решениями:

Работа с COM портом
по COM порту через Agilen подключается вольтметр с адресом 1. необходимо "прозвонить" все порты и автоматически сделать рабочим тот,...

работа с COM портом
здравствуйте всем,я в форумах в первие ,и просил бы не судить очень строго. помогите пожалуйста , хочу реализовать приложение работающую с...

Работа с COM-портом
Подскажите, какие компоненты нужны для работы с ком-портами? а именно (хотя бы для начала) отправка шестнадцатиричного кода на порт, к...

67
 Аватар для ITDeveloper
86 / 86 / 6
Регистрация: 14.01.2011
Сообщений: 265
17.11.2016, 13:19
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от d7d1cd Посмотреть сообщение
У прибора ModBus подобный протокол обмена
В таком случае прибор в своем сообщении всегда указывает количество байт данных.
Формат ответа для modbus(пример) - адрес:00 функция:02 кол-во байт данных:03 данные 01 02 03 контрольная сумма 05 06
1
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
17.11.2016, 13:28  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
наверняка в течение 200 мс устройство не может молчать
По протоколу обмена для скорости 9600 бод максимальное время ожидания ответа равно 150 мс, для скорости 300 бод - 1600 мс. Выходит, что устройство может молчать и 1,6 секунды...

Цитата Сообщение от vxg Посмотреть сообщение
тогда я бы на вашем месте настроил тайм-ауты и засчитывал конец передачи если ReadFile выходит по тайм-ауту (возвращает ноль)
Проблема в том, что для ReadFile надо указывать количество считываемых данных... Хотя можно указать количество ожидаемых данных. Подскажите, как настроить таймауты COM порта.

Добавлено через 1 минуту
Цитата Сообщение от ITDeveloper Посмотреть сообщение
В таком случае прибор в своем сообщении всегда указывает количество байт данных.
Нет. Не указывает. Количество данных указываю я, когда хочу записать их в прибор или прочитать их оттуда.
0
Модератор
 Аватар для vxg
3409 / 2181 / 354
Регистрация: 13.01.2012
Сообщений: 8,464
17.11.2016, 13:31
Цитата Сообщение от d7d1cd Посмотреть сообщение
Выходит, что устройство может молчать и 1,6 секунды
ну, можете высчитывать тайм-аут по заданной скорости и накидывать немножко
Цитата Сообщение от d7d1cd Посмотреть сообщение
надо указывать количество считываемых данных
можно указать либо количество ожидаемых данных либо просто иметь достаточно большой буфер
Цитата Сообщение от d7d1cd Посмотреть сообщение
Подскажите, как настроить таймауты COM порта.
тут https://www.cyberforum.ru/com-... ost9765891
0
 Аватар для ITDeveloper
86 / 86 / 6
Регистрация: 14.01.2011
Сообщений: 265
17.11.2016, 13:36
Цитата Сообщение от d7d1cd Посмотреть сообщение
Нет. Не указывает. Количество данных указываю я, когда хочу записать их в прибор или прочитать их оттуда
А по стандарту modbus в ответном сообщении это указывается. Но пусть даже в вашем случае он это не указывает. Раз вы указываете количество байт данных, то и ожидаете их столько же в ответном сообщении. То есть получаете сообщение, выбираете из него байты данных, общитываете их контрольную сумму и сравниваете с той, которая пришла от прибора. Совпало ОК, не совпало - все сообщение мусор. В чем проблема?
1
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
17.11.2016, 13:47  [ТС]
Цитата Сообщение от ITDeveloper Посмотреть сообщение
А по стандарту modbus в ответном сообщении это указывается.
У меня ModBus подобный протокол, то есть он не точно соответствует стандарту.

Цитата Сообщение от ITDeveloper Посмотреть сообщение
То есть получаете сообщение,
Именно в этом и загвоздка. Понятно, что можно отправить запрос, подождать секунду, считать все что пришло и обрабатывать. Но ответы приходят намного быстрее, чем за секунду.
Было уже выяснено, что ждать следующий байт надо не более 5 мс после приема последнего (для скорости 9600). Если в течении 5 мс байт не пришел, значит прибор больше ничего не пришлет. Как реализовать такое ожидание, а так же отправку и прием данных в рамках одной функции SwapData...
0
Модератор
 Аватар для vxg
3409 / 2181 / 354
Регистрация: 13.01.2012
Сообщений: 8,464
17.11.2016, 15:04
Лучший ответ Сообщение было отмечено d7d1cd как решение

Решение

d7d1cd, как было написано в той самой теме
C++
1
2
3
4
5
6
7
        COMMTIMEOUTS cto; 
        cto.ReadIntervalTimeout = 5;
        cto.ReadTotalTimeoutMultiplier = 0;
        cto.ReadTotalTimeoutConstant = 0;
        cto.WriteTotalTimeoutMultiplier = 0;
        cto.WriteTotalTimeoutConstant = 0;
        SetCommTimeouts(h, &cto);
Добавлено через 1 минуту
...после такой настройки функция ReadFile вернется как только будет пауза дольше чем 5 мс
1
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
17.11.2016, 16:31  [ТС]
vxg, почитал про структуру COMMTIMEOUTS. Отличное решение, скажу Вам. По крайней мере в теории. Но есть вопрос. После отправки запроса прибор не сразу начинает присылать байты ответа, а через время от 5 мс до 150 мс. То есть функция ReadFile должна ждать не менее 150 мс поступления хотя бы одного байта. Как мне настроить таймауты для этого?

Мое решение следующее. При чтении я указываю функции ReadFile гарантированно большое значение данных, больше которого прибор никогда не пришлет, например 200. Члену структуры ReadTotalTimeoutMultiplier задаю значение 1. Таким образом функция ReadFile будет ждать поступления первого байта 1*200=200 мс. Однако если поступит байт, то далее функция будет ждать следующего символа только 5 мс как указано в ReadIntervalTimeout. Все верно?
0
Модератор
 Аватар для vxg
3409 / 2181 / 354
Регистрация: 13.01.2012
Сообщений: 8,464
17.11.2016, 16:50
d7d1cd, я только ReadTotalTimeoutConstant пользовался для гарантированного ограничения по времени всего запроса, предлагаю вам попробовать без наворотов как показано (только с ReadIntervalTimeout) - почему то мне кажется что система интерпретирует это значение именно как интервал, а не как время ожидания у моря погоды - то есть возможно она дождется первого символа и только потом будет засекать интервал. пробовать надо

Добавлено через 10 минут
...если вдруг окажется что она выйдет через 5 мс после вызова (засчитает ожидание за интервал), то просто вызывать ее в цикле заданное предельное количество раз (например 150 / 5 = 30)
0
188 / 41 / 12
Регистрация: 22.02.2016
Сообщений: 149
17.11.2016, 20:01
Цитата Сообщение от d7d1cd Посмотреть сообщение
А уж если использовать сигналы при работе с портом, то нельзя ли использовать их и тут, чтобы процессор не крутил впустую этот цикл?
можно, но стоит ли? ждать вы все равно будете либо окончания приема данных, либо время без ответа. Насколько я понял оно не велико. С сигналами будет просто чуть больше кода. и если у вас прием данных будет выполнен не за один раз а за несколько, то Вам нужно будет постоянно сбрасывать сигнальное состояние и устанавливать при приеме новых данных.
Если решите на ивентах сделать, вот функции ResetEvent, SetEvent, WaitForSingleObject
1
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
17.11.2016, 20:51  [ТС]
vxg, докладываю об экспериментах с прибором. Прибор подключен через преобразователь интерфейсов RS485 - USB. Преобразователь при подключении к компьютеру через USB создает виртуальный COM порт.

Скорость 9600 бод
Сначала настроил таймауты порта по Вашему совету из этого поста. Отправил запрос прибору, на который он должен был ответить пакетом размером 11 байт (количество данных для чтения в функции ReadFile указал 200). Функция ReadFile прочитала только 4 байта. Пробовал несколько раз: читается от 3-х до 5-ти байт, не больше. Далее начал экспериментировать и выяснил, что при установке ReadIntervalTimeout = 15 читается каждый раз разное количество байт (от 3 до 11). При установке ReadIntervalTimeout = 16 стабильно читается 11 байт, то есть именно то количество, что и передает прибор.

Скорость 1200 бод
Далее изменил скорость обмена с прибором на 1200 бод. И, как это ни удивительно, но история повторилась. При ReadIntervalTimeout = 15 читаются не все данные, при ReadIntervalTimeout = 16 стабильно читается всё.

Скорость 300 бод
На скорости 300 бод ситуация стала несколько иной. При ReadIntervalTimeout = 16 и даже при ReadIntervalTimeout = 200 данные читались не все. Только при ReadIntervalTimeout = 1600 данные читались стабильно все.

Делаю выводы
Скорее всего прибор присылает данные согласно протоколу обмена, однако преобразователь интерфейсов и его драйвер COM порта "хулиганят" и передают данные от прибора в COM порт не синхронно с прибором. Именно по этой причине при установке ReadIntervalTimeout = 5 и даже ReadIntervalTimeout = 15 функция ReadFile читает не все данные. Точнее, она читает все, что есть в буфере COM порта, просто преобразователь еще не успел передать в буфер все те данные, что получил от прибора. Вывод: надо устанавливать значение ReadIntervalTimeout во первых в зависимости от скорости обмена и протокола обмена, а во вторых с запасом. Другой преобразователь интерфейсов может по-другому "хулиганить" и еще не известно в какую сторону. Мой преобразователь, по видимому, имеет задержку примерно в 11 мс. Думаю, что запас для других преобразователей в 20 мс и плюс длительность ожидания по протоколу обмена будет достаточна.

P. S. Настройка ReadTotalTimeoutConstant
Так же был произведен эксперимент, когда в прибор заведомо отправляется некорректный запрос. Если значение ReadTotalTimeoutConstant = 0, то так как прибор вообще не отвечает, функция ReadFile глухо зависает. При установке ReadTotalTimeoutConstant = 3000 функция ReadFile, как и предполагалось, возвращала управление через 3 секунды. При этом число прочитанных байт было равно 0, что и логично.
0
 Аватар для ITDeveloper
86 / 86 / 6
Регистрация: 14.01.2011
Сообщений: 265
18.11.2016, 06:02
Цитата Сообщение от d7d1cd Посмотреть сообщение
однако преобразователь интерфейсов и его драйвер COM порта "хулиганят"
Это не удивительно! Все эти устройства "посредники" могут вносить дополнительные задержки и ошибки. Да и программу вы пишете под Windows. А это не операционная система реального времени. Она тоже может вносить свои задержки (и порой очень значительные). Поэтому, как я и писал, лучше все таки использовать ассинхронный режим! Нашел еще информацию про таймауты! Высылаю во вложении!
1
Модератор
 Аватар для vxg
3409 / 2181 / 354
Регистрация: 13.01.2012
Сообщений: 8,464
18.11.2016, 09:52
d7d1cd, почему-то мне кажется что настройки порта должны восприниматься преобразователем и в данном случае проблема может быть в том что устройство реально так отвечает. истину поможет установить либо честный COM-порт либо если с ним все будет так же - осциллограф
0
45 / 44 / 1
Регистрация: 11.07.2012
Сообщений: 1,024
18.11.2016, 11:56
Разрешите поинтересоваться, а почему вы считываете данные из сом порта побайтно? Можно же использовать буфер FIFO в регистрах UART СОМ порта, тогда данные будут считываться пачками байтов, в зависимости от того какая микросхема UART установлена на вашем железе, я правда разбираюсь с СОМ портом не под виндой, а под досом, но компьютерное железо одно и тоже и не зависит от того, какая именно на него установлена операционная система. Может быть при настройке передачи данных через СОМ не побайтно, а пачками через FIFO у вас будет меньше проблем для чтения данных?
0
Модератор
 Аватар для vxg
3409 / 2181 / 354
Регистрация: 13.01.2012
Сообщений: 8,464
18.11.2016, 12:00
седьмой, я не думаю что здесь речь о чтении по байтам если только ТС не зашел в свойства порта и не начал там терзать галочками и ползунками настройки буфера FIFO о которых как я понял вы говорите
1
 Аватар для ITDeveloper
86 / 86 / 6
Регистрация: 14.01.2011
Сообщений: 265
18.11.2016, 12:13
Цитата Сообщение от d7d1cd Посмотреть сообщение
C++
1
2
3
4
/* Выполняю чтение данных из буфера COM порта */ 
if(!cs.cbInQue) return eNotData; 
Data.resize(cs.cbInQue);
 if(!ReadFile(COMHandle, &Data.front(), Data.size(), &dw, NULL)
Чтение пакчки байт
1
45 / 44 / 1
Регистрация: 11.07.2012
Сообщений: 1,024
18.11.2016, 18:53
А нельзя разве посмотреть какие ошибки появляются во время чтения данных по СОМ порту, если вы говорите что настройки стандартные и данные передаются через FIFO буфер UART сом порта, то в современных компьютерах пачки данных должны передаваться сразу по 512 байт . И если данных в компьютер приходит меньше, чем поступило на входе, то в регистре LSR может быть код ошибки ( данные в компьютер считываются медленнее, чем поступают на входе и тогда часть данных затирается 1й бит регистра LSR; 2й бит этого регистра - ошибка паритета, 3й бит ошибка кадра, 4й- во время приема был обрыв линии и тд. ) Под виндой нет возможности проверки ошибок по регистру LSR (база+5) UART? Или в коде ошибки проверяются и их нет?
0
Модератор
 Аватар для vxg
3409 / 2181 / 354
Регистрация: 13.01.2012
Сообщений: 8,464
18.11.2016, 19:39
седьмой, пропуска данных как я понял нет иначе система наверное бы вернула ошибку при чтении. В тех настройках UART что я видел максимум 16 байт (это не означает что будет читать по 16 байт - функция чтения возвращает и бОльшие блоки данных), не знаю о каких 512 идёт речь, наверное мы о разном
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
18.11.2016, 20:57
Есть готовые реализации:

1. Компонент BComPort
2. boost/asio

Это легко ищется поиском по форуму.

Я использую свой велосипед: https://www.cyberforum.ru/blog... g4416.html там можно посмотреть код.

Цитата Сообщение от ITDeveloper Посмотреть сообщение
А по стандарту modbus в ответном сообщении это указывается. Но пусть даже в вашем случае он это не указывает. Раз вы указываете количество байт данных, то и ожидаете их столько же в ответном сообщении. То есть получаете сообщение, выбираете из него байты данных, общитываете их контрольную сумму и сравниваете с той, которая пришла от прибора. Совпало ОК, не совпало - все сообщение мусор. В чем проблема?
Вероятно в невежестве ТС, ему уже N-тем назад я пытался объяснить что нужно читать протокол обмена и разобраться как определить "конец" приема, но он и дальше продолжает плодить темы с попытками чтения синхронно.
1
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
18.11.2016, 22:09  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Вероятно в невежестве ТС, ему уже N-тем назад я пытался объяснить что нужно читать протокол обмена и разобраться как определить "конец" приема, но он и дальше продолжает плодить темы с попытками чтения синхронно.
Avazart, если Вы не читали всю эту тему, то повторю цитату из протокола обмена: "Критерием окончания запроса или ответа является гарантированный тайм-аут, длительность которого зависит от выбранной скорости обмена. Стандартные длительности тайм-аута: ...около 5 мс для скорости 9600 бод".
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
18.11.2016, 22:24
Да и что мешает использовать OVERLOPPED режим что бы читать с таймаутами?

В духе:
C++
1
2
3
4
5
6
7
8
9
10
SerialPort serial;
serial.setPortName(L"COM5");
serial.setBaudRate(CBR_9600);
serial.setReadTimeOut(5);
serial.open();
 
std::string  buffer(2048); // 2048 макс возможный размер.
 
std::size_t length= serial.read(&buffer[0],buffer.size()); 
buffer.resize(length);// устанавливаем реальный размер
Где: read нечто вроде:
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
ulong SerialPort::read(char *data, ulong size, ulong &errorCode)
{
  ulong mask= 0;
  WaitCommEvent(handle_, & mask, &rOverlapped_);
  ulong waitResult=
     WaitForSingleObject(rOverlapped_.hEvent, readTimeOut_);
  switch (waitResult)
  {
    case WAIT_OBJECT_0: errorCode= SerialError::Success; break;
    case WAIT_TIMEOUT:  errorCode= SerialError::WaitTimeOut; return 0;
    case WAIT_ABANDONED:
    case WAIT_FAILED:   errorCode= GetLastError();     return 0;
    default:    break;
  }
 
  if(aborted_)
  {
    errorCode= SerialError::Aborted;
    return 0;
  }
 
  ulong length= 0;
  BOOL success=
    ReadFile(handle_, data, size, &length,  &rOverlapped_);
  if(!success)
  {
    errorCode= GetLastError();
    if(errorCode==ERROR_IO_PENDING)
    {
      ulong waitResult=
        WaitForSingleObject(rOverlapped_.hEvent,    readTimeOut_);
      switch(waitResult)
      {
        case WAIT_OBJECT_0: errorCode= SerialError::Success; break;
        case WAIT_TIMEOUT:  errorCode= SerialError::WaitTimeOut; return 0;
        case WAIT_ABANDONED:
        case WAIT_FAILED:   errorCode= GetLastError(); return 0;
        default: break;
      }
 
      if(aborted_)
      {
        errorCode= SerialError::Aborted;
        return 0;
      }
    }
    else
      throw SystemException(errorCode);
  }
 
  success=
    GetOverlappedResult(handle_, &rOverlapped_,&length, true);
 
  if(!success)
    errorCode= GetLastError();
 
  rOverlapped_.Offset+= length;
  return length;
}

Вырвал из реального кода отсюда

Но полагаю 5мс число взятое от фонаря - уж слишком мало как мне кажется.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.11.2016, 22:24
Помогаю со студенческими работами здесь

Работа с COM портом
Здравствуйте! В процессе написания программы работы с устройством, подключенным к ПК через преобразователь интерфейсов RS485 - USB,...

Работа с Com портом
Привет всем! У меня собственно такая ситуация, есть bluetooth и телефон Nokia устанавливаю соединение через виртуальный com порт, мне...

Работа с COM портом в Builder C++ 6.0
Добрый день, уважаемые форумчане. Никогда не спрашивал совета на форумах, но нужна подсказка. Кто располагает временем, буду очень...

Работа с COM портом на С++ Builder 6
Работаю я с GSM модемами, пишу под них программу на C++ Builder 6. Посылаю в модем, через COM порт соответственно, AT команды (строку...

Работа с USB портом.
Доброго всем времени суток! Суть задачи в следующем: Есть устройство (USB принтер этикеток) и им можно управлять при помощи...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
19. здоровье, усталость и психотип работника влияют на производительность предприятия, и наоборот, производительность на здоровье, усталось и психотип
anaschu 28.05.2026
Дискретно-событийная модель рабочего коллектива на AnyLogic: здоровье, выгорание, психотипы и микростимуляция Привет, коллеги. Хочу поделиться итогами нескольких недель работы над симуляционной. . .
"Прокси" для последовательного порта
Eddy_Em 28.05.2026
Эту штуку написал я достаточно давно. Но сейчас вот понадобилось настроить датчик грозы, но при этом не отключать его от "метеодемона". Соответственно, надо запустить этот "прокси": метеодемон будет. . .
Рефакторинг программы уравнивания.
Massaraksh7 26.05.2026
Пример по предыдущей записи в блоге. Но, надо заметить, что, во-первых, там оптимизация не только математики, но и работы с базой данных, и с графами, а во-вторых, это ещё не всё.
Использование TThread в Lazarus для математических вычислений.
Massaraksh7 25.05.2026
Производя рефакторинг своих программ на предмет ускорения их работы, обратил внимание на такой аспект, как сокращение времени матвычислений. Дело в том, что приходится работать с большими матрицами. . .
Модель здравосохранения 18. Чем здоровее работник, тем быстрее выгорает
anaschu 24.05.2026
Имитационная модель корпоративного здравоохранения: что показывает математика Сегодня в модели рабочего коллектива на AnyLogic появились три новые механики — выгорание через накопленную усталость,. . .
Модель здравосохранения 17. Планы на выгорание
anaschu 23.05.2026
Вот конкретная схема реализации: В классе Работник добавить: накопленнаяУсталость — растёт каждый час работы, снижается в перерывы и болезни коэффициентПрезентеизма — снижает продуктивность. . .
Изменение цветов в палитре gif файла aka фавикона
russiannick 23.05.2026
Изменение цветов в палитре gif файла, юзаемого как фавиконка в составе html-файла, помещенная в base64, средствами нативного Java Script, навеянное сном в майский день. Для работы необходим браузер,. . .
Модель здравосохранения 16. Слишком хорошие и здоровые сотрудники уходят, недовольные зарплатой
anaschu 23.05.2026
Отладка увольнений и настройка производительности Сегодня во второй половине дня разобрались с механикой увольнений и настроили коэффициент сложности заданий. Вот что было сделано. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru