Декодер Pelco-d на ардуино

Вопросы программирования в системе Ардуино
Mahotin
Сообщения: 3
Зарегистрирован: 21 мар 2017, 21:35

Декодер Pelco-d на ардуино

Сообщение Mahotin » 21 мар 2017, 21:37

Подскажите куда и как копать

Есть ардуина, L298N и поворотная платформа для камеры с вращением в двух плоскостях, двигатели управляются постоянным навряжением 24В. Созрело зелание сделать PTZ камеру. С программированием, к сожалению... на уровне школьного Basic, но стараюсь))) С синтаксисом могут быть проблемы.

Суть задачи следующая: получение команд по протоколу Pelco-D через max485 на Rx UART ардуины, с последующим управление двигателями камеры через драйвер L298N. Все что после ардуины уже запустил, но как правильно получать и определять команды не совсем понимаю.

Допросив гугл понял что Посылка Pelco-d состоит из 7 байт:
1- байт синхронизации
2- адрес (естественно нужен, в случае нескольких камер)
3- байт команд 1 (фокус, диафрагма...-нам не интересен)
4- байт команд 2 (наклон, поворот... - то что нужно)
5- дата 1 (скорость поворота - нужная вещь, но при дальнейшей доработке)
6- дата 2 (скорость наклона - так же при дальнейшей доработке)
7- контрольная сумма (в моем случае мало важна)

Байт 6 "дата 2" состоит из бит:
7- фокус в даль
6- зум широкоугольный
5- зум теле
4- наклон вниз (то что нужно)
3- вверх
2- поворот влево
1- вправо
0- всегда 0

В некоторых источниках указана посылка FF 01 00 00 00 00 - STOP
Отсюда ПЕРВЫЙ ВОПРОС: камера выполняет наклон/поворот пока ей с определенной переодичность шлют команду наклоняться/поворачиваться либо до момента прихода посылки Stop?

В мой реализации достаточно вверх, вниз, влево, вправо без диагональных направлений и скорости.
Пример байта 6 (команда на поворот влево, остальные 0):
0b00000100 или 0x04

Соответственно посылка будет иметь следующие виды (адрес: 1, к.с. не важна, пусть будет 12, а скорость 3F):
FF 01 00 04 3F 00 12 - Влево
FF 01 00 02 3F 00 12 - Вправо
FF 01 00 08 00 3F 12 - Вверх
FF 01 00 10 00 3F 12 - Вниз

Поправьте если я что-то не так понял про реализацию протокола.

И самый главный вопрос как все это считать из UART и определить что делать? Ввести переменную ByteBuf[7], в теле цикла проверять поступление данных в UART командой if (Serial.available()), вносить байты данных в ByteBuf через for (int i=0; i<7; i++) {ByteBuf[i]= Serial.read();} и потом сравнивать адрес c ByteBuf[1] по средствам if (ByteBuf[1] == 0х01) {}, а команды c ByteBuf[3] и включать двигатель в том или ином направлении? Либо как-то через прерывание?


Эдуард
Администратор
Сообщения: 365
Зарегистрирован: 30 окт 2016, 20:53

Re: Декодер Pelco-d на ардуино

Сообщение Эдуард » 21 мар 2017, 21:59

Здравствуйте!

Я сейчас пишу серию уроков, посвященных обмену информацией по локальной сети.
Для начала посмотрите, как реализован протокол обмена в уроке 31. Только там текстовый протокол а у вас числовой.
Дальше посмотрите реализацию обмена в уроках 48 и 49. Там уже числовой протокол. Он простой, только 2 устройства в сети, селектирования адреса нет. Но принцип реализации вы можете понять.
Через 1 урок я собираюсь реализовывать протокол ModBus. Это уже более сложный обмен данными с несколькими устройствами.

Принцип работы с UART у меня везде одинаковый. В цикле прерывания от таймера опрашивается состояние буфера класса Serial. По приходу данных принимается решение, что делать.

