Konstantin Dorohov
Published © GPL3+

Hacking YT-500 Pan-Tilt Head Radio Remote

But why?

BeginnerShowcase (no instructions)913
Hacking YT-500 Pan-Tilt Head Radio Remote

Things used in this project

Hardware components

Arduino UNO & Genuino UNO
Arduino UNO & Genuino UNO
×1
FS1000A 433 MHz RF Transmitter
×1

Software apps and online services

SDR# software
Audacity software
Arduino IDE
Arduino IDE
Processing
The Processing Foundation Processing

Hand tools and fabrication machines

RTL-SDR Blog V3 R820T2 RTL2832U 1PPM TCXO SMA Software Defined Radio
Any SDR dongle will do

Story

Read more

Schematics

Block diagram

FS1000A RF transmitter connection

Code

Arduino sketch

Arduino
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 code

Processing
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));  
}

Credits

Konstantin Dorohov

Konstantin Dorohov

1 project • 3 followers
Biophysics research scientist in USSR Acad. of Sciences - 20 yrs; 25 yrs in IT, including 20 yrs as Oracle Developer.

Comments