Seguro que todos tenéis por el trastero alguna radio RC de algún dron chino que ha dejado de funcionar, o simplemente algún familiar os la ha regalado, porque como sois makers seguro que la podéis aprovechar… Pues estáis de suerte, en esta entrada vamos a ver como modificar y adaptar una radio RC, quitarle las tripas y dejar nuestro Arduino con el nRF24L01.

El hacernos nosotros mismos una radio RC con Arduino y nRF24L01 nos ofrece varias ventajas e inconvenientes que iremos viendo a lo largo de la entrada. Sin embargo, os puedo decir que para controlar pequeños robots caseros es más que suficiente. Además, en el transcurso del proyecto aprenderemos a manejar señales PWM, el ADC del Arduino y muchas otras cosas más!

El vídeo!

¿Cómo funciona un sistema de radiocontrol?

Generalmente todos los sistemas de radiocontrol funciona de manera muy parecida. Todos se basan en emitir una señal en radio frecuencia que contiene la información de las señales que se tienen que recibir.

Las radios antiguas emitían en VHF (alrededor de los 35Mhz) y la única forma de hacer que las señales no colisionaran en el aire (y así evitar las interferencias) era usando unos cristales de cuarzo. Estos se colocaban en la radio, para configurar analógicamente la frecuencia exacta de emisión, ya que con esa tecnología, si dos emisoras estaban emitiendo en la misma frecuencia, el receptor no sabría a que señal hacer caso y se producirían las temidas interferencias.

En la actualidad, se utilizan sobre todo señales en el rango de los 2.4Ghz, las mismas señales que usa el Wifi de tu casa. Además, por suerte, existen módulos muy baratos que nos permiten enviar y recibir señales en esta frecuencia. La ventaja de usar este rango de frecuencia es que los anchos de banda son mayores, y se pueden enviar más datos por segundo.

El módulo nRF24L01

El módulo del que os hablaba, que es capaz de transmitir datos en 2.4Ghz a precios muy asequibles (1.5€ por dos) es el nRF24l01. A lo largo de este post vamos a usar dos módulos para hacer la comunicación entre la radio RC y el receptor. De este módulo, existen dos variantes, la primera, que funciona con una antena puesta en la PCB; y otra con más potencia para enlaces más distantes.

Foto del nRF24l01

Módulo nRF24l01

Además, al ser muy conocido, tiene disponibles librerías para el IDE de Arduino, por lo que las primeras pruebas y prototipos se pueden hacer muy fácilmente.

La radio RC con Arduino

El sistema que vamos a usar es muy sencillo, conectamos el nRF24L01 al arduino, y por otro lado conectamos las entradas analógicas y digitales que van conectadas a nuestros botones y mandos de control. Estas señales las leemos y las enviamos a través de el radioenlace.

nRF24 Pinout

nRF24 Pinout

Como configurar el nRF24l01 como emisor

En principio, vamos a usar la Radio para solo emitir, es decir, no vamos a configurar la parte del receptor para hacer las cosas más fáciles y poder hacer el proyecto de manera más rápida.

Al usar la librería que podemos descargar para Arduino, toda nuestra configuración se puede resumir en:

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>

// RF24
#define CE_PIN 9
#define CSN_PIN 10

RF24 radio(CE_PIN, CSN_PIN);

const uint64_t pipe_tx = 0xAABBCCDD01LL;

void setup() {

  radio.begin();
  radio.openWritingPipe(pipe_tx);

  if (radio.isChipConnected())
    Serial.println("Conectado!");

  radio.setAutoAck(false);
  radio.setDataRate(RF24_1MBPS);
  radio.setPALevel(RF24_PA_MAX);
  radio.setCRCLength(RF24_CRC_8); 

  // Paramos de recibir para solo mandar datos.
  radio.stopListening();
}

void loop() {
   /*..*/
}

Básicamente configuramos la dirección de envío, esta dirección tiene que se compartida por el transmisor y el receptor. Es decir, si uno escribe a la dirección 0xAABBCCDD01el otro tiene que escuchar en el 0xAABBCCDD01. Además, desactivamos el ACK, configuramos la velocidad a 1Mbps, ponemos la potencia al máximo y activamos el CRC.

Si estáis utilizando el USB para alimentar todo este sistema, tened cuidado ya que si no os funciona puede ser por problema de la alimentación. Intentad lo mismo usando 5V bien regulados para el Arduino.

Enviando estructuras a con el nRF24l01

Generalmente, todos los tutoriales que veo, usan el nRF24l01 para enviarse datos muy básicos o mensajes. Para aprender está bien, pero en la práctica muy pocas veces vas a enviarte strings (son el demonio en sistemas embarcados), sino que vas a intentar enviar datos brutos, generalmente ordenados. Y la mejor manera de enviar los datos de manera ordenada es usando estructuras de datos.

La manera de enviar structs a través del nRF24 es muy sencillo. Lo primero que necesitamos es definir nuestra estructura, la cuál definirá como tendrá los datos dentro de la misma. En nuestro caso simplificado, como vamos a usar solo 4 canales ADC la estructura quedaría:

struct msg_{
  uint16_t adc1;
  uint16_t adc2;
  uint16_t adc3;
  uint16_t adc4;
} mensaje;

Es decir, hemos definido una variable mensaje que contiene cuatro números que hemos llamado adc1, adc2 … Solo tenemos que rellenar estos campos, con los valores de cada conversor Analógico-Digital del Arduino, y enviar la estructura entera.

En recepción, tendremos la misma estructura, y al simplemente recibirla, cada campo tendrá el valor que tenía en el envío. Y como hacemos este envío, junto con la lectura de nuestros ADCs? Pues es tan sencillo como lo que se ve en el siguiente trozo de código:

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>

// RF24
#define CE_PIN 9
#define CSN_PIN 10


// ADCs
#define ADC_1 15
#define ADC_2 16
#define ADC_3 17
#define ADC_4 18


RF24 radio(CE_PIN, CSN_PIN);

const uint64_t pipe_tx = 0xAABBCCDD01LL;
void setup() {
  pinMode(ADC_1, INPUT);
  pinMode(ADC_2, INPUT);
  pinMode(ADC_3, INPUT);
  pinMode(ADC_4, INPUT);

  radio.begin();
  radio.openWritingPipe(pipe_tx);

  if (radio.isChipConnected())
    Serial.println("Conectado!");

  radio.setAutoAck(false);
  radio.setDataRate(RF24_1MBPS);
  radio.setPALevel(RF24_PA_MIN);
  radio.setCRCLength(RF24_CRC_8); 
  radio.stopListening();
}

struct msg_{
  uint16_t adc1;
  uint16_t adc2;
  uint16_t adc3;
  uint16_t adc4;
} mensaje;

void loop() {
  
  mensaje.adc1 = analogRead(ADC_1);
  mensaje.adc2 = analogRead(ADC_2);
  mensaje.adc3 = analogRead(ADC_3);
  mensaje.adc4 = analogRead(ADC_4);

   bool ok= radio.writeFast(&mensaje,sizeof(mensaje));  
   radio.txStandBy();

  delay(50);
}

Y con esto estaría todo ya estaríamos enviando, la estructura con los cuatro valores de ADC a través de nuestro nRF24. Sin embargo, no todo es bonito, como en cualquier proyecto todo tiene sus ventajas e inconvenientes.

Ventajas e inconvenientes

Las principales ventajas son: la alta personalización posible del mando, así como de los datos a transmitir; y la posibilidad de implementar mensajes de vuelta para tener algo de telemetría. Sin embargo, por otra parte el alcance es más limitado que radios un poco más profesionales, y la fialibilidad del sistema depende un poco de la programación, así que si vuestro software se cuelga, el sistema dejará de recibir datos y de actuar.

Por lo tanto, si es para robots que no puedan hacer daño a nadie, y que en caso de error, lo peor que puede pasar es que os echéis unas risas viendo como el robot se estampa contra la pared, es una radio completamente válida. Sin embargo, no la recomendaría para drones o cosas voladoras por lo comentado antes.


Gluón

Teleco con ganas de aprender más y compartirlo. Viajero empedernido y amante de la fotografía y la tecnología. Espero dejar mi granito de arena y que este pueda servir de ayuda.