Fernsteuerung mit nRF24L01 (2,4 GHz) - AZ-Delivery

Después de darme cuenta del control remoto con el transceptor HC-12 de 433MHz, que desafortunadamente ya no está en el rango, en las publicaciones anteriores, me gustaría reemplazarlo con el transceptor nRF24L01. Este módulo también se puede utilizar como transmisor y receptor bajo control de programa. Pero básicamente se controla de manera diferente, es decir, a través de la interfaz de periféricos en serie, o SPI para abreviar.

Hardware

Número Componente
1 Placa de microcontrolador con ATmega328P, ATmega16U2, compatible con Arduino UNO R3
o Nano V3.0 con Atmega328 CH340! 100% Arduino compatible con Nano V3
o ¡Nano V3.0 con chip FT232RL y ATmega328! 100% compatible con Arduino Nano V3
2 NRF24L01 con módulo inalámbrico de 2,4 GHz, para Ardiuno, ESP8266, Raspberry Pi
posiblemente. Adaptador para NRF24L01 (ver nota en el texto)
1 PS2 Joystick Shield Game Pad Keypad V2.0 für Arduino
o Módulo de joystick KY-023 para Arduino UNO R3 y otros MCU
Protoboard, cables de puente, artículos pequeños
posiblemente. Carcasa de la impresora 3D


Primero, echemos un vistazo al nRF24L01 con su adaptador opcional.


Incluso si no utilizo el adaptador para el transceptor nRF24L01, lo presento aquí, porque en primer lugar puede ver muy bien la asignación de pines.

En segundo lugar, debes hacer lo siguiente Nota dar: El transceptor solo puede tolerar voltaje de 3.3V. Para voltajes más altos, se recomienda este adaptador, con el que se puede ver el regulador de voltaje en la imagen de la izquierda.


A partir de las designaciones de los pines, puede ver rápidamente que no está conectado a una interfaz en serie (UART), sino a la Interfaz de periféricos en serie (SPI).

Aquí está la asignación de pines típica:

SCE Chip Enable (RX TX Mode Select) Digital D9
CSN Chip Select (Active Low) Digital D10
SCK Serial Clock Digital D13
MOSI Master Out Slave In Digital D11
MISO Master In Slave Out Digital D12
VCC 3,3V !!!
GND GND
IRQ not connected


No necesita preocuparse por esto cuando conecte el nRF24L01 al protector del joystick. Sin embargo, tenemos que recordar SCE = 9 y CSN = 10, porque podemos y definiremos estos pines nosotros mismos, si es necesario, mientras que SCK, MOSI y MISO están asignados permanentemente.

Para nuestro boceto, necesitamos una nueva biblioteca de programas, que se agrega a través del administrador de la biblioteca. Allí ingresamos RF24 como término de búsqueda.


Si se desplaza un poco hacia abajo, encontrará la biblioteca TMRh20 que utilizo.

Como (casi) siempre, los programas de muestra también se instalan con la biblioteca. Así que desplácese hacia abajo en Archivo / Ejemplos hasta RF24. Un boceto llamado GettingStarted es una opción obvia para los usuarios primerizos.


Qué bueno que haya algo para usar al principio:


/**
* A simple example of sending data from 1 nRF24L01 transceiver to another.
*
* This example was written to be used on 2 devices acting as "nodes".
* Use the Serial Monitor to change each node's behavior.
*/

Entonces: necesitamos dos MCU cada uno con el transceptor. El mismo boceto se carga en ambas MCU; qué microcontrolador es el remitente y qué receptor se determina en el monitor en serie.

Recuerde que debe iniciar (instanciar) el IDE de Arduino dos veces en una PC para dos puertos COM virtuales diferentes.

Y necesitamos hacer un pequeño cambio en la línea 18. Allí se definen los pines para CE y CSN. El valor predeterminado es:

Radio RF24 (7, 8); // usando el pin 7 para el pin CE y el pin 8 para el pin CSN

Como se indicó anteriormente, cambiamos los números de pin a CE / SCE = 9 y CSN = 10, es decir

Radio RF24 (9, 10); // usando el pin 9 para el pin CE y el pin 10 para el pin CSN

Compílelo, cárguelo y pruébelo.

Lo bueno de este programa es que recibe un mensaje de error si el transceptor no reacciona, por ejemplo, porque estaba conectado incorrectamente o el cambio anterior no se realizó en el boceto.


Con otros programas en los que no recibe esta información, la resolución de problemas suele llevar más tiempo.

Si todo es correcto, se le preguntará qué dispositivo (nodo) es. Entonces ingrese IDE 0 en el monitor serial e IDE 1 en el otro.


