Передача через COM-порт.
- Войдите на сайт для отправки комментариев
Вс, 07/07/2013 - 11:23
Всем привет! Проблема такая. Плата Mega 2560. Через Serial1 (115200 бод) поступают данные от устройства A, обрабатываются и передаются через Serial2 (28800 бод) в устройство B через Serial2.write(). Вовремя принять данные из буфера позволяет функция Serial1.available(). Передать данные, так же асинхронно пополнив буфер передачи, средствами языка разработки нельзя, т. к. отсутствует функция проверки опустошения буфера передачи (аналогичная .available()). Применение delay() для создания задержек на передачу съест кучу времени у функций обработки. Уважаемые господа, может подскажете, как проверить буфер передачи на опустошение средствами скетч-языка?
т. к. отсутствует функция проверки опустошения буфера передачи (аналогичная .available()).
http://arduino.ru/Reference/Serial/Flush
Но там написано:
Serial.flush() ОЖИДАЕТ окончания передачи исходящих данных, т. е. на время ожидания все тормозит?
Да, но ведь пока она выполняется,буфер первого сериала будет заполнятся принятыми данными. так что просто делаешь последовательность, считал, преобразовал, передал.
Синхронно все делать все равно не получится из за разности скоростей.
Программно обработка осуществляется 8-ю связанными конечными автоматами, и один из них выполняет выравнивание потоков данных на входе и выходе, так что, к сожалению, в данном случае поможет не внесение дополнительной задержки, а проверка свободного места в буфере передачи.
Ну тогда, разбирай библиотеку serial на составные части.
как я понял в функции
именно регистр TXC0 отвечает за наличие данных в буфере
Вообще-то мысль неплохая! А где эта библиотека Serial находится, если не секрет?Попробую дописать в Serial функцию что-то вроде int txbuffer_is_empty().
\arduino-1.0\hardware\arduino\cores\arduino\ HardwareSerial.cpp и HardwareSerial.h
Так же некоторые методы наследуются от Stream.
Спасибо, буду разбираться & дописывать.
P. S.
Так оно и оказалось. Добавил в библиотеку HardwareSerial (файл HardwareSerial.cpp)
функцию bool txempty(void), с Serial.write() вроде работает:
здесь надо обязательно использовать флаг transmitting. И в заголовочном файле HardwareSerial.h в объявлении класса, в разделе public соответственно добавить функцию
Теперь можно вызывать из скетча проверку буфера
и по ходу дела добавлять данные на передачу.
Не используйте Serial.flush() она не всегда нормально работает, точнее не всегда работает, я сам попал на этот глюк, но добрые люди подсказали
без такого сброса рано или поздно начнут приходить левые данные
Почитайте о Serial.flush(), а потом перечитали что хотел ТС, эта функция ожидает окончания передачи данных, в то время как вы пытаетесь этой функцией очистить приемный буфер. Так что работает она всегда и нормально если ей правильно пользоваться.
Хм... таки да, до версии 1.0 она стирала буфер, но как тогда ею пользоваться и в каких случаях? а точнее какой тогда смысл? Всеравно в большенстве случаев данные передаются блоками и читаем с буфера блоками(побатово). Я чисто для самообразования интерисуюсь, т.к. програмер только на уровне библиотек
Кстати ТС мог бы и написать как именно передаются данные, возможно упростило бы понимание что именно нужно сделать, я в своем проекте передаю необходимые данные в 37ми символах, в 10й системе, первые четыре цифры - адрес и комада, остальное данные этой команды.
А ТС можно порыться в либе от GPS там думаю ему будит много полезного, ИМХО конечно
Пользоваться как раз в таких случаях как у ТС, то есть когда нужно дождаться окончания передачи данных.
Да но если как у ТС и входящие данные идут неприрывно, то все рано или поздно упрется в буфер, как по мне то лучше в его случае ждать заполнения буфера например 10 байтами, сразу читать далее отправлять, а пока отправляются на меньшей скорости то буфер заполнится еще каким то количевством данны, и мы не будим ждать пока закончится передача кажется так лучше, т.е. как то так:
Или я не правельно понимаю как работает буфер?
допустим данные идут неприрывно, мы считали первые 10 байт, и после это например данные из ечейчи 11 и 12 которые заполнились во время чтения переносятся в ячейку памяти 1 и 2 соответственно, тоесть сжвиг данных получается по адресу.
Или происходит по другому?
А как тогда собирать принятые данные? писать то будим в масив? но как узнать количевство принятых данных? т.к. если например в стринг собирать чтобы проще было то стринг забъется в конце нулями в зависимости от длинны массива, или как то по другому можне?тогда получается
Наверно как то так тогда получается и нужно учесть что буфер максимум 128 байт http://arduino.ru/Reference/Serial/Available
Всем привет! Только что вернулся из командировки, где успешно установил свое устройство на Mega 2560 (раньше Arduino не пользовался, программировал контроллеры на C и ASM).
Вкратце сутью проекта было построение конвертора протоколов из разновидности modbus (115200 бод, с байтами-разделителями, адресами, кодами операций, данными, пустыми байтами и CRC8, переменная длина кадра) в специфический протокол ввода в PC (28800 бод). Цель - подключить внешнее устройство к Soft-у на PC, изначально для работы с этим устройством не предназначенному (т. е. эмулировать одно устройство с помощью другого, аналогичного по функциям).
Прием. Из вариантов: 1)прием по прерываниям, 2)прием в бесконечном цикле в отдельном потоке, 3)прием в общем бесконечном цикле, для Arduino подошел последний вариант №3 в цикле loop{}. Для большей равномерности и исключения всяческих зависаний оптимален ПОБАЙТОВЫЙ прием и обработка со СРЕДНЕЙ скоростью 115200 бод, и честно говоря, большой необходимости в программном буфере я здесь не наблюдаю. Передача. Здесь, наоборот, оказалось удобнее формировать и класть в программный буфер передачи с помощью Serial.write() порции байтов (в моем случае по 24 байта), проверяя его на пустоту по Serial.txempty() (POST #9) опять же в общем бесконечном цикле.
Проверенный надежный способ реализации нескольких задач в бесконечном цикле - представление их в виде конечных автоматов (КА) по известной switch-технологии (управление состоянием КА по switch-case). Единственное ограничение - функции КА не должны вносить больших задержек, чтобы обеспечивать СРЕДНИЕ скорости приема и передачи.
vs2007,
вероятно, возможно развитие ...
1. узнать размер буфера отправки
2. в цикле: если программе есть что отправить и если в буфере отправки есть N свободных байт, вызвать Serial.write ...
Да, конечно. Кстати, полный размер программного буфера отправки 64 байта, но его можно изменить в библиотеке.