Cómo controlar un motor PTZ de cámara CCTV con Arduino

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)

7 comentarios en “Cómo controlar un motor PTZ de cámara CCTV con Arduino”

  1. Cesar Antonio Mundaca Alarcon

    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.

  2. Cesar Antonio Mundaca Alarcon

    Estimado:

    He probado su programa, es excelente funciona sin problemas. Felicitaciones por su aporte.

    atte.
    Cesar Mundaca A
    Temuco Chile

  3. 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.

  4. Carlos Torrez

    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

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Zamora Aventura utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies
Scroll al inicio