Transmisor RC Arduino de bricolaje

¿Eres un entusiasta de la electrónica y la programación? ¡Entonces este artículo es para ti! En esta guía, te enseñaremos cómo crear tu propio transmisor RC Arduino de bricolaje. Con simples componentes y un poco de creatividad, podrás controlar tus dispositivos a distancia de una manera divertida y sencilla. ¡Prepárate para embarcarte en un emocionante proyecto de DIY!

En el tutorial aprenderemos cómo construir un transmisor Arduino RC de bricolaje. Como a menudo necesito control inalámbrico para mis proyectos, construí este controlador inalámbrico multifuncional que se puede usar para prácticamente cualquier cosa.

Puede ver el vídeo a continuación o leer el tutorial escrito a continuación.

descripción general

Ahora puedo controlar de forma inalámbrica cualquier proyecto Arduino con sólo unos pequeños ajustes en el lado del receptor. Este transmisor también se puede utilizar como cualquier transmisor RC disponible en el mercado para controlar juguetes, automóviles, drones, etc. Todo lo que necesita es un simple receptor Arduino, que luego genera las señales correspondientes para controlar los dispositivos RC disponibles comercialmente.

Explicaré cómo funciona todo en este video con algunos ejemplos de cómo controlar un automóvil robot Arduino, controlar el robot Arduino Ant de mi video anterior y controlar un motor DC sin escobillas usando un controlador y algunos servomotores.

Transmisor RC Arduino de bricolaje

La>

Transmisor RC Arduino de bricolaje

Tiene>

Diagrama del circuito del transmisor Arduino RC

Primero, veamos el diagrama del circuito. El cerebro de este controlador RC es un Arduino Pro Mini alimentado por 2 baterías LiPo que producen aproximadamente 7,4 voltios. Podemos conectarlos directamente al pin RAW del Pro Mini, que tiene un regulador de voltaje que reduce el voltaje a 5V. Tenga en cuenta que hay dos versiones del Arduino Pro Mini, la que tengo que funciona a 5V y la otra que funciona a 3,3V.

Transmisor RC Arduino de bricolaje

Por>

Puede obtener los componentes necesarios para este tutorial de Arduino en los siguientes enlaces:

  • Módulo transceptor NRF24L01……….. Amazonas / Banggood / AliExpress
  • NRF24L01 + PA + LNA……………………. Amazon / Banggood / AliExpress
  • Potenciómetro ……………………………….. Amazonas / Banggood / AliExpress
  • Servo motor …………………………………… Amazon / Banggood / AliExpress
  • Interruptor de palanca…………………………….….. Amazon / Banggood / AliExpress
  • Palanca de mando ………………………………………….. Amazon / Banggood / AliExpress – Este joystick viene con una placa de conexión, por lo que es necesario desoldar el joystick.
  • Joystick sin placa de ruptura………… Ebay
  • Arduino Pro Mini……………………………….. Amazon / Banggood / AliExpress– Para estas placas necesitas PCB versión V2 o V3
  • Arduino Pro Mini como el que usé….. Ebay– PCB V1
  • Regulador de voltaje HT7333 3.3V…………. En la tienda de electrónica local: PCB V1 y PCB V2
  • Regulador de voltaje AMS1117 3.3V……………… Amazonas / Excelente / AliExpress – PCB V3

Divulgación: estos son enlaces de afiliados. Como asociado de Amazon, gano con compras que califican.

diseño de PCB

De hecho, terminé usando todos los pines analógicos y digitales del Arduino Pro Mini. Ahora, si intento conectar todo usando cables de puente, será un gran desastre. Así que diseñé una placa de circuito impreso personalizada utilizando el software gratuito de diseño de circuitos en línea EasyEDA.

Transmisor RC Arduino de bricolaje

Tomé>

Tenga en cuenta: Asegúrese de tener la versión correcta de Arduino Pro Mini para editar la PCB o cambiar el diseño de la PCB en consecuencia. Aquí hay una foto comparativa entre las tres versiones diferentes según su Arduino y su regulador de voltaje.

Transmisor RC Arduino de bricolaje

Aquí>Archivos de proyecto de este diseño de PCB.. Esto abrirá las tres versiones diferentes en pestañas separadas para que puedas seleccionar la versión que desees.

Después de completar el diseño, creé el archivo Gerber necesario para hacer la placa de circuito.

Archivo Gerber:

Entonces yo Pedí la placa a JLCPCB quienes también son los patrocinadores de este video.

Transmisor RC Arduino de bricolaje

Aquí>

Transmisor RC Arduino de bricolaje

Y>

Transmisor RC Arduino de bricolaje

Montaje de la placa de circuito

Bien, ahora podemos continuar con el montaje del tablero. Comencé soldando los pines del Arduino Pro Mini. Una forma sencilla y buena es colocarlos en una placa para que permanezcan firmemente en su lugar mientras se sueldan.

Transmisor RC Arduino de bricolaje

El>

Transmisor RC Arduino de bricolaje

Para>

Transmisor RC Arduino de bricolaje

Luego>

Transmisor RC Arduino de bricolaje

Seguimos>

Luego, para soldar los potenciómetros a la placa, tuve que extender sus pines con algunos cabezales de pines.

Transmisor RC Arduino de bricolaje

Podemos>

Luego inserté los dos interruptores de palanca y los dos joysticks y los soldé en su lugar.

Transmisor RC Arduino de bricolaje

Finalmente>

Y listo, nuestra placa ya está lista y podemos proceder a realizarle la funda. Como me gusta el aspecto del tablero y quiero que sea visible, elegí acrílico transparente para la cubierta.

Transmisor RC Arduino de bricolaje

Aquí>

Transmisor RC Arduino de bricolaje
Transmisor RC Arduino de bricolaje

Así>

Luego refiné la forma del acrílico usando una simple escofina. Las dos placas quedaron geniales y encajaron perfectamente en el tablero.

Transmisor RC Arduino de bricolaje

A>

Transmisor RC Arduino de bricolaje

Utilicé>

Transmisor RC Arduino de bricolaje

Antes>

Transmisor RC Arduino de bricolaje

Bien,>

Transmisor RC Arduino de bricolaje

Luego>

Transmisor RC Arduino de bricolaje

A>

Transmisor RC Arduino de bricolaje

Finalmente,>

Transmisor RC Arduino de bricolaje

Ahora>

Transmisor RC Arduino de bricolaje

Luego>

Transmisor RC Arduino de bricolaje

Y>

Código de transmisor RC basado en Arduino DIY

Expliquemos cómo funciona el código del transmisor. Entonces necesitamos incluir el SPI primero y biblioteca RF24 para comunicación inalámbrica y la biblioteca I2C para el módulo de aceleración. Luego necesitamos definir las entradas digitales, definir algunas variables necesarias para el siguiente programa, así como el objeto de radio y la dirección de comunicación.

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>


// Define the digital inputs
#define jB1 1  // Joystick button 1
#define jB2 0  // Joystick button 2
#define t1 7   // Toggle switch 1
#define t2 4   // Toggle switch 1
#define b1 8   // Button 1
#define b2 9   // Button 2
#define b3 2   // Button 3
#define b4 3   // Button 4

const int MPU = 0x68; // MPU6050 I2C address
float AccX, AccY, AccZ;
float GyroX, GyroY, GyroZ;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY;
float angleX, angleY;
float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY;
float elapsedTime, currentTime, previousTime;
int c = 0;


RF24 radio(5, 6);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001"; // AddressCode language: Arduino (arduino)

Luego necesitamos definir una estructura en la que almacenamos los 14 valores de entrada del controlador. El tamaño máximo de esta estructura puede ser 32 bytes porque este es el límite del búfer NRF24L01 o la cantidad de datos que el módulo puede enviar a la vez.

/ Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
  byte pot1;
  byte pot2;
  byte tSwitch1;
  byte tSwitch2;
  byte button1;
  byte button2;
  byte button3;
  byte button4;
};

Data_Package data; //Create a variable with the above structureCode language: Arduino (arduino)

En la sección de configuración necesitamos inicializar el módulo MPU6050 y también podemos calcular el error de IMU, valor que luego se utilizará para calcular los ángulos correctos del módulo.

void initialize_MPU6050() {
  Wire.begin();                      // Initialize comunication
  Wire.beginTransmission(MPU);       // Start communication with MPU6050 // MPU=0x68
  Wire.write(0x6B);                  // Talk to the register 6B
  Wire.write(0x00);                  // Make reset - place a 0 into the 6B register
  Wire.endTransmission(true);        //end the transmission
  // Configure Accelerometer
  Wire.beginTransmission(MPU);
  Wire.write(0x1C);                  //Talk to the ACCEL_CONFIG register
  Wire.write(0x10);                  //Set the register bits as 00010000 (+/- 8g full scale range)
  Wire.endTransmission(true);
  // Configure Gyro
  Wire.beginTransmission(MPU);
  Wire.write(0x1B);                   // Talk to the GYRO_CONFIG register (1B hex)
  Wire.write(0x10);                   // Set the register bits as 00010000 (1000dps full scale)
  Wire.endTransmission(true);
}Code language: Arduino (arduino)

Puede encontrar más detalles sobre cómo funcionan el acelerómetro y el giroscopio MEMS aquí. Próximamente habrá un tutorial especial para el MPU6050.

Luego debemos inicializar la comunicación por radio, habilitar las resistencias pull-up internas de Arduino para todas las entradas digitales y establecer los valores predeterminados iniciales para todas las variables.

