Mostrando entradas con la etiqueta Radio Frecuencia. Mostrar todas las entradas
Mostrando entradas con la etiqueta Radio Frecuencia. Mostrar todas las entradas

jueves, 6 de octubre de 2016

nRF24L01 para Arduino (AVR), ejemplo con structs

En el último post de esta serie de publicaciones con respecto al módulo de RF nRF24L01, hemos transmitido un simple entero desde un Arduino Nano a un Arduino Mega2560. 

En este caso veremos un pequeño ejemplo, que permitirá transmitir un struct, que estará conformado por 
  • ID del paquete
  • Cantidad de milisegundos en el que fue enviado el paquete.
El paquete saldrá del Arduino Nano, llegará al Mega el cual simplemente lo recibe, lo imprime en consola por medio del protocolo UART y luego lo reenvía. por su lado el Arduino Nano, se queda esperando un determinado lapso de tiempo. Cuando recibe el paquete que envió calcula la diferencia de milisegundos y la imprime en consola (UART).

La estructura del ejemplo es muy parecida a la del post anterior (sería conveniente volverlo a mirar). Desde el lado del transmisor usamos el struct siguiente:

1:  struct Data_struct {  
2:       uint8_t id;  
3:       uint64_t timing;  
4:  } data_to_send, data_responce;  


Se usará data_to_send para el struct que se envía; y se usa data_responce para el mensaje que se recibe. Se podría usar el mismo y optimizar el código pero opté por mantenerlo simple (y no tan eficiente).
Por el lado del receptor el struct es el siguiente:

1:  struct Data_struct {  
2:       uint8_t id;  
3:       uint64_t timing;  
4:  } data_to_read;  

Envío de datos

Para envíar el dato, primero conformamos el struct. asignamos un ID y llamamos  a la función millis():

1:  data_to_send.id = i;  
2:  data_to_send.timing = millis();  
3:  i++;  
4:  /*Go to TX_MODE*/  
5:  TX_MODE(&data_to_send);  
6:  /*Sending data*/  

Espero mientras se termina el proceso de envío y luego paso al modo de recepción:

1:  /*Wait for transmission end*/  
2:  while(nrf24_isSending());  
3:  RX_MODE(); /*Go to RX MODE*/

La variable lastTiming la utilizo para almacenar el instante en el que envío el paquete (Nota: no es lo más eficiente. Solo es una prueba.)

Si recibo el dato, calculo el tiempo que demora y lo imprimo en pantalla.

Si pasa más de 10000 ms imprimo un mensaje de error, de no llegada de paquetes.


1:     lastTiming = millis();  
2:            do{  
3:                 if(rf_data_ready())  
4:                      {  
5:                           rf_get_data(&data_responce);  
6:                           put_string("\nData recieve correctly\n");  
7:                           put_int(data_responce.id);  
8:                           put_string("\n");  
9:                           put_string("El mensaje tardo: ");  
10:                           put_long(millis() - data_responce.timing);  
11:                           break;  
12:                      }  
13:            }while((lastTiming - temp) < 10000);  
14:            if((lastTiming - temp) > 1000){  
15:                 put_string("\nSending Fails\n");  
16:            }  

Recepción de datos

Para la recepión de datos (en el Arduino Mega2560) simplemente se reciben los paquetes, los imprimo en pantalla y luego se los reenvía, sin realizar ninguna modificación.

1:  if(rf_data_ready())  
2:            {  
3:                 rf_get_data(&data_to_read);  
4:                 put_int(data_to_read.id);  
5:                 put_string("\n");  
6:                 put_long(data_to_read.timing);  
7:                 put_string("\n");  
8:                 TX_MODE(&data_to_read);  
9:                 /*Wait for transmission end*/  
10:                 while(nrf24_isSending());  
11:                 RX_MODE();  
12:            }  


Resultados

El resultado de la ejecución se la ve en la siguiente imágen:


El código del receptor se lo puede encontrar aquí.
El código del transmisor se lo puede encontrar aquí.
 

jueves, 29 de septiembre de 2016

Driver nRF24L01 para arduino

En el post anterior vimos como conectar correctamente los pines del nRF24L01 y los Arduinos Nanos y Mega2560. La conexión de los pines pueden variar dependiendo de la configuración del driver. Pero la que usé en mi ejemplo, es casi como un "estándar", ya que ví varios ejemplos de otros desarrolladores, que lo configuraban como yo.

Vamos a ver las partes más importantes del driver.

En primer lugar en el archivo nRF24L01_RegisterMap.h se encuentra la declaración de los registros del módulo.


Lo primero que se debe hacer, en el main es llamar a la función rf_init() para inicializar el módulo.

1:  //inizialize rf tx   
2:  rf_init();  

Está función hace lo siguiente:

Lo que hace es setear como salida los pines CE y CSN definidos en nRF24L01_RegisterMap.h. Luego pone en cero CE y en uno CSN

Paso siguiente se llama a la función rf_config() en el cual se pasa como parámetro el canal de transmisión más el ancho del payload. Esta función realiza una serie de configuraciones necesarias y básicas para poder funcionar. Y luego se setea en modo RX, para que el módulo se ponga a escuchar.


Es importante setear correctamente las direcciones. Para el transmisor se utiliza las sigiuentes direcciones:

1:  uint8_t tx_address[5] = {0xE7,0xE7,0xE7,0xE7,0xE7};/**<Dirección del transmisor*/  
2:  uint8_t rx_address[5] = {0xD7,0xD7,0xD7,0xD7,0xD7};/**<Dirección del receptorr*/  

En el caso del receptor las direcciones son las siguientes:

1:  /*define addr*/  
2:  uint8_t tx_address[5] = {0xD7,0xD7,0xD7,0xD7,0xD7};  
3:  uint8_t rx_address[5] = {0xE7,0xE7,0xE7,0xE7,0xE7};  

Para ello se utiliza las siguientes función:

1:  //set the device addr  
2:  set_rx_address(rx_address);  
3:  set_tx_address(tx_address);  

Notese que las direcciones están cruzadas.

Transmisor

El código del transmisor se muestra a continuación.


Receptor

El código del receptor se muestra quedó de la siguiente manera.



En post posteriores se moestrará más detalle del código del módulo. Y se buscará complejizar el código.

El código del transmisor se lo puede descargar de aquí. Mientras que al código del receptor se lo descarga desde aquí.

martes, 27 de septiembre de 2016

nRF24L01 usando arduino (AVR) II

En el post anterior di una muy breve introducción al módulo nRF24L01. En esta oportunidad daré un poco más de detalle sobre cómo conectar el módulo a los Arduinos.

Antes de continuar se debe indicar que este será usado en el desarrollo de un Drone (quadcopter) casero. El control remoto (Arduino Nano - atmega328p) y el drone en sí mismo (Arduino Mega - atmega2560) se comunicarán por radio frecuencia (RF), usando este módulo.

 

 Pines del nRF24L01+

El módulo tiene 8 pines. 
  1. GND
  2. VCC
  3. CE
  4. CSN
  5. CSK
  6. MOSI
  7. MISO
  8. IRQ

Pines nRF24L01+


VCC siempre tiene que conectarse a 3.3V.
 
La conexión al Arduino Nano es la siguiente:
GND   ->  GND
VCC    ->  3.3V
CE      ->  D9
CSN   ->  D10
SCK   ->  D13
MOSI ->  D11
MISO ->  D12
IRQ    ->  No usado


Arduino Nano + nRF24L01



 Por otro lado tenemos el Arduino Mega conectado de la siguiente manera:

GND   ->  GND
VCC    ->  3.3V
CE      ->  9
CSN   ->  53
SCK   ->  52
MOSI ->  51
MISO ->  50
IRQ    ->  No usado

Arduino Mega + nRF24L01

El código del Arduino Nano (transmisor) se lo puede descargar desde aquí.

El código del Arduino Mega (receptor) se lo puede descargar desde aquí.

En el siguiente post se explicará las principales partes del código.

lunes, 26 de septiembre de 2016

nRF24L01 usando arduino (AVR) I

El nRF24L01 es un tranceiver de 2.4Ghz con un protocolo embebido (Enhanced ShockBurst™). Este se suele utilizar en aplicaciones wireless de bajo consumo. En este caso será utilizado en la comunicación con un Drone.


Resultado de imagen para nrf24l01



Para controlar el chip se utiliza SPI (Serial Peripheral Interface). Los registros son accedidos mediante SPI.

El radio usa modulación GFSK. Este tranceptor tiene parámetros configurables como el canal de frecuencia, power de salida, air data rate (250kbps, 1Mbps, 2Mbps).

La idea de este pequeño proyecto es enviar datos desde un arduino Nano a un arduino Mega, mediante este tranceptor y utilizando el lenguaje C.

Se puede encontrar más información en el datasheet del módulo