126 lines
4.2 KiB
C
126 lines
4.2 KiB
C
#include "rf_433mhz.h"
|
|
#include "util.h"
|
|
|
|
protocol_433mhz protocols_433mhz[] = {
|
|
{ { 1, 31 }, { 1, 3 }, { 3, 1 }, false }, // protocol 1
|
|
{ { 1, 10 }, { 1, 2 }, { 2, 1 }, false }, // protocol 2
|
|
{ { 30, 71 }, { 4, 11 }, { 9, 6 }, false }, // protocol 3
|
|
{ { 1, 6 }, { 1, 3 }, { 3, 1 }, false }, // protocol 4
|
|
{ { 6, 14 }, { 1, 2 }, { 2, 1 }, false }, // protocol 5
|
|
{ { 23, 1 }, { 1, 2 }, { 2, 1 }, true }, // protocol 6 (HT6P20B)
|
|
{ { 2, 62 }, { 1, 6 }, { 6, 1 }, false } // protocol 7 (HS2303-PT, i. e. used in AUKEY Remote)
|
|
};
|
|
|
|
static inline unsigned int diff(int A, int B) {
|
|
return abs(A - B);
|
|
}
|
|
|
|
//Transmit single pulse meaning 1 or 0 or sync
|
|
void transmit(uint8_t pin, protocol_433mhz* proto, pulse_t pulse_params, uint16_t pulse_length) {
|
|
bool firstLogicLevel = proto->inverted ? 0 : 1;
|
|
bool secondLogicLevel = proto->inverted ? 1 : 0;
|
|
|
|
setPinDigital(pin, firstLogicLevel);
|
|
delayMicroSec(pulse_length * pulse_params.high_time);
|
|
setPinDigital(pin, secondLogicLevel);
|
|
delayMicroSec(pulse_length * pulse_params.low_time);
|
|
}
|
|
|
|
void send_message_433mhz(uint8_t pin, message_433mhz* msg) {
|
|
disableInterrupts();
|
|
for (uint8_t n_repeat=0; n_repeat < msg->repeat; n_repeat++) {
|
|
for(int i = msg->code_lenght-1; i>=0; i--) {
|
|
if ( msg->data & (1L << i) ) {
|
|
transmit(pin, msg->protocol, msg->protocol->one, msg->pulse_length);
|
|
} else {
|
|
transmit(pin, msg->protocol, msg->protocol->zero, msg->pulse_length);
|
|
}
|
|
}
|
|
transmit(pin, msg->protocol, msg->protocol->sync, msg->pulse_length);
|
|
}
|
|
//make sure antenna is powered off
|
|
setPinDigital(pin, 0);
|
|
enableInterrupts();
|
|
}
|
|
|
|
void recieve_on_interrupt(reciever_433mhz* reciever) {
|
|
long time = getMicroSec();
|
|
unsigned int duration = time - reciever->last_time;
|
|
|
|
if (duration > reciever->seperation_limit) {
|
|
//long stretch without change -> might be gap between transmittions
|
|
if ( diff(duration, reciever->timeings[0]) < 200 ) {
|
|
//this long singal is close in length to the previous recorded signals
|
|
reciever->repeatCount++;
|
|
return;
|
|
} else {
|
|
reciever->changeCount = 0;
|
|
}
|
|
}
|
|
|
|
if ( reciever->changeCount >= RECIEVE_MAX_BUFFER_LEN ) {
|
|
reciever->changeCount = 0;
|
|
reciever->repeatCount = 0;
|
|
}
|
|
|
|
reciever->timeings[reciever->changeCount++] = duration;
|
|
reciever->last_time = time;
|
|
}
|
|
|
|
bool decode_recieved(reciever_433mhz* reciever, protocol_433mhz* proto, message_433mhz* msg) {
|
|
msg->data = 0;
|
|
unsigned int sync_len = (proto->sync.low_time > proto->sync.high_time) ? proto->sync.low_time : proto->sync.high_time;
|
|
unsigned int delay = reciever->timeings[0]/sync_len;
|
|
unsigned int delay_tolerance = delay * reciever->recieve_tolerance /100;
|
|
/* For protocols that start low, the sync period looks like
|
|
* _________
|
|
* _____________| |XXXXXXXXXXXX|
|
|
*
|
|
* |--1st dur--|-2nd dur-|-Start data-|
|
|
*
|
|
* The 3rd saved duration starts the data.
|
|
*
|
|
* For protocols that start high, the sync period looks like
|
|
*
|
|
* ______________
|
|
* | |____________|XXXXXXXXXXXXX|
|
|
*
|
|
* |-filtered out-|--1st dur--|--Start data--|
|
|
*
|
|
* The 2nd saved duration starts the data
|
|
*/
|
|
unsigned int firstdata = proto->inverted ? 2 : 1;
|
|
for (unsigned int i = firstdata; i < reciever->changeCount-1; i+=2) {
|
|
msg->data <<= 1;
|
|
if ( diff(reciever->timeings[i], delay*proto->zero.high_time) < delay_tolerance &&
|
|
diff(reciever->timeings[i+1], delay*proto->zero.low_time) < delay_tolerance ){
|
|
//recieved zero
|
|
} else if ( diff(reciever->timeings[i], delay*proto->one.high_time) < delay_tolerance &&
|
|
diff(reciever->timeings[i+1], delay*proto->one.low_time) < delay_tolerance ) {
|
|
//recieved one
|
|
msg->data |= 1;
|
|
} else {
|
|
//Failed to decode data with given protocol
|
|
return false;
|
|
}
|
|
}
|
|
if (reciever->changeCount > 7) {
|
|
msg->code_lenght = (reciever->changeCount -1)/2;
|
|
msg->protocol = proto;
|
|
msg->pulse_length = delay;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
reciever_433mhz* create_reciever_buffer() {
|
|
reciever_433mhz* reciever = malloc(sizeof(reciever_433mhz));
|
|
reciever->recieve_tolerance = RECIEVE_TOLERANCE_433MHZ;
|
|
reciever->seperation_limit = SEPERATION_LIMIT_433MHZ;
|
|
reciever->changeCount = 0;
|
|
reciever->repeatCount = 0;
|
|
reciever->last_time = getMicroSec();
|
|
reciever->recieve_len = 0;
|
|
memset(&reciever->timeings, 0, RECIEVE_MAX_BUFFER_LEN);
|
|
return reciever;
|
|
}
|