Qué nodo envía se decide ingresando la letra T ot (para Transmitir) en la línea superior del Monitor serial.


Le aconsejo que copie estos intentos para ganar confianza en el manejo de los transceptores. Si algo no funcionó en mis intentos, simplemente cargué este boceto para ver si recibía el mensaje "hardware de radio no responde". Luego, el error se encontró rápidamente.

Ahora vamos a cambiar y programar nuestros mandos a distancia y el coche robot modificado, inicialmente con dos nanos.

los Asignación de pines se especifica en gran medida debido a la interfaz SPI. Cuando se usa el Nano, SCK está en el pin D13, MISO en el pin 12 y MOSI en el pin 11. Se pueden seleccionar los otros pines. Elijo CE en el pin D2 y CSN en el pin D3, para no ocupar los pines PWM que se utilizan para los motores en el segundo boceto. Para el joystick utilizo las entradas analógicas A6 y A7, así como D4 para el botón.

Imagen y boceto para control remoto:


/*
Joystick als Motor Controller, Stillstand = 505
je 5 Stufen vor/zurück, je 5 Stufen rechts/links
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(2, 3); // CE, CSN
const byte address[6] = "CodeR";

int x = 5; // x-Achse = links/rechts
int y = 5; // y-Achse = vor/zurück
int code = 505;
int joybutton = 4; // Joystick button
float faktor = 1.0; // für Anpassung bei unterschiedlicher Spannung oder ADC

void setup() {
pinMode(joybutton,INPUT_PULLUP);
Serial.begin(115200);
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
}

void sendcode() {
radio.write(&code, sizeof(code));
delay(100); // little delay for next button press
}

void loop() {
float A6 = faktor * analogRead (6);
float A7 = faktor * analogRead (7);
bool button = digitalRead(joybutton);

Serial.print("x-Achse: ");
Serial.print(A6);
Serial.print("y-Achse: ");
Serial.print(A7);
Serial.print(" Button pressed ");
Serial.print(button);

x = int(A6/100);
y = int(A7/100);
code = 100*y + x;
Serial.print(" Code = ");
Serial.println(code);
sendcode();
}
 

Y aquí la imagen y el bosquejo del coche robot con dos motores:



#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(2, 3); // CE, CSN
const byte address[6] = "CodeR";

// define variables for speed control
int x = 0;
int y = 0;
int left = 0;
int right = 0;
int code = 505;
int speedL = 0;
float factor = 0.66; // correction of speedLevel = maxValue/255
// define motor pins
int m11 = 5; //left motor(s) pwr1
int m12 = 6; //left motor(s) pwr2
int m1e = 7; //left motor(s) enable

int m21 = 9; //right motor(s) pwr1
int m22 = 10; //right motor(s) pwr2
int m2e = 8; //right motor(s) enable


void setup() {
Serial.begin(9600); // set up Serial Monitor at 9600 bps
Serial.println("Motor test!");

// initialize radio nRF24L01
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();

// initialize digital pins as output for motors.
pinMode(m11, OUTPUT);
pinMode(m12, OUTPUT);
pinMode(m1e, OUTPUT);
digitalWrite(m1e, LOW);
pinMode(m21, OUTPUT);
pinMode(m22, OUTPUT);
pinMode(m2e, OUTPUT);
digitalWrite(m2e, LOW);

} // end of setup

void loop() {

if (radio.available()) {
code = 0;
radio.read(&code, sizeof(code));
Serial.println(code);
motor();
}
delay(20); //little delay for better serial communication

} // end of loop

void motor(){
int speedLevel[11]={-255,-210,-165,-120,-75,0,75,120,165,210,255};
y = int(code /100);
x = code - 100*y;
speedL = speedLevel[y];
Serial.print("code = ");
Serial.print(code);
Serial.print(" y = ");
Serial.print(y);
Serial.print(" x = ");
Serial.print(x);
Serial.print(" speedL = ");
Serial.println(speedL);

//correction of speedLevel for cornering
if (x==0){
right = speedL+60;
left = speedL-60;
}
else if (x==1){
right = speedL+48;
left = speedL-48;
}
else if (x==2){
right = speedL+36;
left = speedL-36;
}
else if (x==3) {
right = speedL+24;
left = speedL-24;
}
else if (x==4) {
right = speedL+12;
left = speedL-12;
}
else if (x==6) {
right = speedL -12;
left = speedL+12;
}
else if (x==7) {
right = speedL-24;
left = speedL+24;
}
else if (x==8) {
right = speedL-36;
left = speedL+36;
}
else if (x==9) {
right = speedL-48;
left = speedL+48;
}
else if (x==10) {
right = speedL-60;
left = speedL+60;
}
else {
right = speedL;
left = speedL;
}

//speedLevel for "left" and "right"
Serial.print("left = ");
Serial.print(left);
Serial.print(" right = ");
Serial.println(right);

// stop
if (left < 63 & left > -63) {
digitalWrite(m1e, LOW);
}
if (right < 63 & right > -63) {
digitalWrite(m2e, LOW);
}
// forward
if (left>=63) {
if (left>255) left=255;
int corrl=int(left * factor);
Serial.print("corrl = ");
Serial.println(corrl);
analogWrite(m11,corrl);
analogWrite(m12, 0);
digitalWrite(m1e, HIGH);
}
if (right>=63) {
if (right>255) right=255;
int corrr=int(abs(right) * factor);
Serial.print("corrr = ");
Serial.println(corrr);
analogWrite(m21, corrr);
analogWrite(m22, 0);
digitalWrite(m2e, HIGH);
}
// backward
if (left<= -63) {
if (left<-255) left=-255;
int corrl=int(abs(left) * factor);
Serial.print("corrl = ");
Serial.println(corrl);
analogWrite(m11,corrl);
analogWrite(m11, 0);
analogWrite(m12, int(abs(left) * factor));
digitalWrite(m1e, HIGH);
}
if (right<= -63) {
if (right<-255) right=-255;
int corrr=int(abs(right) * factor);
Serial.print("corrr = ");
Serial.println(corrr);
analogWrite(m21, 0);
analogWrite(m22, corrr);
digitalWrite(m2e, HIGH);
}
Serial.print("Motorsteuerung okay");
} // end of motor
 

Como se puede ver en la imagen con los cables voladores, el nRF23L01 - y por cierto también el adaptador - no es adecuado para enchufar en la protoboard.

Por lo tanto, aquí de nuevo una imagen del escudo de la palanca de mando, donde se proporciona una ranura para el nRF24L01.


Como recordatorio, aquí el pinout era CE = pin 9, CSN = pin10, eje x = A0, eje y = A1 y botón JoyStick = D8. Con estos cambios, el Sketch Motor Controller funciona.

En general, el transceptor nRF24L01 es una solución barata y buena para el control remoto por radio de nuestros pequeños coches robot.

En las próximas entradas del blog añadiremos sensores al controlador para conseguir un controlador de velocidad y eventualmente poder conducir de forma autónoma.




Für arduino

3 comentarios

Wolfgang Menzel

Wolfgang Menzel

Hallo,
bezüglich NRF24L01 habe ich ein riesen Problem, das mich schon einige Stunden gekostet hat.
Ich verwende einen ESP32 DevKit mit I2C-Display und NRF24L01 als Empfänger zur Anzeigen von Daten. Allerdings ist das Display etwas klein. Ich habe noch ein 4 inch RPI TFT LCD mit Touch. Dieses funktionier am ESP einwandfrei. Allerdings finde ich keine Möglichkeit, das 4 inch Display und den NRF-Empfanger gemeinsam zu betreiben.
Ich verwende folgende includes:
#include
#include
#include

Pinbelegung für:
RF:
SCK:18or MISO:19br MOSI:23gn CE:4sw CNS:2ge +5V:rt GND:bl
TFT:
SCK:18gn MISO:19wß MOSI:23sw CS:15or DC:5ge RST:ENvi TOUCH:26gr +5V:rt GND:bl

(die Buchstaben hinter den Pins sind die Kabelfarben, hier keine relevanz)

Eigentlich sollte es doch so sein, daß der SPI-Bus mehrfach verwendet werden kann, nur CS muss sich unterscheiden. Wo kann also das Problem liegen?

Kann mit jemand helfen?

Mit freundlichen Grüßen
Wolfgang

Walter

Walter

Mit Arduino UNO konnte ich den nRF24L01 nicht zum laufen bringen, zig Internet Beiträge zum trotz.

Da entgegen klappte es mit Arduino NANO und sogar mit ESP32 Dev Kit auf Anhieb.

Rudi Brand

Rudi Brand

Hi, klingt gut! Wäre das eine Möglichkeit, einen Dashbutton-Ersatz zu bauen? Senden direkt auf Tastendruck in einem Batteriebetriebenen Gehäuse und der Empfänger am Netzteil sendet dann per MQTT ins private Netz? Aktuell habe ich einige Buttons mit ESP8266 gebaut, die im Deepsleep sind und nach dem Drücken 3-5s brauchen, bis sie im WLAN sind und mit die Batteriespannung per MQTT liefern..

Deja un comentario

Todos los comentarios son moderados antes de ser publicados