// Define the radio communication
  radio.begin();
  radio.openWritingPipe(address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  
  // Activate the Arduino internal pull-up resistors
  pinMode(jB1, INPUT_PULLUP);
  pinMode(jB2, INPUT_PULLUP);
  pinMode(t1, INPUT_PULLUP);
  pinMode(t2, INPUT_PULLUP);
  pinMode(b1, INPUT_PULLUP);
  pinMode(b2, INPUT_PULLUP);
  pinMode(b3, INPUT_PULLUP);
  pinMode(b4, INPUT_PULLUP);Code language: Arduino (arduino)

En la sección de bucle, comience a leer todas las entradas analógicas y asigne sus valores de 0 a 1023 a valores de bytes de 0 a 255, ya que ya hemos definido las variables en nuestra estructura como bytes. Cada entrada se almacena en la variable de datos respectiva de la estructura.

// Read all analog inputs and map them to one Byte value
  data.j1PotX = map(analogRead(A1), 0, 1023, 0, 255); // Convert the analog read value from 0 to 1023 into a BYTE value from 0 to 255
  data.j1PotY = map(analogRead(A0), 0, 1023, 0, 255);
  data.j2PotX = map(analogRead(A2), 0, 1023, 0, 255);
  data.j2PotY = map(analogRead(A3), 0, 1023, 0, 255);
  data.pot1 = map(analogRead(A7), 0, 1023, 0, 255);
  data.pot2 = map(analogRead(A6), 0, 1023, 0, 255);Code language: Arduino (arduino)

Solo debemos tener en cuenta que los valores de los pines digitales serán 0 cuando se presionen los botones porque estamos usando resistencias pull-up.

// Read all digital inputs
  data.j1Button = digitalRead(jB1);
  data.j2Button = digitalRead(jB2);
  data.tSwitch2 = digitalRead(t2);
  data.button1 = digitalRead(b1);
  data.button2 = digitalRead(b2);
  data.button3 = digitalRead(b3);
  data.button4 = digitalRead(b4);Code language: Arduino (arduino)

Entonces, con la función radio.write() simplemente enviamos los valores de los 14 canales al receptor.

// Send the whole data from the structure to the receiver
  radio.write(&data, sizeof(Data_Package));Code language: Arduino (arduino)

Si el interruptor de palanca 1 está activado, utilizamos los datos del acelerómetro y el giroscopio para el control.

if (digitalRead(t1) == 0) {
    read_IMU();    // Use MPU6050 instead of Joystick 1 for controling left, right, forward and backward movements
  }Code language: Arduino (arduino)

Entonces, en lugar de los valores X e Y del joystick 1, usamos los valores de ángulo que obtenemos de la IMU, que previamente convertimos de valores de -90 a +90 grados a byte. valores de 0 a 255, respectivamente.

// Map the angle values from -90deg to +90 deg into values from 0 to 255, like the values we are getting from the Joystick
  data.j1PotX = map(angleX, -90, +90, 255, 0);
  data.j1PotY = map(angleY, -90, +90, 0, 255);Code language: Arduino (arduino)

Entonces este es el código del transmisor. Lo más importante fue definir la comunicación por radio y enviar los datos al receptor.

Aquí está el código Arduino completo para este transmisor Arduino RC de bricolaje:

/*
        DIY Arduino based RC Transmitter
  by Dejan Nedelkovski, www.HowToMechatronics.com
  Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Wire.h>


// Define the digital inputs
#define jB1 1  // Joystick button 1
#define jB2 0  // Joystick button 2
#define t1 7   // Toggle switch 1
#define t2 4   // Toggle switch 1
#define b1 8   // Button 1
#define b2 9   // Button 2
#define b3 2   // Button 3
#define b4 3   // Button 4

const int MPU = 0x68; // MPU6050 I2C address
float AccX, AccY, AccZ;
float GyroX, GyroY, GyroZ;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY;
float angleX, angleY;
float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY;
float elapsedTime, currentTime, previousTime;
int c = 0;


RF24 radio(5, 6);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001"; // Address

// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
  byte pot1;
  byte pot2;
  byte tSwitch1;
  byte tSwitch2;
  byte button1;
  byte button2;
  byte button3;
  byte button4;
};

Data_Package data; //Create a variable with the above structure

void setup() {
  Serial.begin(9600);
  
  // Initialize interface to the MPU6050
  initialize_MPU6050();

  // Call this function if you need to get the IMU error values for your module
  //calculate_IMU_error();
  
  // Define the radio communication
  radio.begin();
  radio.openWritingPipe(address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  
  // Activate the Arduino internal pull-up resistors
  pinMode(jB1, INPUT_PULLUP);
  pinMode(jB2, INPUT_PULLUP);
  pinMode(t1, INPUT_PULLUP);
  pinMode(t2, INPUT_PULLUP);
  pinMode(b1, INPUT_PULLUP);
  pinMode(b2, INPUT_PULLUP);
  pinMode(b3, INPUT_PULLUP);
  pinMode(b4, INPUT_PULLUP);
  
  // Set initial default values
  data.j1PotX = 127; // Values from 0 to 255. When Joystick is in resting position, the value is in the middle, or 127. We actually map the pot value from 0 to 1023 to 0 to 255 because that's one BYTE value
  data.j1PotY = 127;
  data.j2PotX = 127;
  data.j2PotY = 127;
  data.j1Button = 1;
  data.j2Button = 1;
  data.pot1 = 1;
  data.pot2 = 1;
  data.tSwitch1 = 1;
  data.tSwitch2 = 1;
  data.button1 = 1;
  data.button2 = 1;
  data.button3 = 1;
  data.button4 = 1;
}
void loop() {
  // Read all analog inputs and map them to one Byte value
  data.j1PotX = map(analogRead(A1), 0, 1023, 0, 255); // Convert the analog read value from 0 to 1023 into a BYTE value from 0 to 255
  data.j1PotY = map(analogRead(A0), 0, 1023, 0, 255);
  data.j2PotX = map(analogRead(A2), 0, 1023, 0, 255);
  data.j2PotY = map(analogRead(A3), 0, 1023, 0, 255);
  data.pot1 = map(analogRead(A7), 0, 1023, 0, 255);
  data.pot2 = map(analogRead(A6), 0, 1023, 0, 255);
  // Read all digital inputs
  data.j1Button = digitalRead(jB1);
  data.j2Button = digitalRead(jB2);
  data.tSwitch2 = digitalRead(t2);
  data.button1 = digitalRead(b1);
  data.button2 = digitalRead(b2);
  data.button3 = digitalRead(b3);
  data.button4 = digitalRead(b4);
  // If toggle switch 1 is switched on
  if (digitalRead(t1) == 0) {
    read_IMU();    // Use MPU6050 instead of Joystick 1 for controling left, right, forward and backward movements
  }
  // Send the whole data from the structure to the receiver
  radio.write(&data, sizeof(Data_Package));
}

void initialize_MPU6050() {
  Wire.begin();                      // Initialize comunication
  Wire.beginTransmission(MPU);       // Start communication with MPU6050 // MPU=0x68
  Wire.write(0x6B);                  // Talk to the register 6B
  Wire.write(0x00);                  // Make reset - place a 0 into the 6B register
  Wire.endTransmission(true);        //end the transmission
  // Configure Accelerometer
  Wire.beginTransmission(MPU);
  Wire.write(0x1C);                  //Talk to the ACCEL_CONFIG register
  Wire.write(0x10);                  //Set the register bits as 00010000 (+/- 8g full scale range)
  Wire.endTransmission(true);
  // Configure Gyro
  Wire.beginTransmission(MPU);
  Wire.write(0x1B);                   // Talk to the GYRO_CONFIG register (1B hex)
  Wire.write(0x10);                   // Set the register bits as 00010000 (1000dps full scale)
  Wire.endTransmission(true);
}

void calculate_IMU_error() {
  // We can call this funtion in the setup section to calculate the accelerometer and gury data error. From here we will get the error values used in the above equations printed on the Serial Monitor.
  // Note that we should place the IMU flat in order to get the proper values, so that we then can the correct values
  // Read accelerometer values 200 times
  while (c < 200) {
    Wire.beginTransmission(MPU);
    Wire.write(0x3B);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 6, true);
    AccX = (Wire.read() << 8 | Wire.read()) / 4096.0 ;
    AccY = (Wire.read() << 8 | Wire.read()) / 4096.0 ;
    AccZ = (Wire.read() << 8 | Wire.read()) / 4096.0 ;
    // Sum all readings
    AccErrorX = AccErrorX + ((atan((AccY) / sqrt(pow((AccX), 2) + pow((AccZ), 2))) * 180 / PI));
    AccErrorY = AccErrorY + ((atan(-1 * (AccX) / sqrt(pow((AccY), 2) + pow((AccZ), 2))) * 180 / PI));
    c++;
  }
  //Divide the sum by 200 to get the error value
  AccErrorX = AccErrorX / 200;
  AccErrorY = AccErrorY / 200;
  c = 0;
  // Read gyro values 200 times
  while (c < 200) {
    Wire.beginTransmission(MPU);
    Wire.write(0x43);
    Wire.endTransmission(false);
    Wire.requestFrom(MPU, 4, true);
    GyroX = Wire.read() << 8 | Wire.read();
    GyroY = Wire.read() << 8 | Wire.read();
    // Sum all readings
    GyroErrorX = GyroErrorX + (GyroX / 32.8);
    GyroErrorY = GyroErrorY + (GyroY / 32.8);
    c++;
  }
  //Divide the sum by 200 to get the error value
  GyroErrorX = GyroErrorX / 200;
  GyroErrorY = GyroErrorY / 200;
  // Print the error values on the Serial Monitor
  Serial.print("AccErrorX: ");
  Serial.println(AccErrorX);
  Serial.print("AccErrorY: ");
  Serial.println(AccErrorY);
  Serial.print("GyroErrorX: ");
  Serial.println(GyroErrorX);
  Serial.print("GyroErrorY: ");
  Serial.println(GyroErrorY);
}

void read_IMU() {
  // === Read acceleromter data === //
  Wire.beginTransmission(MPU);
  Wire.write(0x3B); // Start with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  //For a range of +-8g, we need to divide the raw values by 4096, according to the datasheet
  AccX = (Wire.read() << 8 | Wire.read()) / 4096.0; // X-axis value
  AccY = (Wire.read() << 8 | Wire.read()) / 4096.0; // Y-axis value
  AccZ = (Wire.read() << 8 | Wire.read()) / 4096.0; // Z-axis value

  // Calculating angle values using
  accAngleX = (atan(AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) + 1.15; // AccErrorX ~(-1.15) See the calculate_IMU_error()custom function for more details
  accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) - 0.52; // AccErrorX ~(0.5)

  // === Read gyro data === //
  previousTime = currentTime;        // Previous time is stored before the actual time read
  currentTime = millis();            // Current time actual time read
  elapsedTime = (currentTime - previousTime) / 1000;   // Divide by 1000 to get seconds
  Wire.beginTransmission(MPU);
  Wire.write(0x43); // Gyro data first register address 0x43
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 4, true); // Read 4 registers total, each axis value is stored in 2 registers
  GyroX = (Wire.read() << 8 | Wire.read()) / 32.8; // For a 1000dps range we have to divide first the raw value by 32.8, according to the datasheet
  GyroY = (Wire.read() << 8 | Wire.read()) / 32.8;
  GyroX = GyroX + 1.85; //// GyroErrorX ~(-1.85)
  GyroY = GyroY - 0.15; // GyroErrorY ~(0.15)
  // Currently the raw values are in degrees per seconds, deg/s, so we need to multiply by sendonds (s) to get the angle in degrees
  gyroAngleX = GyroX * elapsedTime;
  gyroAngleY = GyroY * elapsedTime;

  // Complementary filter - combine acceleromter and gyro angle values
  angleX = 0.98 * (angleX + gyroAngleX) + 0.02 * accAngleX;
  angleY = 0.98 * (angleY + gyroAngleY) + 0.02 * accAngleY;
  // Map the angle values from -90deg to +90 deg into values from 0 to 255, like the values we are getting from the Joystick
  data.j1PotX = map(angleX, -90, +90, 255, 0);
  data.j1PotY = map(angleY, -90, +90, 0, 255);
}Code language: Arduino (arduino)

Código de destinatario

Ahora veamos cómo podemos obtener estos datos. Aquí hay un esquema simple de un receptor Arduino y NRF24L01. Por supuesto, también puedes utilizar cualquier otra placa Arduino.

Transmisor RC Arduino de bricolaje

Y>

/*
    DIY Arduino based RC Transmitter Project
              == Receiver Code ==

  by Dejan Nedelkovski, www.HowToMechatronics.com
  Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(10, 9);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001";

unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;

// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
  byte pot1;
  byte pot2;
  byte tSwitch1;
  byte tSwitch2;
  byte button1;
  byte button2;
  byte button3;
  byte button4;
};

Data_Package data; //Create a variable with the above structure

void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.startListening(); //  Set the module as receiver
  resetData();
}
void loop() {
  // Check whether there is data to be received
  if (radio.available()) {
    radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
    lastReceiveTime = millis(); // At this moment we have received the data
  }
  // Check whether we keep receving data, or we have a connection between the two modules
  currentTime = millis();
  if ( currentTime - lastReceiveTime > 1000 ) { // If current time is more then 1 second since we have recived the last data, that means we have lost connection
    resetData(); // If connection is lost, reset the data. It prevents unwanted behavior, for example if a drone has a throttle up and we lose connection, it can keep flying unless we reset the values
  }
  // Print the data in the Serial Monitor
  Serial.print("j1PotX: ");
  Serial.print(data.j1PotX);
  Serial.print("; j1PotY: ");
  Serial.print(data.j1PotY);
  Serial.print("; button1: ");
  Serial.print(data.button1);
  Serial.print("; j2PotX: ");
  Serial.println(data.j2PotX); 
}

void resetData() {
  // Reset the values when there is no radio connection - Set initial default values
  data.j1PotX = 127;
  data.j1PotY = 127;
  data.j2PotX = 127;
  data.j2PotY = 127;
  data.j1Button = 1;
  data.j2Button = 1;
  data.pot1 = 1;
  data.pot2 = 1;
  data.tSwitch1 = 1;
  data.tSwitch2 = 1;
  data.button1 = 1;
  data.button2 = 1;
  data.button3 = 1;
  data.button4 = 1;
}Code language: Arduino (arduino)

En el bucle principal utilizamos la función disponible() para comprobar si hay datos entrantes. Si esto es cierto, simplemente leemos los datos y los almacenamos en las variables de la estructura. Ahora podemos imprimir los datos en el monitor serie para comprobar si la transferencia está funcionando correctamente. También usamos la función millis() y una declaración if para verificar si todavía estamos recibiendo datos. Si no recibimos datos durante más de 1 segundo, restablecemos las variables a sus valores predeterminados. Usamos esto para prevenir comportamientos no deseados. Por ejemplo, si un dron tiene el acelerador al máximo y perdemos la conexión, podrá seguir volando a menos que reseteemos los valores.

Eso es todo. Ahora podemos implementar este método de recibir datos para cualquier proyecto Arduino. Por ejemplo, aquí está el código para controlar el coche robot Arduino de uno de mis vídeos anteriores.

Como actualización de este proyecto, creé un receptor RC especial basado en Arduino. Nuevamente, se basa en la placa Arduino Pro Mini y tiene varios conectores ESC y servo listos para usar alojados en una placa compacta.

Transmisor RC Arduino de bricolaje

Ver también
Receptor DIY Arduino RC para modelos RC y proyectos Arduino

Control inalámbrico del coche robot Arduino con un transmisor RC

Transmisor RC Arduino de bricolaje

código>

Aquí necesitamos definir las bibliotecas, la estructura y la comunicación por radio como se explicó anteriormente. Luego, en el bucle principal sólo tenemos que leer los datos entrantes y utilizarlos para cualquier propósito. En este caso estoy usando los valores del joystick 1 para conducir el coche.

Controlador Arduino Ant Robot/Hexapod con transmisor Arduino RC

Transmisor RC Arduino de bricolaje

código>

Asimismo, diseñé el robot hormiga Arduino de mi video anterior para que se controle de forma inalámbrica mediante este transmisor Arduino RC. Solo necesitamos leer los datos y ejecutar las funciones correspondientes en consecuencia, como por ejemplo: Por ejemplo, adelante, izquierda, derecha, morder, atacar, etc.

ESC y servocontrol con transmisor RC

Finalmente, echemos un vistazo a cómo se puede utilizar este transmisor para controlar dispositivos RC comerciales.

Transmisor RC Arduino de bricolaje

Generalmente>Servobiblioteca Arduino y utilizar valores de 0 a 180 grados. Para controlar un motor sin escobillas usando un controlador, podemos usar nuevamente la biblioteca de servos para generar la señal PWM de 50 Hz que se usará para controlar el controlador. Al variar el ciclo de trabajo de 1000 a 2000 microsegundos, controlamos la velocidad del motor de cero al máximo. Sin embargo, puedes aprender más sobre cómo controlar motores sin escobillas con ESC en mi próximo tutorial.

Transmisor RC Arduino de bricolaje

See también
Avión RC Arduino | 100% bricolaje

Tenga en cuenta que en realidad no podemos conectar el sistema receptor RC estándar con este sistema NRF24L01 de 2,4 GHz. En su lugar, necesitamos modificar o crear nuestro propio receptor que consta de un Arduino y un módulo NRF24L01. Desde allí podemos generar las señales PWM o PPM apropiadas para controlar el dispositivo RC.

Transmisor RC Arduino de bricolaje
/*
    DIY Arduino based RC Transmitter Project
   == Receiver Code - ESC and Servo Control ==

  by Dejan Nedelkovski, www.HowToMechatronics.com
  Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Servo.h>

RF24 radio(10, 9);   // nRF24L01 (CE, CSN)
const byte address[6] = "00001";

unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;

Servo esc;  // create servo object to control the ESC
Servo servo1;
Servo servo2;
int escValue, servo1Value, servo2Value;

// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
  byte pot1;
  byte pot2;
  byte tSwitch1;
  byte tSwitch2;
  byte button1;
  byte button2;
  byte button3;
  byte button4;
};

Data_Package data; //Create a variable with the above structure

void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.startListening(); //  Set the module as receiver
  resetData();
  esc.attach(9);
  servo1.attach(3);
  servo2.attach(4);
}
void loop() {
  // Check whether we keep receving data, or we have a connection between the two modules
  currentTime = millis();
  if ( currentTime - lastReceiveTime > 1000 ) { // If current time is more then 1 second since we have recived the last data, that means we have lost connection
    resetData(); // If connection is lost, reset the data. It prevents unwanted behavior, for example if a drone jas a throttle up, if we lose connection it can keep flying away if we dont reset the function
  }
  // Check whether there is data to be received
  if (radio.available()) {
    radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
    lastReceiveTime = millis(); // At this moment we have received the data
  }
  // Controlling servos
  servo1Value = map(data.j2PotX, 0, 255, 0, 180);
  servo2Value = map(data.j2PotY, 0, 255, 0, 180);
  servo1.write(servo1Value);
  servo2.write(servo2Value);
  // Controlling brushless motor with ESC
  escValue = map(data.pot1, 0, 255, 1000, 2000); // Map the receiving value form 0 to 255 to 0 1000 to 2000, values used for controlling ESCs
  esc.writeMicroseconds(escValue); // Send the PWM control singal to the ESC
}

void resetData() {
  // Reset the values when there is no radio connection - Set initial default values
  data.j1PotX = 127;
  data.j1PotY = 127;
  data.j2PotX = 127;
  data.j2PotY = 127;
  data.j1Button = 1;
  data.j2Button = 1;
  data.pot1 = 1;
  data.pot2 = 1;
  data.tSwitch1 = 1;
  data.tSwitch2 = 1;
  data.button1 = 1;
  data.button2 = 1;
  data.button3 = 1;
  data.button4 = 1;
}Code language: Arduino (arduino)

Eso es todo. Espero que hayas disfrutado este video y hayas aprendido algo nuevo. No dudes en hacer tus preguntas en la sección de comentarios a continuación y consultar mi colección de proyectos Arduino.

Categorías Proyectos
Error 403 The request cannot be completed because you have exceeded your quota. : quotaExceeded

Transmisor RC Arduino de bricolaje: Guía paso a paso

En este tutorial aprenderás cómo construir un transmisor RC Arduino DIY. Muchas veces necesito control inalámbrico para los proyectos que hago, por lo tanto he construido este controlador de radio multifuncional que puede ser utilizado para prácticamente todo. Ahora puedo controlar de forma inalámbrica cualquier proyecto de Arduino con solo algunos ajustes en el lado receptor.

Visión General

Este transmisor puede ser utilizado como cualquier transmisor RC comercial para controlar juguetes, autos, drones, entre otros. Para ello solo necesitas un receptor Arduino simple que luego generará las señales adecuadas para controlar esos dispositivos RC comerciales.

La comunicación de radio de este controlador se basa en el módulo transceptor NRF24L01, que si se utiliza con una antena amplificada puede tener un rango estable de hasta 700 metros en espacio abierto. Cuenta con 14 canales, 6 de los cuales son entradas analógicas y 8 entradas digitales. Además, tiene dos joysticks, dos potenciómetros, dos interruptores de palanca, seis botones y además una unidad de medición interna que consta de un acelerómetro y un giroscopio que también se puede utilizar para controlar cosas simplemente moviéndose o inclinando el controlador.

Diagrama del Circuito del Transmisor RC Arduino

El cerebro de este controlador RC es un Arduino Pro Mini que se alimenta con 2 baterías LiPo para obtener alrededor de 7.4 voltios. Se pueden conectar directamente al pin RAW del Pro Mini que cuenta con un regulador de voltaje que reduce el voltaje a 5V. Es importante tener en cuenta que existen dos versiones del Arduino Pro Mini, como la que opera a 5V y la otra que opera a 3.3V.

Por otro lado, el módulo NRF24L01 necesita estrictamente 3.3V y se recomienda que provenga de una fuente de alimentación dedicada. Por lo tanto, necesitamos utilizar un regulador de voltaje de 3.3V que esté conectado a las baterías y convertir los 7.4V a 3.3V. También es necesario utilizar un condensador de desacoplamiento justo al lado del módulo para mantener el voltaje más estable, lo que garantizará una comunicación de radio más estable.

Diseño del PCB

Después de diseñar el PCB a través del software de diseño de circuitos en línea EasyEDA, se generó un archivo Gerber necesario para la fabricación del PCB. Una vez se realizó el pedido del PCB en JLCPCB, se procedió con el ensamblaje del PCB, soldando los componentes en su lugar y creando una cubierta de acrílico transparente para proteger el PCB.

Código del Transmisor Arduino RC

El código del transmisor Arduino RC se encarga de leer los valores de los potenciómetros, botones, interruptores, entre otros y enviarlos al receptor a través del módulo NRF24L01. Además, si el interruptor de palanca 1 está encendido, se utilizan los datos del acelerómetro y giroscopio en lugar de los valores del joystick para el control.

Código del Receptor Arduino RC

El código del receptor Arduino RC se encarga de recibir los datos enviados por el transmisor a través del módulo NRF24L01 y actuar en consecuencia. En este caso, se muestra un ejemplo de cómo controlar un Arduino robot car con los datos recibidos.

Control de ESC y Servo

Además, se muestra cómo se puede utilizar este transmisor para controlar dispositivos RC comerciales, como servos o motores brushless mediante ESC. Para ello, simplemente leemos los datos recibidos y los utilizamos para controlar los servos y motores de acuerdo a los valores recibidos.

En resumen, este tutorial te enseñó cómo construir tu propio transmisor RC Arduino DIY. Si tienes alguna pregunta o sugerencia, no dudes en dejar un comentario y ¡diviértete creando tu propio controlador de radio personalizado!

5 comentarios en «Transmisor RC Arduino de bricolaje»

Deja un comentario