add rf433mhz component to extras, for using antenna modules with esp
This commit is contained in:
parent
a721fb0bc7
commit
01e9c1b98e
7 changed files with 359 additions and 0 deletions
4
examples/rf433mhz/Makefile
Normal file
4
examples/rf433mhz/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
PROGRAM = rf-send-recieve
|
||||
EXTRA_COMPONENTS = extras/rf433mhz
|
||||
include ../../common.mk
|
||||
|
88
examples/rf433mhz/rf-send-recieve.c
Normal file
88
examples/rf433mhz/rf-send-recieve.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
//esp sdk
|
||||
#include "espressif/esp_common.h"
|
||||
#include "esp/uart.h"
|
||||
|
||||
//rtos
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "queue.h"
|
||||
|
||||
//rf 433mhz
|
||||
#include <rf433mhz/rf_433mhz.h>
|
||||
|
||||
#define TRANSMITTER_PIN 5
|
||||
#define RECIEVER_PIN 4
|
||||
|
||||
reciever_433mhz* reciever;
|
||||
QueueHandle_t decode_queue;
|
||||
|
||||
void rf433mhz_transmit(void *pvParameters) {
|
||||
gpio_enable(TRANSMITTER_PIN, GPIO_OUTPUT);
|
||||
message_433mhz msg;
|
||||
msg.code_lenght=24;
|
||||
msg.repeat=2;
|
||||
msg.pulse_length = 312;
|
||||
protocol_433mhz proto = protocols_433mhz[PROTO1];
|
||||
msg.protocol = &proto;
|
||||
|
||||
while(true) {
|
||||
msg.data=1364;
|
||||
send_message_433mhz(TRANSMITTER_PIN, &msg);
|
||||
vTaskDelay(1000);
|
||||
msg.data=1361;
|
||||
send_message_433mhz(TRANSMITTER_PIN, &msg);
|
||||
vTaskDelay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void recieve_interrupt_handler(uint8_t gpio_num) {
|
||||
BaseType_t xHigerPriorityTaskTriggerd = pdFALSE;
|
||||
UBaseType_t uxSavedInterruptStatus;
|
||||
uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR();
|
||||
recieve_on_interrupt(reciever);
|
||||
if (reciever->repeatCount < 2) {
|
||||
taskEXIT_CRITICAL_FROM_ISR(uxSavedInterruptStatus);
|
||||
return;
|
||||
}
|
||||
//printf("Function recieve_interrupt_handler recieved going enter critical \n");
|
||||
reciever_433mhz* old_reciever = reciever;
|
||||
reciever = create_reciever_buffer();
|
||||
taskEXIT_CRITICAL_FROM_ISR(uxSavedInterruptStatus);
|
||||
xQueueSendFromISR(decode_queue, &old_reciever, &xHigerPriorityTaskTriggerd);
|
||||
}
|
||||
|
||||
void rf433mhz_recieve(void *pvParameters) {
|
||||
//enable reception on recieve pin
|
||||
gpio_enable(RECIEVER_PIN, GPIO_INPUT);
|
||||
reciever = create_reciever_buffer();
|
||||
gpio_set_interrupt(RECIEVER_PIN, GPIO_INTTYPE_EDGE_ANY, recieve_interrupt_handler);
|
||||
|
||||
reciever_433mhz* recv;
|
||||
message_433mhz msg;
|
||||
while(1) {
|
||||
if(xQueueReceive(decode_queue, &recv, 0) == pdTRUE){
|
||||
//try to decode recieved data
|
||||
bool recieved = false;
|
||||
for(int i=0; i < PROTOCOL_COUNT ; i++) {
|
||||
if(decode_recieved(recv, &protocols_433mhz[i], &msg)) {
|
||||
recieved = true;
|
||||
printf("Recieved message with data: %d\n", msg.data);
|
||||
break;
|
||||
}
|
||||
//no protcol found to decode data
|
||||
}
|
||||
free(recv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void user_init(void) {
|
||||
uart_set_baud(0, 115200);
|
||||
|
||||
decode_queue = xQueueCreate(2, sizeof(reciever_433mhz*));
|
||||
|
||||
//start tasks
|
||||
xTaskCreate(rf433mhz_transmit, "transmitter_rf", 256, NULL, 1, NULL);
|
||||
xTaskCreate(rf433mhz_recieve, "reciever_rf", 256, NULL, 1, NULL);
|
||||
|
||||
}
|
35
extras/rf433mhz/README.md
Normal file
35
extras/rf433mhz/README.md
Normal file
|
@ -0,0 +1,35 @@
|
|||
rf433hmz - A Copyright (c) 2018 Felix Richter <judge@felixrichter.tech>
|
||||
|
||||
# About
|
||||
|
||||
This is a simple c library which implements encoding and decoding of various rf protocols for sending and recieving rf transmissions.
|
||||
It is heavly based on the RC Switch library. It is designed to be used with the esp8266 using open rtos, but it should be very easy to port
|
||||
to other platforms.
|
||||
|
||||
# Issues
|
||||
|
||||
If you find any bugs, please report them at: https://github.com/Felix5721/rf433mhz
|
||||
|
||||
# License
|
||||
|
||||
rf433hmz is published under the MIT license.
|
||||
|
||||
Copyright © 2018 Felix Richter <judge@felixrichter.tech>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
9
extras/rf433mhz/component.mk
Normal file
9
extras/rf433mhz/component.mk
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Component makefile for extras/rf433mhz
|
||||
|
||||
# expected anyone using this driver includes it as 'rf433mhz/rf_433mhz.h'
|
||||
INC_DIRS += $(rf433mhz_ROOT)..
|
||||
|
||||
# args for passing into compile rule generation
|
||||
rf433mhz_SRC_DIR = $(rf433mhz_ROOT)
|
||||
|
||||
$(eval $(call component_compile_rules,rf433mhz))
|
126
extras/rf433mhz/rf_433mhz.c
Normal file
126
extras/rf433mhz/rf_433mhz.c
Normal file
|
@ -0,0 +1,126 @@
|
|||
#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;
|
||||
}
|
66
extras/rf433mhz/rf_433mhz.h
Normal file
66
extras/rf433mhz/rf_433mhz.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
#ifndef rf_h_INCLUDED
|
||||
#define rf_h_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define RECIEVE_MAX_BUFFER_LEN 67
|
||||
#define SEPERATION_LIMIT_433MHZ 5000
|
||||
#define RECIEVE_TOLERANCE_433MHZ 60
|
||||
|
||||
/*
|
||||
* This is a pure c reimplemnation of the rc swich library, it was build to be used with open rtos
|
||||
* Copyright: Felix Richter 2018
|
||||
*/
|
||||
|
||||
|
||||
typedef struct{
|
||||
uint8_t high_time;
|
||||
uint8_t low_time;
|
||||
} pulse_t;
|
||||
|
||||
typedef struct{
|
||||
pulse_t sync;
|
||||
pulse_t zero;
|
||||
pulse_t one;
|
||||
bool inverted;
|
||||
} protocol_433mhz;
|
||||
|
||||
typedef struct{
|
||||
uint32_t data;
|
||||
unsigned int code_lenght;
|
||||
protocol_433mhz* protocol;
|
||||
uint16_t pulse_length;
|
||||
uint8_t repeat;
|
||||
} message_433mhz;
|
||||
|
||||
typedef struct{
|
||||
uint16_t recieve_len;
|
||||
unsigned long last_time;
|
||||
unsigned int changeCount;
|
||||
unsigned int repeatCount;
|
||||
unsigned int seperation_limit;
|
||||
unsigned int recieve_tolerance;
|
||||
unsigned int timeings[RECIEVE_MAX_BUFFER_LEN];
|
||||
} reciever_433mhz;
|
||||
|
||||
void send_message_433mhz(uint8_t pin, message_433mhz* msg);
|
||||
void recieve_on_interrupt(reciever_433mhz* reciever);
|
||||
bool decode_recieved(reciever_433mhz* reciever, protocol_433mhz* proto, message_433mhz* msg);
|
||||
reciever_433mhz* create_reciever_buffer();
|
||||
|
||||
extern protocol_433mhz protocols_433mhz[];
|
||||
|
||||
typedef enum {
|
||||
PROTO1,
|
||||
PROTO2,
|
||||
PROTO3,
|
||||
PROTO4,
|
||||
PROTO5,
|
||||
PROTO6,
|
||||
PROTO7,
|
||||
PROTOCOL_COUNT
|
||||
} protocol_name_433mhz;
|
||||
|
||||
#endif // rf_h_INCLUDED
|
||||
|
31
extras/rf433mhz/util.h
Normal file
31
extras/rf433mhz/util.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#ifndef util_h_INCLUDED
|
||||
#define util_h_INCLUDED
|
||||
|
||||
#include "espressif/esp_common.h"
|
||||
#include "espressif/esp_misc.h"
|
||||
#include "esp8266.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
void delayMicroSec(uint16_t us) {
|
||||
sdk_os_delay_us(us);
|
||||
}
|
||||
|
||||
void setPinDigital(uint8_t pin, bool value) {
|
||||
gpio_write(pin, value);
|
||||
}
|
||||
|
||||
unsigned long getMicroSec() {
|
||||
return sdk_system_get_time();
|
||||
}
|
||||
|
||||
void disableInterrupts() {
|
||||
taskENTER_CRITICAL();
|
||||
}
|
||||
|
||||
void enableInterrupts() {
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
|
||||
#endif // util_h_INCLUDED
|
||||
|
Loading…
Reference in a new issue