Mahotin
Сообщения: 3
Зарегистрирован: 21 мар 2017, 21:35

Re: Декодер Pelco-d на ардуино

Сообщение Mahotin » 24 мар 2017, 12:39

Эдуард, спасибо за уроки!

Позаимствовал код из Вашего урока №48.
Проект Готов)))

Схема проекта(нарисована в paint, не судите строго):
Изображение

Примененное оборудование:
- Arduino Uno
- Драйвер L298N (логика включена - всего два сигнала на канал)
Изображение
- Приёмопередатчик MAX485
- Поворотная платформа (со встроенными оконечниками - самостоятельно отключает питание от двигателя в данном направлении)
Изображение

Программа:
► Показать



В данной проекте реализовано включение двигателей наклона и поворота при поступлении соответствующих команд.
Направления движения: вверх, вниз, влево, вправо, 4 диагональных направления.
Скорость постоянная, для реализации разноскоростных движений нужно дорабатывать программу. По этому введены "мертвые зоны скорости".
Нужно учесть что байт команд 2 содержит информацию не только о наклоне и повороте, но и о зуме и фокусе, сейчас это не реализовано и при поступлении байта комадн 2 с поворотом/наклоном и фокусом/зумом (наклоне PTZ-джойстика и нажатии кнопки зум/фокус) контроллер полностью проигнорирует эту посылку. Для доработки нужно рассматривать не байт команды, а находящиеся в нем биты (см протокол Pelco-D).
Логика работы:
Контроллер при поступлении команды вверх/вниз включает двигатели, остановка происходит после поступления команды Stop (0хFF 0х01 0х00 0х00 0х00 0х00 0х01), а именно когда скорость = 0х00.

Эдуард
Администратор
Сообщения: 365
Зарегистрирован: 30 окт 2016, 20:53

Re: Декодер Pelco-d на ардуино

Сообщение Эдуард » 24 мар 2017, 14:47

Рад, если помог.
Если скорость не высокая (до 19200 бод), я бы MAX485 заменил на оптрон. Повысилась бы помехоустойчивость, увеличилась длина линии связи, появилась бы гальваническая развязка. В следующем уроке я буду рассказывать об этом (интерфейс ИРПС).

Mahotin
Сообщения: 3
Зарегистрирован: 21 мар 2017, 21:35

Re: Декодер Pelco-d на ардуино

Сообщение Mahotin » 24 мар 2017, 23:15

Уточнение: на драйвере L298N перемычка VC=VS убрана!!!



Эдуард, подскажите, если реализовывать считывание и обработку данных не по прерыванию, а в теле loop
Например:
void loop() {
if (Serial.available()) {
byte buf[7];
buf[0]=serial.read();
buf[1]=serial.read();
И так далее
}
}


В чем ошибка и чем такая реализация(при исправлении ошибки) хуже или лучше чем через прерывание.
Поясню почему созрел вопрос: изначально начал делать в теле loop, только получал одиночные посылки по 7 байт из порта, а выводил их разбитые на байты на подключенный к ардуино LCD. Все было хорошо в buf[0] получал байт синхронизации, в buf[1] байт адреса и т.д., но когда начал убирать строчки кода для работы с дисплеем и добавлять управление драйвером двигателей ничего не заработало. Начал ответно отслылать считанные байты в монитор порта и увидел что все 7 байт выводятся при serial.print(buf[0]), а не как раньше с LCD. А так как делал все на рабочем месте параллельно с работой, в голове началась каша, плюнул и взял ваш код с прерыванием. Чуть позже попробую проверить свой код, но хотелось бы услышать Ваше мнение.

Эдуард
Администратор
Сообщения: 365
Зарегистрирован: 30 окт 2016, 20:53

Re: Декодер Pelco-d на ардуино

Сообщение Эдуард » 24 мар 2017, 23:55

Ошибка мне кажется уже в первой строке: if (Serial.available()).
Должно быть принято 7 байт if (Serial.available() == 7).

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


Вернуться в «Программирование Ардуино»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей