Wednesday, 22 February 2017

Arduino Serial Communication using RF modules ASK Receptor (Receiver) and transmisor (Transmitter))

Receiver

 /* *******************************************************************************  
  * 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