Skip to content

Instantly share code, notes, and snippets.

@CrosseyeJack
Last active March 7, 2017 06:10
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CrosseyeJack/8397361 to your computer and use it in GitHub Desktop.
Save CrosseyeJack/8397361 to your computer and use it in GitHub Desktop.
Clone of a Shock Collar RF Remote slapped together for an Arduino Leonardo
#define transmit_pin 2 // The digital pin the transmitter is connected to. I'm using a FS1000A
#define led_pin 3 // The digital pin the LED is connected to. I'm using a BLUE LED cause...
// Using a classic replay attack for cloning the remote. Its a fairly simple remote using fixed codes.
// The pulsewidth and messages were recoded and decoded using the "Hack a receiver into the line in port of a soundcard
// and press record" method. A method I first learnt about at http://rayshobby.net/?p=3381 - who picked up the idea from
// http://forum.arduino.cc/index.php/topic,22105.0.html who got the idea from http://davehouston.net/learn.htm who may
// of got the idea from something else. Who Knows... Anywhos. Thanks to all of the above for shining a light on this.
#define pulsewidth 465 // The width of a single pulse
const char* vibrate = "010111110010000000000100"; // The 24 bit message sent when the vibrate button was pushed
const char* shock = "010111110010000000001000"; // the 24 bit message sent when the shock button was pushed
boolean vib_state = false; // Boolean to store the "should vibrate" varible
boolean shock_state = false; // Boolean to store the "should shock" varible
boolean vib_after_shock = false; // A flag used to send a quick vibrate after a shock as the collar used.
// atm uses "fixed" shock lenghts. This means when you let go of the
// shock button the collar Stops shocking.
void setup() {
attachInterrupt(2, vibrate_change, CHANGE); // The vibrate button interrupt
attachInterrupt(3, shock_change, CHANGE); // The shock button interrupt
}
void loop() { // Loop - checking if any of the var's means works needs to be done.
while (vib_state) { // The vibrate flag was set - loop until the flag is unset
digitalWrite(led_pin,HIGH); // Light up the LED...
RFsend(vibrate); // Send the vibrate packet
} // Loop...
while (shock_state) { // The Shock flag was set - loop until the flag is unset
if (!vib_after_shock) // Check the "After Shock" flag
vib_after_shock = true; // And set it if its false
digitalWrite(led_pin,HIGH); // Light up the LED...
RFsend(shock); // Send the Shock Packet
} // Loop...
if (vib_after_shock) { // Check if the "after shock" flag was set
RFsend(vibrate); // Send a single vibrate packet
vib_after_shock = false; // Clear the "after shock" flag
}
digitalWrite(led_pin,LOW); // switch off the LED
}
// So what the fuck is this "After Shock" thingy bob???
// Well the see the collar I am expermenting on atm is a bit "shit" it vibrates and shocks for a "Fixed" amount of time
// of about 1 second and then just loops that if you need a longer shock/vibrate. But we want finer control of at least
// of the shock command. This is wherer the "after shock" comes in. I discovered that the fixed lengh shock could be
// interrupted with a vibrate command. So when the shock button is released we send a single vibrate packet that halts
// shocking and vibrates. Fairly simple... The other Collar I had (and killed) didn't have the "flaw" of fixing the
// shock and vibrate lengths.
void vibrate_change() { // A simple "hack" instead of fucking around with debounce
vib_state = digitalRead(0); // If the button is pressed - do something
}
void shock_change() { // Rinse and Repeat
shock_state = digitalRead(1);
}
void RFtransmit(int highp, int lowp) { // Send High for X - Send Low for X - Simple RF on this remote isn't
digitalWrite(transmit_pin, HIGH); // Rocket science - tbh I found its simplicity rather *shocking*
delayMicroseconds(pulsewidth * highp);
digitalWrite(transmit_pin, LOW);
delayMicroseconds(pulsewidth * lowp);
}
void RFsend(const char* code) { // Given a char array of 1's and 0's decide with packet to send
int i = 0;
while (code[i] != '\0') { // Loop though the array until we hit the end
switch(code[i]) { // have a look at the bit we have
case '0': // if we have a 0 bit
RFtransmit(1,3); // 0 bit // send one high pulse then 3 low pulses _|‾|___
break;
case '1': // if we ahve a 1 bit
RFtransmit(3,1); // 1 bit // send 3 high pulse and 1 low pulse _|‾‾‾|_
break;
}
i++;
} // AGAIN - AGAIN....
RFtransmit(1,31); // Send the "End Pulse" - 1 High pulse 31 - Low Pulses
}
@jmsaavedra
Copy link

This looks great, thanks for posting. Any chance you remember what collar/brand/model this was confirmed working with?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment