-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This looks great, thanks for posting. Any chance you remember what collar/brand/model this was confirmed working with?