Created
May 13, 2017 13:22
-
-
Save CurlyWurly-1/0e7b74b01537f6af4a4d2a80896fd558 to your computer and use it in GitHub Desktop.
A pair of Arduino UNO sketches to decrypt and spoof 433 MHz "static code" communication
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
/* | |
sketch : sniffer_433_RX (sister of "sniffer_433_TX") | |
Author : Peter Matthews (CurlyWurly) May 2017 | |
Desc : When a static 433 transmission is received, a "int codez[]=.." line is output to the serial bus. | |
Copy this line and paste it into the the sister sketch "sniffer_433_TX" | |
INFORMATION | |
N.B. Connect pin 2 (rxpin) to the RX module output | |
N.B. Copy the output "int codez[] = ...." from serial bus and copy into the sister sketch "Sniffer_433_TX" | |
N.B. This sniffer sketch just outputs a set value of 35 in code[0]. This means that you may have to | |
experiment using a different "repeat" value (usually a value of 15 - 45) when used in the "TX" sketch | |
N.B. The code structure is contained from code[0] to code[n] and is defined as: | |
code[0] - No. of times to repeat the code | |
code[1] - No. of pulses (Hi/low combination) - This means it is half the total number of Hi and Low states | |
code[2] - Wait unit time (Hi and Low states are constructed with multiples of this) | |
code[3] - First HIGH state multiplier - multiply with code[2] | |
code[4] - First LOW state multiplier - multiply with code[2] | |
.... | |
code[n] - last LOW state multiplier | |
The first pulse is made up of code[3] and code[4] | |
and the second pulse is made up of code[5] and code[6] | |
*/ | |
#define rxPin 2 //Input from receiver | |
#define maxState 300 //Maximum States (Halve for pulses, will detect "pulse trains" up to 75 pulses long) | |
bool pinstate; // State of input pin - Hi(1) or Low(0) | |
int stateCount; // State change counter | |
int i; // Array counter | |
int low1; // Index of Low period 1 | |
int low2; // Index of Low period 2 | |
int low3; // Index of Low period 3 | |
int low4; // Index of Low period 4 | |
unsigned long T_array[maxState]; // Array of HiLo pulse lengths (starts with Hi) | |
unsigned long same_cntr; // "Still Same State" Counter (arbitrary | |
unsigned long minlengthHI; // Minimum Hi pulse length in us | |
unsigned long maxlengthHI; // Maximum Hi pulse length in us | |
unsigned long minlengthLOW; // Minimum Lo pulse length in us | |
unsigned long maxlengthLOW; // Maximum Lo pulse length in us | |
unsigned long pulseLen; // pulse length in us | |
unsigned long startTime; // Start Time of pulse in us | |
unsigned long endTime; // End Time of pulse in us | |
unsigned long unitlen; // lowest pulse length in us (assumed L.C.Denominator) | |
//********************************************************************************************* | |
void setup() { | |
//********************************************************************************************* | |
pinMode(rxPin, INPUT); // initialize input pin used for input signal | |
Serial.begin(57600); // Set up Serial baud rate | |
pinstate = 0; // prepare stored version of pin state to start as "low" | |
startTime = micros(); // Store first "Start time" | |
same_cntr = 0; // initialise | |
stateCount = 0; // initialise | |
minlengthHI = 9999; // initialise | |
maxlengthHI = 0; // initialise | |
minlengthLOW = 9999; // initialise | |
maxlengthLOW = 0; // initialise | |
} | |
//********************************************************************************************* | |
void loop() { | |
//********************************************************************************************* | |
// If no state change, then increment same_cntr | |
if (pinstate == digitalRead(rxPin)) { | |
same_cntr++; | |
} | |
else | |
{ | |
endTime = micros(); //Record the end time of the read period. | |
pinstate = !pinstate; | |
// If there has been a input state change, then use "same_cntr" | |
// to arbitrarily check if pulse length is acceptable | |
if (same_cntr < 10 || same_cntr > 10000 ) { | |
// if you are here, then pulse length is either too short or too long, so reset variables | |
startTime = endTime; | |
same_cntr = 0; | |
stateCount = 0; | |
minlengthHI = 9999; | |
maxlengthHI = 0; | |
minlengthLOW = 9999; | |
maxlengthLOW = 0; | |
} | |
else | |
{ | |
// if you are here, then there has been a state change and pulse length is OK | |
pulseLen = endTime - startTime; // Calculate Pulse length in us | |
startTime = endTime; // Remember start time for next state change | |
same_cntr = 0; // Initialise "Same State" counter | |
T_array[stateCount] = pulseLen; // Store Pulse Length | |
// Remember the max/min time extremes for each state | |
if (pinstate == false) { | |
if (pulseLen > maxlengthHI) { maxlengthHI = pulseLen; }; | |
if (pulseLen < minlengthHI) { minlengthHI = pulseLen; } | |
} else { | |
if (pulseLen > maxlengthLOW) { maxlengthLOW = pulseLen; }; | |
if (pulseLen < minlengthLOW) { minlengthLOW = pulseLen; }; | |
} | |
// Keep storing data up to "maxState" times | |
if (stateCount < maxState) { | |
stateCount++; | |
} else { | |
//******************************************************************************** | |
// If you are here, then we have reached the "MaxState" number of time lengths, | |
// so now we interpret the array data to determine where the repeating | |
// patterns are, so that we can output the "code" to serial before trying again | |
//******************************************************************************** | |
stateCount = 0; | |
// First, we detect the first 4 longest LOW states | |
low1 = 0; | |
low2 = 0; | |
low3 = 0; | |
low4 = 0; | |
for(i=0; i<maxState; i=i+1){ | |
if ( T_array[i] > ( maxlengthLOW * .80 ) ) | |
{ | |
if ( low1 == 0 ) { | |
low1 = i; | |
} else { | |
if ( low2 == 0 ) { | |
low2 = i; | |
} else { | |
if ( low3 == 0 ) { | |
low3 = i; | |
} else { | |
if ( low4 == 0 ) { | |
low4 = i; | |
} | |
}; | |
}; | |
}; | |
}; | |
}; | |
// Now we check if the 3 latest pulse trains between the LOW states | |
// have the same number of state changes. | |
// If they agree, then output the data | |
// N.B. the first pulse train could be unreliable so it is ignored. | |
if ( ( ( low2 - low1 ) == ( low4 - low3 ) ) | |
&& ( ( low3 - low2 ) == ( low4 - low3 ) ) | |
&& ( low1 > 0 ) | |
&& ( low2 > 0 ) | |
&& ( low3 > 0 ) | |
&& ( low4 > 0 ) ) { | |
// Re-examine pulse widths for our selected pulse train | |
// N.B. We start from 3rd pulse train because it is hoped it is the most reliable | |
minlengthHI = 9999; | |
maxlengthHI = 0; | |
minlengthLOW = 9999; | |
maxlengthLOW = 0; | |
for(i=low3+1; i<low4+1; i=i+1){ | |
if ( ( ( i - low3 ) % 2) == 0 ) { | |
if (T_array[i] > maxlengthLOW) { maxlengthLOW = T_array[i]; }; | |
if (T_array[i] < minlengthLOW) { minlengthLOW = T_array[i]; }; | |
} else { | |
if (T_array[i] > maxlengthHI) { maxlengthHI = T_array[i]; }; | |
if (T_array[i] < minlengthHI) { minlengthHI = T_array[i]; } | |
}; | |
// if ( ( ( j - low3 ) >= 0 ) && ( j <= ( low4 - 2 ) ) ) { | |
// Serial.print(T_array[j]); | |
// Serial.print(", "); | |
// }; | |
}; | |
// Calculate unit length of pulses | |
unitlen = 0; | |
if ( minlengthLOW < ( minlengthHI / 2 )) { | |
unitlen = minlengthLOW ; | |
} else { | |
unitlen = ( ( minlengthHI + minlengthLOW ) / 2 ); | |
}; | |
// Output deciphered data for TX sketch | |
Serial.print("int codez[] = {35,"); | |
Serial.print( ( low4 - low3 ) / 2 ); | |
Serial.print(","); | |
Serial.print(unitlen); | |
for(i=low3+1; i<low4+1; i=i+1){ | |
Serial.print(","); | |
// Serial.print( (T_array[i] / unitlen) ); | |
Serial.print( ( (T_array[i] * 10) + (5 * unitlen) ) / (10 * unitlen) ); | |
}; | |
Serial.println("};"); | |
}; | |
// Output deciphered data as HnLn | |
// Serial.print("Pulses = "); | |
// Serial.print( ( low4 - low3 ) / 2 ); | |
// Serial.print(", Unit length = "); | |
// Serial.print(unitlen); | |
// Serial.print(", Code = "); | |
// for(i=low3+1; i<low4+1; i=i+1){ | |
// if ( ( ( i - low3 ) % 2) == 0 ) { | |
// Serial.print("L"); | |
// Serial.print( ( (T_array[i] * 10) + (5 * unitlen) ) / (10 * unitlen) ); | |
// Serial.print(", "); | |
// } else { | |
// Serial.print("H"); | |
// Serial.print( ( (T_array[i] * 10) + (5 * unitlen) ) / (10 * unitlen) ); | |
// }; | |
// }; | |
// Serial.println(" "); | |
// }; | |
// Reset "extreme" variables | |
minlengthHI = 99999; | |
maxlengthHI = 0; | |
minlengthLOW = 99999; | |
maxlengthLOW = 0; | |
}; | |
//******************************************* | |
// The above is part of the decipering code * | |
//******************************************* | |
}; | |
}; | |
} |
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
/* | |
sketch : sniffer_433_TX (sister of "sniffer_433_RX") | |
Author : Peter Matthews (CurlyWurly) May 2017 | |
Desc : Copy the "int codez[]=.." line manufactured by the sister sketch "sniffer_433_RX" | |
and paste it into this sketch so that this sketch can spoof the original transmitter. | |
INFORMATION | |
N.B. Connect pin 3 (txpin) to the TX module input | |
N.B. Copy the output "int codez[] = ...." from the "Sniffer_433_RX" sketch and paste where marked below | |
N.B. The sniffer sketch just outputs a set value of 35 in code[0]. This means that you may have to | |
experiment using a different "repeat" value (usually a value of 15 - 45 is OK) | |
N.B. The code structure is contained from code[0] to code[n] and is defined as: | |
code[0] - No. of times to repeat the code | |
code[1] - No. of pulses (Hi/low combination) - This means it is half the total number of Hi and Low states | |
code[2] - Wait unit time (Hi and Low states are constructed with multiples of this) | |
code[3] - First HIGH state multiplier - multiply with code[2] | |
code[4] - First LOW state multiplier - multiply with code[2] | |
.... | |
code[n] - last LOW state multiplier | |
The first pulse is made up of code[3] and code[4] | |
and the second pulse is made up of code[5] and code[6] | |
*/ | |
#define ldPin 13 //Onboard LED = digital pin 13 | |
#define txPin 3 //Output to RF TX module | |
//*********************** Copy the output from the "Sniffer_433_RX" sketch here ************************** | |
// int codez[] = | |
//**************************** and reference it in "loop()" as tx(codez); ******************************** | |
// Maplin mains switch 1,1 ON | |
int code1[] = {10,25,434,1,3,1,3,1,3,3,1,1,3,3,1,1,3,3,1,1,3,1,3,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,31}; | |
// Maplin mains switch 1,1 OFF | |
int code2[] = {10,25,432,1,3,1,3,1,3,3,1,1,3,3,1,1,3,3,1,1,3,1,3,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,3,1,1,3,1,3,1,31}; | |
// 1byOne driveway alarm | |
int code3[] = {41,18,362,1,3,1,3,1,1,3,1,3,1,3,3,1,1,3,1,3,3,1,1,3,3,1,3,1,1,3,1,3,1,3,1,3,1,3,18}; | |
// Friedland PIR alarm | |
int code4[] = {15,21,754,1,1,1,1,1,1,1,4,1,5,1,4,1,4,1,5,1,6,1,4,1,7,1,4,1,7,1,3,1,5,1,5,1,5,1,5,1,4,1,5,1,27}; | |
void tx(int code); | |
//************************************************************ | |
void setup() { | |
//************************************************************ | |
pinMode(ldPin, OUTPUT); | |
pinMode(txPin, OUTPUT); | |
Serial.begin(57600); // Set up Serial baud rate | |
} | |
//************************************************************ | |
void loop() { | |
//************************************************************ | |
tx(code1); | |
delay(2000); | |
tx(code2); | |
delay(2000); | |
tx(code3); | |
delay(2000); | |
tx(code4); | |
delay(2000); | |
} | |
//************************************************************ | |
void tx(int code[]){ | |
//************************************************************ | |
digitalWrite(ldPin, HIGH); // LED pin on | |
for(int j=0; j<code[0]; j=j+1 ){ | |
for(int i=3; i<((code[1]*2)+3); i=i+1 ){ | |
if ( ( ( i ) % 2) == 0 ) { | |
digitalWrite(txPin, LOW); | |
} else { | |
digitalWrite(txPin, HIGH); | |
}; | |
for(int k=0; k<code[i]; k=k+1){ | |
delayMicroseconds(code[2]); | |
}; | |
}; | |
}; | |
digitalWrite(ldPin, LOW); // LED pin off | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment