Skip to content

Instantly share code, notes, and snippets.

@vk2gpu
Created October 29, 2023 07:57
Show Gist options
  • Save vk2gpu/812d3fb654fe67c0ecc4801a0bd84a79 to your computer and use it in GitHub Desktop.
Save vk2gpu/812d3fb654fe67c0ecc4801a0bd84a79 to your computer and use it in GitHub Desktop.
Shock Collar Remote on Arduino.
const uint32_t RemoteSecret = 0b0101111110011001;
const int PinTX = 8;
const int PinLED = LED_BUILTIN;
const int PreambleHighTime = 1370;
const int PreambleTotalTime = 2160;
const int BitOneHighTime = 725;
const int BitZeroHighTime = 225;
const int BitTotalTime = 1020;
#define TYPE_SHOCK 1
#define TYPE_VIBRATE 2
#define TYPE_BEEP 3
struct ShockCollarMsg
{
uint8_t bytes[5];
};
ShockCollarMsg BuildShockCollarMsg( uint32_t secret, uint32_t channel, uint32_t type, uint32_t power )
{
ShockCollarMsg msg = {};
msg.bytes[0] = secret >> 8;
msg.bytes[1] = secret & 0xff;
msg.bytes[2] = (channel & 0x7) << 4 | ( type & 0x7);
msg.bytes[3] = power > 99 ? 99 : power;
msg.bytes[4] = msg.bytes[0] + msg.bytes[1] + msg.bytes[2] + msg.bytes[3];
return msg;
}
void TransmitSymbol(int highTime, int totalTime )
{
unsigned long stopwatch = 0;
stopwatch = micros();
digitalWrite(PinTX, HIGH);
while( ( micros() - stopwatch ) < highTime );
digitalWrite(PinTX, LOW);
while( ( micros() - stopwatch ) < totalTime );
}
void TransmitByte( uint8_t byte )
{
for(int i = 7; i >= 0; --i )
{
if( byte & (1 << i) )
TransmitSymbol( BitOneHighTime, BitTotalTime );
else
TransmitSymbol( BitZeroHighTime, BitTotalTime );
}
}
void TransmitShockCollarMsg( ShockCollarMsg msg )
{
digitalWrite(PinLED, LOW);
// Hacky switch it off and on again as there was some weird timing issues...
delayMicroseconds( 50000 );
digitalWrite(PinTX, HIGH);
digitalWrite(PinTX, LOW);
delayMicroseconds( 50000 );
// Preamble.
TransmitSymbol( PreambleHighTime, PreambleTotalTime );
// Payload.
for(int i = 0; i < 5; ++i )
{
TransmitByte( msg.bytes[i] );
}
// End of message.
TransmitSymbol( BitZeroHighTime, BitTotalTime );
TransmitSymbol( BitZeroHighTime, BitTotalTime );
TransmitSymbol( BitZeroHighTime, BitTotalTime );
digitalWrite(PinTX, LOW);
digitalWrite(PinLED, HIGH);
}
void setup()
{
pinMode(PinTX, OUTPUT);
pinMode(PinLED, OUTPUT);
}
void loop()
{
static int lastTime = millis();
if ((millis() - lastTime) >= 2000)
{
ShockCollarMsg msg = {};
for(int i = 0; i < 100; i += 10 )
{
msg = BuildShockCollarMsg( RemoteSecret, 0, TYPE_VIBRATE, i );
for(int j = 0; j < 10; ++j)
{
TransmitShockCollarMsg( msg );
}
delay(500);
}
msg = BuildShockCollarMsg( RemoteSecret, 0, TYPE_BEEP, 0 );
TransmitShockCollarMsg( msg );
delay(500);
for(int i = 0; i < 100; i += 10 )
{
msg = BuildShockCollarMsg( RemoteSecret, 0, TYPE_SHOCK, i );
for(int j = 0; j < 10; ++j)
{
TransmitShockCollarMsg( msg );
}
delay(500);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment