/* *******************************************************************************
* Comunicacion Serial Mediante Frecuencia con Modulos RF ASK
*
* Este es un ejemplo de una comunicacion inalambrica con modulos ASK 315/433MHZ
* de bajo costo. Se muestra un ejemplo sencillo de protocolo de comunicacion
* que incluye direccionamiento, sincronizacion y comprobacion de errores para
* una comunicacion mas confiable con estos modulos. Este ejemplo es meramente
* didactico y contiene solamente la funcionalidad basica para demostracion.
*
* Hardware TX: Arduino Uno, Transmisor RF 315/433MHz ASK generico
* Hardware RX: Arduino Uno, Receptor RF 315/433MHz ASK generico
* Funciones: Software ejemplo para la implementacion de un protocolo (TX/RX)
* Version: 0.1 (18 de Noviembre de 2013)
* *
* Descargado de www.TecBolivia.com - Ingresa al sitio para más ejemplos similares.
* *******************************************************************************
* IMPORTANTE: Para programar los Arduinos deben desconectar cualquier cable
* conectado a los pines Tx y Rx en la placa Arduino, de otro modo la programación
* podría fallar.
**********************************************************************************/
// La tasa maxima de transmision de estos modulos es de 2400 y hasta 4800 en
// algunos casos, sin embargo, a mayor tasa de transmision el rango para una
// comunicacion confiable sin errores disminuye. Para lograr mayores distancias
// usar tasas menores o iguales a 1200 baudios */
#define BAUD_RATE 1200 // Tasa de transmision
// Definicion de bytes para el protocolo
#define BYTE_SINC 0xAA // Byte de sincronia
#define BYTE_INICIO 0x7E // Byte delimitador de inicio
#define BYTE_DIR_RX 0x11 // Dirección asignada al nodo receptor
#define TAM_TRAMA 4 // Cantidad de bytes en una trama
// Definicion de entradas/salidas
#define LED_ACTIVIDAD 8 // LED indicador de recepcion
#define LED_ACTUADOR 4 // LED que indica la activacion de un actuador
/* Declaracion de funciones */
void Recibir(); //Funcion de recepcion serial
void Parpadear( int veces, int periodo); // Funcion para parpadear un LED
unsigned char estado_led = 0;
void setup(void)
{
/* Inicializar puertos digitales */
pinMode(LED_ACTIVIDAD, OUTPUT);
pinMode(LED_ACTUADOR, OUTPUT);
/*Inicializar comunicacion serial */
Serial.begin(BAUD_RATE);
/* Parpadeo de inicio */
Parpadear(2, 1000);
}
/* Funcion principal del programa */
void loop(void)
{
Recibir(); // Funcion de recepcion
}
/*******************************************************************************
* RECIBIR
*
* Descripción : Recibe una trama completa del protocolo. Esta funcion ira
* leyendo uno a uno los bytes del buffer circular hasta
* encontrar un delimitador de inicio para luego procesar toda
* la trama que sigue. Los bytes de sincronia son ignorados.
* Argumentos : Ninguno
* Retorna : Nada
* Notas :
********************************************************************************/
void Recibir()
{
// Variables para almacenamiento de bytes de la trama
static unsigned char dir, dato;
// Ejecutar solo si se recibieron la cantidad minima de caracteres por trama
if (Serial.available() >= TAM_TRAMA)
{
// Buscar un byte de inicio, si se lo encuentra procesar los bytes
// siguientes (son parte de la trama)
if (Serial.read() == BYTE_INICIO)
{
dir = Serial.read(); // Leer el byte de direccion
// Verificar que la trama este dirigida a nosotros
if (dir == BYTE_DIR_RX)
{
dato = Serial.read(); // Leer el byte de datos
if (Serial.read() == (dir + dato)) // Verificar el checksum
{
/* En este punto podemos estar seguros que la informacion no
contiene errores */
// Cambiar estado LED de actividad para visualizacion externa
if(estado_led)
digitalWrite(LED_ACTIVIDAD, HIGH);
else
digitalWrite(LED_ACTIVIDAD, LOW);
estado_led = ~estado_led;
/* Aplicar el bit correspondiente recibido en los datos
para activar/desactivar el actuador.
En este ejemplo solo estamos usando el bit 0 pero se
podrian usar mas bits */
digitalWrite(LED_ACTUADOR, (dato & 0b00000001));
// Para usar más bits recibidos para el control de
// actuadores:
// digitalWrite(LED_ACTUADOR_1, ( (dato >> 1) & 0b00000001) );
// digitalWrite(LED_ACTUADOR_2, ( (dato >> 2) & 0b00000001) );
// digitalWrite(LED_ACTUADOR_3, ( (dato >> 3) & 0b00000001) );
// ... y asi sucesivamente
}
}
}
}
}
/*******************************************************************************
* PARPADEAR
*
* Descripción : Parpadea un LED
* Argumentos : int veces: cantidad de parpadeos
* int periodo: periodo del parpadeo
* Retorna : Nada
* Notas :
********************************************************************************/
void Parpadear( int veces, int periodo) {
for (int i = 0; i < veces; i++) {
digitalWrite(LED_ACTIVIDAD, HIGH);
delay(periodo >> 2);
digitalWrite(LED_ACTIVIDAD, LOW);
delay(periodo >> 2);
}
}
Transmitter
/* *******************************************************************************
* Comunicacion Serial Mediante Frecuencia con Modulos RF ASK
*
* Este es un ejemplo de una comunicacion inalambrica con modulos ASK 315/433MHZ
* de bajo costo. Se muestra un ejemplo sencillo de protocolo de comunicacion
* que incluye direccionamiento, sincronizacion y comprobacion de errores para
* una comunicacion mas confiable con estos modulos. Este ejemplo es meramente
* didactico y contiene solamente la funcionalidad basica para demostracion.
*
* Hardware TX: Arduino Uno, Transmisor RF 315/433MHz ASK generico
* Hardware RX: Arduino Uno, Receptor RF 315/433MHz ASK generico
* Funciones: Software ejemplo para la implementacion de un protocolo (TX/RX)
* Version: 0.1 (18 de Noviembre de 2013)
*
* Descargado de www.TecBolivia.com - Ingresa al sitio para más ejemplos similares.
* *******************************************************************************
* IMPORTANTE: Para programar los Arduinos deben desconectar cualquier cable
* conectado a los pines Tx y Rx en la placa Arduino, de otro modo la programación
* podría fallar.
**********************************************************************************/
// La tasa maxima de transmision de estos modulos es de 2400 y hasta 4800 en
// algunos casos, sin embargo, a mayor tasa de transmision el rango para una
// comunicacion confiable sin errores disminuye. Para lograr mayores distancias
// usar tasas menores o iguales a 1200 baudios */
#define BAUD_RATE 1200 // Tasa de transmision
// Definicion de bytes para el protocolo
#define BYTE_SINC 0xAA // Byte de sincronia
#define BYTE_INICIO 0x7E // Byte delimitador de inicio
#define BYTE_DIR_RX 0x11 // Dirección asignada al nodo receptor
#define TAM_TRAMA 4 // Cantidad de bytes en una trama
// Definicion de entradas/salidas
#define LED_ACTIVIDAD 13 // Pin de salida para LED de actividad
#define PIN_SENSOR 4 // Pin de entrada para sensor digital
/* Declaracion de funciones */
void Transmitir(); //Funcion de transmisión serial
void Parpadear( int veces, int periodo); // Funcion para parpadear un LED
// Funcion para simular un oscilador 555 para prueba de los modulos TX y RX
// Usado solo para pruebas y depuracion:
void Oscilador_555(void);
/* Funcion principal del programa */
void setup(void)
{
/* Inicializar puertos digitales */
pinMode(LED_ACTIVIDAD, OUTPUT);
pinMode(PIN_SENSOR, INPUT);
/*Inicializar comunicacion serial */
Serial.begin(BAUD_RATE);
/* Parpadeo de inicio */
Parpadear(2, 1000);
}
/* Funcion principal del programa */
void loop(void)
{
/* Con la ejecucion de la siguiente funcion las transmisiones se realizan
de forma ininterrumpida a alta velocidad. Si alguna trama no es recibida
correctamente, esta será reemplazada casi inmediatamente por otra
siguiente */
Transmitir(); // Funcion de transmision
/* En caso de hacer transmisiones cortas con pausas largas se ha visto
* que el receptor a veces no responde a la transmision de una sola
* trama aislada debido posiblemente a las limitaciones de su diseño que
* es bastante susceptible al ruido. En estos casos, hacer dos envios
* consecutivos antes de un retardo largo generalmente soluciona el
* problema. Habilitar las dos lineas siguientes adicionalmente para
* hacer transmisiones cada 250 milisegundos: */
Transmitir();
delay(250);
}
/*******************************************************************************
* TRANSMITIR
*
* Descripción : Transmite una trama completa del protocolo
* Argumentos : Ninguno
* Retorna : Nada
* Notas :
********************************************************************************/
void Transmitir()
{
unsigned char dato_tx = 0x00; // Variable auxiliar para el byte a transmitirse
/* Enviar 8 bits. En este ejemplo solo estamos usando el bit 0 (PIN_SENSOR)
para activar remotamente un actuador pero se podrian enviar mas bits */
dato_tx = dato_tx | digitalRead(PIN_SENSOR);
// Para incluir más sensores de entrada en el byte enviado:
// dato_tx = dato_tx | (digitalRead(PIN_SENSOR_1) << 1);
// dato_tx = dato_tx | (digitalRead(PIN_SENSOR_2) << 2);
// dato_tx = dato_tx | (digitalRead(PIN_SENSOR_3) << 3);
// ... y asi sucesivamente
/* Enviar los bytes de la trama, uno a uno, por el puerto serial */
Serial.write(BYTE_SINC); // Enviar el byte de sincronia
/* Si hay problemas en la recepcion, podria ayudar enviar algunos bytes de
* sincronia adicionales. El codigo del receptor ignora cualquier byte
* adicional de sincronia. Habilitar lo siguiente en caso de errores en la
* recepcion:*/
// Serial.write(BYTE_SINC);
// Serial.write(BYTE_SINC);
// Serial.write(BYTE_SINC);
Serial.write(BYTE_INICIO); // Enviar el byte delimitador de inicio
Serial.write(BYTE_DIR_RX); // Mandar la direccion del receptor
Serial.write(dato_tx); // Mandar el byte de dato
Serial.write(BYTE_DIR_RX + dato_tx); // Calcular y mandar el checksum (direccion + datos)
}
/*******************************************************************************
* PARPADEAR
*
* Descripción : Parpadea un LED
* Argumentos : int veces: cantidad de parpadeos
* int periodo: periodo del parpadeo
* Retorna : Nada
* Notas :
********************************************************************************/
void Parpadear( int veces, int periodo) {
for (int i = 0; i < veces; i++) {
digitalWrite(LED_ACTIVIDAD, HIGH);
delay(periodo >> 2);
digitalWrite(LED_ACTIVIDAD, LOW);
delay(periodo >> 2);
}
}
/*******************************************************************************
* OSCILADOR 555
*
* Descripción : Simula una oscilacion biestable con 555 para la prueba de
* basica del funcionamiento de los modulos ASK. Se puede
* alimentar la salida de LED_ACTIVIDAD a la entrada del TX
* para mandar una señal binaria oscilante de baja frecuencia.
* La salida del RX debe conectarse a un LED para visualizacion
* Argumentos : Ninguno
* Retorna : Nada
* Notas :
********************************************************************************/
void Oscilador_555(void)
{
#define TIME 400
digitalWrite(LED_ACTIVIDAD, HIGH);
delay(TIME);
digitalWrite(LED_ACTIVIDAD, LOW);
delay(TIME);
}
No comments:
Post a Comment