У попередній статті було розглянуто варіант роботи з протоколом 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
Приклад коду
У нашому абстрактному коді у вакуумі створилася така ситуація, що у функцію потрапляють такі значення:
- адреса - адреса;
- 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);
- }