Se me plantea un problema a la hora de instalar una cámara. Necesito que mediante control remoto gire horizontalmente para que enfoque a otro punto. Dispongo de un grabador al que se conecta la cámara cctv que almacena las imágenes. Por suerte los DVR (grabador) disponen de una salida para controlar el PTZ (Pan Tilt Zoom) de las cámaras. Estos tienen acceso remoto por http y por apps en Android e IOS que incluyen además del visionado de las imágenes, el control del PTZ.
Con estos datos investigo acerca de estos puertos y descubro que son puertos serie RS485.
Por suerte encuentro un módulo para Arduino que me decodifica ese puerto.
Analizo las lecturas y el protocolo de comunicación, en este caso selecciono el PELCO D, uno de los más comunes.
Ya lo tenemos liado, pedido a Amazon que esto parece que se puede hacer.
Objetivo:
Controlar un motor en el eje x para que gire una cámara. El sistema tiene que controlarse con un grabador DVR.
Tecnologías a utilizar:
- Transmisión serie rs485
- Pelco D
- Arduino
- Controladora de motores paso a paso.
Materiales:
- Arduino Nano
- Modulo RS485 Arduino
- Controlador motores Puente H – L298N
- Motor DC 12V
Pelco D
Antes de entrar en detalle, necesito saber un poco acerca del PELCO D.
Pelco D consiste en la transmisión de 7 bytes en hexadecimal.
Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 |
Sync | Camera Address | Command 1 | Command 2 | Data 1 | Data 2 | Checksum |
Prestando atención al Byte 1, que selecciona el canal, es decir, la cámara que queremos controlar, y al Byte 3 que contiene la información para los movimientos según la siguiente tabla:
Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | |
Command 1 | Sense | Reserved | Reserved | Auto / Manual Scan | Camera on / off | Iris Close | Iris Open | Focus Near |
Command 2 | Focus Far | Zoom wide | Zoom Tele | Tilt Down | Tilt Up | Pan Left | Pan Right | Fixed to 0 |
Por ejemplo:
Si el byte 3 es 00000010 (2 en decimal) Gira horizontalmente (pan) a la derecha.
Si el byte 3 es 00000100 (8 en decimal) Gira horizontalmente (pan) a la izquierda.
Pues tema resuelto. Dejo la demás información para si alguien necesita hacer más funciones.
Puente H – L298N
El L298N es un controlador de motores al cual podemos conectar 2 motores DC o un motor paso a paso de 2 bobinados.
Se alimenta a 12V, al igual que nuestro sistema de vigilancia, y además tiene una salida de 5V para alimentar nuestro Arduino.
Para activar nuestro motor DC que conectaremos a la salida 1 – 2, debemos actuar sobre las entradas IN 1 e IN 2.
Si dejamos las dos en LOW. el motor se para.
Si ponemos IN1 en HIGH e IN2 en LOW el motor gira a la Izquierda.
Si invertimos los estados de IN1 e IN2, el motor invierte el sentido.
Además, dispone de otros pines con los cuales podemos regular la velocidad de giro del motor, los cuales yo dejo puenteados porque no me hace falta. Se trata de los pines ENA y ENB.
Max RS485.
Modulo que usamos para leer las tramas serie que envía el controlador PELCO D de nuestro grabador DVR. En el código he añadido mensajes serie, asique podemos abrir la consola serie de Arduino para comprobar los datos recibidos del DVR cuando mandamos las ordenes.
Así quedaría nuestro código con el cual conseguimos que funcione nuestro proyecto.
/*-----( Importar librerias necesarias )-----*/ #include <SoftwareSerial.h> // Software puerto serie /*-----( Declarar constantes y pins )-----*/ #define SSerialRX 0 //Pin recibir serie #define SSerialTX 1 //Pin transmitir serie #define SSerialTxControl 2 //RS485 Control de transmision #define RS485Transmit HIGH // No se usa aquí, los motores no transmiten nada al controlador PELCO D #define RS485Receive LOW #define Pin13LED 13 /*-----( Declaracion de objetos )-----*/ SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX /*-----( Declarar Variables )-----*/ // in1 D7 in2 D8 int IN1 = 7; int IN2 = 8; byte byteReceived[7]; int byteNumber = 0; int byteSend; void setup() { pinMode(IN1, OUTPUT); pinMode(IN2, OUTPUT); Serial.begin(9600); // Abre el puerto serie, pone el data rate en 9600 bps Serial.println("Arduino Serial Servo Control with Pelco D"); Serial.println(); pinMode(Pin13LED, OUTPUT); pinMode(SSerialTxControl, OUTPUT); digitalWrite(SSerialTxControl, RS485Receive); // Inicia transmision RS485Serial.begin(9600); // Pone el data rate a 9600 bps }//--(fin setup )--- void loop() { digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); // Ponemos a nivel bajo las salidas al L298N if (RS485Serial.available() > 0) //Busca datos del Controlador Pelco-D { digitalWrite(Pin13LED, HIGH); // Indica actividad byteReceived[byteNumber ++] = RS485Serial.read(); // Leer byte recibido delay(10); digitalWrite(Pin13LED, LOW); // Indica actividad if ( byteReceived[0] != 0xFF ) {byteNumber = 0;}} // Cuando Byte 0 es distinto de 0xFF (1er Byte Pelco) resetea byteNumber a 0 previniendo que el puerto serie se bloquee. if ( byteNumber > 6 ) // Se procesa { Serial.println(byteReceived[1], DEC); // Mostrar en Monitor serie el byte 1 Serial.println(byteReceived[2], DEC); // Mostrar en Monitor serie el byte 2 Serial.println(byteReceived[3], DEC); // Mostrar en Monitor serie el byte 3 Serial.println(byteReceived[4], DEC); // Mostrar en Monitor serie el byte 4 Serial.println(byteReceived[5], DEC); // Mostrar en Monitor serie el byte 5 byteNumber = 0; // preparado para siguiente transmision //Leyendo los bytes 3 y 4 en decimal: // 4 - 39 = IZQUIERDA // 2 - 39 = DERECHA // 16 - 0 = BAJAR // 8 - 0 = SUBIR // 32 - 0 = ZOOM IN // 64 - 0 = ZOOM OUT int data = byteReceived[3]; // Cogemos el byte 3 que es el que comparamos if (data== 4 ){ //si es = 4 gira a la izquierda el motor e imprime el movimiento en el monitor serie digitalWrite(IN1, HIGH); digitalWrite(IN2, LOW); Serial.print("IZQUIERDA"); delay(600); } else if (data== 2 ) { //si es = 2 gira a la derecha el motor e imprime el movimiento en el monitor serie digitalWrite(IN1, LOW); digitalWrite(IN2, HIGH); Serial.print("DERECHA"); delay(600); } else { //PARAMOS EL MOTOR digitalWrite(IN1, LOW); digitalWrite(IN2, LOW); } } }
Esquema de conexiones:
L298N:
- IN1 – D7
- IN2-D8
- 12V – FUENTE 12V
- GND – GND FUENTE 12V Y GND ARDUINO
- 5V – salida 5v para Arduino a Vin
MAX RS485:
- DI – TX1
- DE- D2
- RE – D2
- RO – RX0
- VCC- 5V ARDUINO
- GND – GND ARDUINO
- A – + DVR
- B – – DVR
En este caso uso las señales del PTZ emitidas por el grabador DVR para mover el motor DC, pero se me ocurren otras aplicaciones como activar relés para abrir puertas o encender luces, eso ya a gusto del consumidor.
Muchas gracias por leer el artículo, si te ha gustado deja un comentario, si no pues también.
Salu010 (010 = 2 = dos para los de letras)
Buenas noches:
Te comento que esta muy interesante tu proyecto, quiero implementar lo mismo pero solo para activar el comando de apertura de mi portón vehicular de la casa. Poseo un DVR y tiene salida RS 485 a si que no ese lado no hay problema.
Sucede que revice el código pero la librería include <SoftwareSerial.h> no logro pillarla, o ser que tengo un error de conocimiento.
Atte.
Te recomiendo el foro de arduino https://forum.arduino.cc/ es una comunidad muy potente:-)
Estimado:
He probado su programa, es excelente funciona sin problemas. Felicitaciones por su aporte.
atte.
Cesar Mundaca A
Temuco Chile
Hola amigo, muy bueno el tutorial, necesito hacer lo mismo pero utilizando los motores de una camra ptx modelo 24byj48 de 12v. Serias tan amable de ayudarme con el codigo. Soy nuevo en arduino.
Lo primero seria hacerse con las ficha de características 😉
Buen Material
Pero se te paso :
Si el byte 3 es 00000100 (8 en decimal) Gira horizontalmente (pan) a la izquierda.
para ser 8 deberia ser 1000, osea 3 ceros y no 2
Saludos
Muy bueno y didáctico, muchísimas gracias