Project showcase
Hacking YT-500 Pan-Tilt Head Radio Remote

Hacking YT-500 Pan-Tilt Head Radio Remote © GPL3+

But why?

  • 313 views
  • 0 comments
  • 4 respects

Components and supplies

Necessary tools and machines

Apps and online services

About this project

Pan-Tilt Head YT-500 from ZIFON is good for controlling some lightweight camera position (like, smartphone or a small camera with the weight under 500g). The head is controlled not by regular IR remote, but with small RF box at 433MHz with telescopic antenna. So I want to emulate this remote with Arduino and cheap RF transmitter. This would allow controlling your camera position from host computer. For simplicity I used Processing for communication with Arduino, which is quite trivial. The only interesting part of this project is about reverse-engineering remote protocol.

Final Result

Here is a short video demonstrating the outcome of the project:

Transmission distance with HS1000A transmitter without any antenna was at least ~6 yards.

RF Package Sniffing

Here is the spectrum of original remote as seen from SDR# program:

Transmission was recorded as regular.wav file, and re-opened in Audacity.

Here is the package view after some filtering and adjustment as seen in Audacity. This package is produced by pressing 'Left' button. Packages are transmitted permanently while the button is pressed, interval between packages is 18 ms:

Each package consists of 10ms preamble, 4 ms break and 53 ms of payload part. The total length of a package (including interval between packages is ~85 ms

Payload of the package above I interpreted as '11112252541112112' ( see description in sketch)

When writing Arduino sketch I had to adjust timing compared to measured in Audacity, until original and emulated packages look visually identical:

Code

Arduino sketchArduino
Description of packages structure is in Arduino sketch comment.
/************************************************************
* WHEN: 23-SEP-2019
* WHAT: Receiving characters from Processing 
* DETAILS:  simple RF transmitter on pin 11
/************************************************************/
#define DATAOUT 11 //RF transmitter

/*here is sniffed packages produced by remote:

package starts with 9 ms HIGH (preambula?)
next - 4 ms pause
next comes data represented by combinations of 1 ms HIGH 
and 2 types of LOW: 1 ms and 2 ms.
for simplicity I did not decode it into bits and I am not using any libraries.
so I interpret:
single HIGH (1 ms) as '1'
single HIGH(1 ms), single LOW (1ms), single HIGH (1 ms) is '2'
single HIGH(1 ms), single LOW (1ms), single HIGH (1 ms), single LOW, single HIGH = '3'
and same way '4' and '5'
these 'numbers' (1,2..5) are separated by double LOW (2 ms)
While remote button is pressed same package is repeated with 18 ms breaks between packages.
so the data for 'Left' button is:
11112252541112112
right:
11112252442121121
down:
11112252343211211
up:
11112252413111313*/
char s_received;

 void setup()
 {
   pinMode(DATAOUT, OUTPUT);     
   Serial.begin(115200);
   while (!Serial); 
 }

 void loop(){
if (Serial.available()) 
   { 
    s_received = Serial.read(); 
    if (s_received=='L') {
      send_left();
      delay(18);
    }
    else if (s_received=='R') {
      send_right();
      delay(18); 
    }      
    else if (s_received=='U')  {
      send_up();
      delay(18); 
    }      
    else if (s_received=='D')  {
      send_down();        
      delay(18); 
    } 
   }
  }  
     
void send_data(byte n){
    for (int i=1; i<n; i++)
    {
      digitalWrite(DATAOUT, HIGH);   
      delayMicroseconds(550);
      digitalWrite(DATAOUT, LOW);
      delayMicroseconds(550);      
    }  
    digitalWrite(DATAOUT, HIGH);   
    delayMicroseconds(550);
    digitalWrite(DATAOUT, LOW);
    delayMicroseconds(1630);
 }

 void send_header(){
     digitalWrite(DATAOUT, HIGH);   //header
     //digitalWrite(LED_BUILTIN, HIGH);
     delayMicroseconds(8900);
     
     digitalWrite(DATAOUT,LOW);
     //digitalWrite(LED_BUILTIN, LOW);
     delayMicroseconds(4450);
 }

void send_left(){
     send_header();
     send_data(1);
     send_data(1);
     send_data(1);
     send_data(1);
     send_data(2);
     send_data(2);       
     send_data(5);
     send_data(2);
     send_data(5);          
     send_data(4);
     send_data(1);     
     send_data(1);     
     send_data(1);     
     send_data(2);
     send_data(1);          
     send_data(1);     
     send_data(2);
}

void send_right(){
     send_header();
     send_data(1);
     send_data(1);
     send_data(1);
     send_data(1);
     send_data(2);
     send_data(2);       
     send_data(5);
     send_data(2);
     send_data(4);          
     send_data(4);
     send_data(2);     
     send_data(1);     
     send_data(2);     
     send_data(1);
     send_data(1);          
     send_data(2);     
     send_data(1);
} 

void send_down(){
     send_header();
     send_data(1);
     send_data(1);
     send_data(1);
     send_data(1);
     send_data(2);
     send_data(2);       
     send_data(5);
     send_data(2);
     send_data(3);          
     send_data(4);
     send_data(3);     
     send_data(2);     
     send_data(1);     
     send_data(1);
     send_data(2);          
     send_data(1);     
     send_data(1);
} 

void send_up(){
     send_header();
     send_data(1);
     send_data(1);
     send_data(1);
     send_data(1);
     send_data(2);
     send_data(2);       
     send_data(5);
     send_data(2);
     send_data(4);          
     send_data(1);
     send_data(3);     
     send_data(1);     
     send_data(1);     
     send_data(1);
     send_data(3);          
     send_data(1);     
     send_data(3);
} 
Processing codeProcessing
most of Draw part is just decorative;
What to pay attention at:
I had to limit frame rate to 10 frames per second. This is important. The package length is ~85 ms; When the keyboard key is pressed and hold, key code is produced 60 times per second. In such case serial commands sent to Arduino with every key code are buffered and as a result arduino keeps transmitting long after the key was released. With decreased frame rate keyPressed event is only registered not more then 10 times per second, no buffering occurs and PanTilt head moves smoothly and stops moving immediately when key is released.
/*
 09/23/2019
 controls arduino with RF transmitter. 
  */


import processing.serial.*;
PShape s_up,s_right,s_down,s_left;
boolean arr_pressed=false;
boolean arr_released=true;
int arr_code;
Integer v_margin=50;

Serial myPort;  // Create object from Serial class
int val;        // Data received from the serial port
boolean no_comport=true;

void setup() 
{ frameRate(10);
  size(200, 200,P2D);
    background(255);
  shapeMode(CENTER);  
  s_up=loadShape("red_up2.svg");
  s_right=loadShape("red_right2.svg");
  s_down=loadShape("red_down2.svg");
  s_left=loadShape("red_left2.svg");
  
  s_right.setFill(color(255,255,255));
  s_down.setFill(color(255,255,255));
  s_left.setFill(color(255,255,255));
  s_up.setFill(color(255,255,255));  
  
  if (Serial.list().length==0){
    println("No ComPort Found");
  }
  else {
  no_comport=false;  
  String portName = Serial.list()[0];  
  printArray(Serial.list());
  myPort = new Serial(this, portName, 115200);
  }
}

void draw() {
  if (no_comport) exit();
//4 lines below can be commented out
 shape(s_right,width-v_margin,height/2, 50,50);
 shape(s_down,width/2,height-v_margin, 50,50);
 shape(s_left,v_margin,height/2, 50,50);
 shape(s_up,width/2,v_margin, 50,50);  
  
  if (arr_pressed)
    switch(arr_code) {
  case UP: 
    myPort.write('U'); 
    break;
  case DOWN: 
    myPort.write('D');  // Does not execute
    break;
  case LEFT: 
    myPort.write('L');  // Does not execute
    break;    
  case RIGHT: 
    myPort.write('R');  // Does not execute
    break;    
    }
}


void keyPressed() {
  if ((key == CODED) && (arr_pressed==false)) {
    arr_code=keyCode;
    arr_pressed=true;
    switch(keyCode) {
    case UP: 
      s_up.setFill(color(255,0,0));
      break;
  case DOWN: 
      s_down.setFill(color(255,0,0));
      break;
  case LEFT: 
      s_left.setFill(color(255,0,0));
      break;    
  case RIGHT: 
          s_right.setFill(color(255,0,0)); 
      break; 
    }   
  }
}  

void keyReleased(){
  arr_pressed=false;
  s_right.setFill(color(255,255,255));
  s_down.setFill(color(255,255,255));
  s_left.setFill(color(255,255,255));
  s_up.setFill(color(255,255,255));  
}

Schematics

Block diagram
FS1000A RF transmitter connection
Capture eb4ljpkd73

Comments

Similar projects you might like

Servo Motor Control with Remote

Project showcase by Electronic Clinic

  • 3,080 views
  • 1 comment
  • 19 respects

How to Make a Remote Controlled Robotic Hand with Arduino

Project showcase by Gabry295

  • 43,350 views
  • 5 comments
  • 135 respects

Rail Road Model IR Remote Control (REMOTINO NANO)

Project showcase by pautax

  • 1,189 views
  • 0 comments
  • 5 respects

Arduino: Switching ON/OFF Appliances Using IR Remote

Project showcase by Naman Chauhan

  • 13,201 views
  • 0 comments
  • 128 respects

Servo Control with TV Remote Control

Project showcase by eldo85

  • 11,165 views
  • 5 comments
  • 32 respects
Add projectSign up / Login