В предыдущей статье был рассмотрен вариант работы с протоколом Pelco-D, а теперь рассмотрим работу с протоколом Pelco-P - это доработанная вариация предыдущего протокола управления PTZ-камерами, который также разработан одноимённой компанией Pelco. Также используется поверх интерфейса RS482/485 для связи с видеокамерами, оборудованными сервоприводами.
Протокол Pelco-P также имеет набор стандартных команд управления, а также расширенный комплект команд. Рассмотрим, как можем работать со стандартными командами. Протокол Pelco-P разберём на примере абстрактного источника команд и абстрактного SDK, которое принимает сообщение для дальнейшей передачи его в интерфейс RS485.
Таким образом имеется протокол, через который передаются данные, данные разбираются и дальше передаются в SDK, который уже отсылает сообщение в тракт передачи RS485. Ниже представлен рисунок, на котором имеется жёлтый квадрат. Именно в этой функции и будет формироваться необходимое нам сообщение, которое нужно будет передать в SDK.
Структура сообщения
Контрольная сумма является суммой по исключающему ИЛИ, то есть XOR, по байтам с 1-го по 7-й. Как видите в этом протоколе используется 8 байт для передачи сообщения, а не 7, как в Pelco-D.
Стоит отметить, что в протоколе Pelco-P адресация начинается не с 1, а 0. То есть первый адрес будет передаваться как #00, но самое интересно то, что в настройках PTZ камеры этот адрес будет указан как 01, стоит учитывать этот момент при разработке прослойки для работы с данным протоколом.
PAN и TILT команды
Примеры команд
Поворот влево: A0 00 00 04 20 00 AF 2B
Поворот вправо: A0 00 00 02 20 00 AF 2D
Наклон вверх: A0 00 00 08 00 20 AF 27
Наклон вниз: A0 00 00 10 00 20 AF 3F
Остановка всех действий: A0 00 00 00 00 00 AF 0F
Пример кода
В нашем абстрактном коде в вакууме создалась такая ситуация, что в функцию попадают следующие значения:
- address - адрес;
- PanSpeed - скорость с направлением поворота, от - 100 до +100;
- TiltSpeed - скорость с направлением наклона, от -100 до +100;
- ZoomSpeed - скорость с направлением Зума, от -100 до +100. Зачем так подавались данные для Зума - это для меня вопрос, учитывая что в Pelco нет установки скорости, но что есть, то есть.
А вот SDK уже принимает сформированную команду в виде указателя на массив данных и указанием длины этого массива. В результате получился следующий код.
void ptzCmd(int addressPTZ, int panSpeed, int tiltSpeed, int zoomSpeed) { unsigned char *dataPelco; unsigned char address, data1, data2, data3, data4, checkSum; address = data1 = data2 = data3 = data4 = checkSum = 0x00; dataPelco = (unsigned char*) malloc(8); memset(dataPelco,0,8); address = (unsigned char)addressPTZ; --address; if(pan < 0) { data2 |= 0x04; pan *= (-1); } else if(pan > 0) { data2 |= 0x02; } data3 = pan*63/100; if(tilt < 0) { data2 |= 0x10; tilt *= (-1); } else if(tilt > 0) { data2 |= 0x08; } data4 = tilt*63/100; if(zoom < 0) { data2 |= 0x40; } else if(zoom > 0) { data2 |= 0x20; } checkSum ^= 0xA0; checkSum ^= address; checkSum ^= data1; checkSum ^= data2; checkSum ^= data3; checkSum ^= data4; checkSum ^= 0xAF; dataPelco[0] = 0xA0; dataPelco[1] = address; dataPelco[2] = data1; dataPelco[3] = data2; dataPelco[4] = data3; dataPelco[5] = data4; dataPelco[6] = 0xAF; dataPelco[7] = checkSum; sdk_write_pelco_cmd(8, dataPelco); // 8 - это длина сообщения free(dataPelco); }