domingo, 26 de julio de 2015

nRF24L01 Control de 2 servos + 1 servo o motor



nRF24L01
Control de 2 servos + 1 servo o motor
xsetaseta@gmail.com


Revisión del circuito. 17/11/2017
Después de bastante tiempo de realizar el montaje, tuve la necesidad de hacer otro montaje con el nRF24.
Montado todo bien no me funcionaba, o el funcionamiento era errático.
Después de muchas pruebas, descubrí que en algún que otro módulo se necesitaba un condensador entre Vcc y GND.
Colocados los condensadores en todos los módulos el funcionamiento era correcto.

____________________________________________________________

En este montaje he utilizado dos placas arduino y dos módulos nRF24L01 para el control de 2 servos  y un motor de DC o 1 servo.
El control se realiza desde el circuito emisor donde existen 3 potenciómetros a modo de joystick, donde 2 hacen de modo coordenadas  X-Y , y el tercer potenciómetro a modo de control de potencia.
Mi objetivo era realizar el control de un avión RC de ala fija, donde el control se realiza con el timón de dirección y con el timón de profundidad, y la potencia del motor con el tercer potenciómetro de potencia.
En este montaje solo he utilizado el modo de transmisión de un módulo emisor  a el otro módulo receptor.
El nRF24L01+ integra un completo transceptor RF de 2,4 GHz, un sintetizador de RF y toda la lógica de banda base incluyendo un acelerador de protocolo por hardware Enhanced ShockBurstTM con una interfaz  SPI de alta velocidad para el controlador de la aplicación. El módulo Transceptor es de baja potencia y corto alcance, 200 metros más o menos.
Estos transceivers utilizan la banda de 2,4 GHz como muchos routers WiFi, algunos teléfonos inalámbricos, etc y no necesitan licencia. Estos transceptores pueden tanto enviar, como recibir datos en “paquetes” de varios bytes a la vez.

La librería utilizada es la RF24             https://github.com/maniacbug/RF24






Conexión del Arduino al nFR24L01
3V3 ----VCC (3.3V )
pin D8-----------CE (chip enable in)
pin D7----------CSN (chip select in)
SCK pin D13----------SCK (SPI clock in)
MOSI pin D11----------SDI (SPI Data in)
MISO pin D12----------SDO (SPI data out)
GND----------GND


Los pin CE y CS se pueden cambiar a otros pin del arduino en el programa.
//RF24 (cepin, cspin)
RF24 radio(8,7);


La alimentación del nFR24L01 debe estar entre 1.9 to 3.6V, por lo cual debemos utilizar la salida de 3.3V del arduino. En algunas páginas recomiendan colocar un condensador en la salida de 3.3V para minimizar posibles caídas de tensión debido a un consumo puntual alto.

Para el control de potencia del motor DC se utiliza el modo PWM (control mediante ancho de pulso) que maneja un MOSFET IRF630, es el que tenía a mano, puede servir cualquier otro.



Los servos se controlan mediante el ancho de pulso.


Emisor


Programa emisor Arduino
//xsetaseta@gmail.com
#include <SPI.h>
#include <nRF24L01.h>

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


#define debug 0

int sensorPin1 = A0;
int sensorPin2 = A1;
int sensorPin3 = A2;

unsigned char cadena[10];

RF24 radio(8,7);

unsigned int z;

// Topology
// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

void setup(void)
{

  Serial.begin(9600);

  radio.begin();
  radio.setRetries(15,15);
  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);
  Serial.println("Transmitiendo datos");
}

void loop(void)
{
    radio.stopListening();
    cadena[0]='A';
    cadena[1] = analogRead(sensorPin1)>>2;
    cadena[2] = analogRead(sensorPin2)>>2;
    cadena[3] = analogRead(sensorPin3)>>2;
    cadena[4] = 'A';
    cadena[5] = 'A';
#if debug    
    Serial.print(cadena[1],DEC);Serial.print(" ");
    Serial.print(cadena[2],DEC);Serial.print(" ");
    Serial.print(cadena[3],DEC);
#endif     
    enviarS();    
    radio.startListening();  
    delay(21); //20
  
}

void enviarS()
{
    if (radio.write( cadena, 6 ))
      { Serial.println(" ok send.");}
    else
      { Serial.println(" failed send.");}
}


Receptor


Programa receptor Arduino
//xsetaseta@gmail.com
#include <SPI.h>
#include <nRF24L01.h>

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

#include <Servo.h>

#define debug 0

Servo myservo1;
Servo myservo2;
Servo myservo3;

int posicion;

bool done;

const int analogOutPin = 5;

unsigned char cadena[10];
int z;

//RF24 (cepin, cspin) 
RF24 radio(8,7);

// Topology
// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

void setup()
{
  Serial.begin(9600);
  myservo1.attach(2);
  myservo2.attach(3);
  myservo3.attach(4);
  
  radio.begin();
  radio.setRetries(15,15);
  radio.startListening();
  radio.openWritingPipe(pipes[1]);
  radio.openReadingPipe(1,pipes[0]);
  Serial.println("Esperando datos");
}

void loop()
{
  delay(10);
  if ( radio.available() )
    {
      done = false;
      while (!done)
        {
        done = radio.read( cadena, 6);
#if debug        
         Serial.print(cadena[0]);Serial.print(" ");
         Serial.print(cadena[1],DEC);Serial.print(" ");
         Serial.print(cadena[2],DEC);Serial.print(" ");
         Serial.print(cadena[3],DEC);Serial.println(" ");
#endif      
         z=cadena[0];
         switch(z)
          {
           case 65:
              posicion = map(cadena[1], 0, 254, 0, 179); myservo1.write(posicion);
              posicion = map(cadena[2], 0, 254, 0, 179); myservo2.write(posicion);
              posicion = map(cadena[3], 0, 254, 0, 179); myservo3.write(posicion);
              analogWrite(analogOutPin, cadena[3]);
             break;
          }

        radio.stopListening();
       delay(10);
        radio.startListening();
        }
    }
}

Los dos servos se controlan desde los pins D2 y D3 .
Como podemos ver podemos controlar un tercer servo en el pin D4 o un motor DC se utiliza el modo PWM en el pin D5.
El sistema funciona en prototipo, pero no lo he montado en circuito impreso, ni montado en el avión como me hubiera gustado hacer.
Tampoco he probado el alcance real en campo abierto para ver el alcance real. Cierto es que si necesitamos mucho más alcance existe un módulo nFR24L01 con antena que promete llegar hasta 1Km.
La alimentación normal de todo el circuito es de 5V a excepción del módulo nFR24L01 que es de 3.3V , pero lo he alimentado todo a 3.4V y funciona perfectamente.

Librerías
Programas


Hasta pronto.
Juan Galaz


BIBLIOGRAFÍA

https://github.com/maniacbug/RF24
https://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
http://openhardware.pe/transceptores-nrf24l01-2-4ghz-radio-wireless-how-to/
http://cursos.olimex.cl/tutoriales/
http://www.electroensaimada.com/servomotor.html
http://arduino.cl/servo-motor-con-arduino/


26 comentarios:

  1. Excelente, voy a utilizarlo en un camion que me estoy haciendo, pero por curiosidad, como puedo hacer para que el motor dc me funcione en ambos sentidos, pensaba utilizar un L298N que tengo, pero no se si esta contemplado en el codigo el cambio de direccion del motor

    ResponderEliminar
  2. hola que tal gracias por toda esta información
    una pregunta los joystick son como los de Xbox y PlayStation??
    saludos y nuevamente gracias

    ResponderEliminar
  3. Hola
    Todos joystick, normalmente, utilizan potenciometros para el control.
    Lo que pasa que para transmitir información a la consola u ordenador, se codifican y transforman la información para tranmitirla en serie, usb, i2c, etc..
    Si quieres utilizar estos mandos debes aislar los potenciometros que llevan.
    Lo mejor es utilizar algún mando averiado que tenga la electrónica estropeadda, pero los potenciometros en uso.

    ResponderEliminar
    Respuestas
    1. tengo los joystick desmontados del mando pero nose como conectar esos es lo mismo que un potenciómetro?
      los conecto normal y ya para que giren en x cambio la posición para acelerar girar etc..no? es que tengo un avión a escala p-51 modifique tu código para tren de aterrizaje y demás cosas gracias de nuevo

      Eliminar
  4. bueno ya resolví todo eso de los joysticks pero tengo problemas con el motor al momento de yo prender arduino me falla el motor sólo como que vibra y no da vuelta nose si podrías ayudarme en eso
    gracias y feliz año

    ResponderEliminar
  5. Hola
    Lo primero que debes saber es que los motores consumen bastante corriente.
    Antes de conectar un motor, coloca un Led, y mira si aumenta o disminuye el brillo. Si funciona con un Led, es que has alimentado el motor a traves del regulador del arduino, y este no da la suficiente potencia.
    Debes alimentar la parte del motor directamente a una fuente de 5V, no a traves del arduino, seguro que es eso.
    Saludos
    Juan

    ResponderEliminar
  6. hola:
    pregunta: a que se refiere con 65:
    z=cadena[0];
    switch(z)
    {
    case 65: <------ ?

    ResponderEliminar
  7. Hola que tal disculpa es posible cambiar el transistor por un controlador de velocidad bushed? ???

    ResponderEliminar
  8. No te lo puedo decir, hay motores con escobillas y sin ellas.
    El circuito modula la anchura del pulso para controlar la potencia de salida.
    Este circuito funciona con motores de escobillas.

    ResponderEliminar
  9. si de echo el motor es de escobillas pero tengo el controlador de velocidad para ese motor, que al parecer funciona igual que un servo solo hay que meterle el voltaje directo
    bueno eso pienso yo.

    ResponderEliminar
    Respuestas
    1. Entonces alimenta el motor directamente y el control lo haces con la salida para servo.

      Eliminar
  10. Hola buen dia, una pregunta, que es lo que hace las lineas de codigo: analogRead(sensorPin1)>>2 que hace el >>2

    ResponderEliminar
  11. Hola.
    Como la lectura analógica tiene 1024 valores, la divido entre 4, que es lo mismo que desplazar a la derecha 2 bits(numero>>2). De esta forma quitas que vibre continuamente el servo.
    Saludos.

    ResponderEliminar
  12. como puedo controlar cuatro motores con un joystick y el nRF24L01.

    Estoy usando un arduino , el SHIELD 4 MOTORES, un joystick con cuatro pulsadores al que se le puede conectar un nrf24l01. Pero tengo varios problemas con las conexiones y el código. Alquilen que haya hecho algo parecido podría ayudarme. Dejo mi correo por si acaso. josepo3012@hotmail.com Un saludo

    ResponderEliminar
    Respuestas
    1. https://m.youtube.com/watch?t=6s&v=_q9Nl4RcN8AA
      Vídeo de control de 4 motores 3 servos esta en ruso pero viene todo

      Eliminar
    2. Lo he visto, y parece buen proyecto.
      https://yadi.sk/d/Qs_RZDQh33wbDB

      Eliminar
  13. hola quetal, alguien podria decirme que transistor ultiliza para el control del motor gracias....

    ResponderEliminar
  14. Hola

    He utilizado uno que tenía de reciclado en concreto
    MOSFET IRF630
    Puede servir cualquiera que aguante la intensidad que desees en el motor.

    Saludos

    ResponderEliminar
  15. Pues si entiendes lo que es un motor de DC y lo que es PWM (variar el ancho del pulso) ya esta, con un transistor que de la suficiente potencia para mover el motor que tengas.

    ResponderEliminar
  16. disculpa, he inentado con su codigo pero no me aparece nada en el recpetor, solo dice esperando datos pero no hace nada tendra alguna idea de que es lo que sucede? ademas le he quitado donde dice done= radio.write ya que me aparece un error en compilacion me dice que no se puede poner el done.

    ResponderEliminar
  17. Hola.
    Hace ya 2 años que hice el montaje y funcionaba perfectamente.
    Existen varios tipos de 24L01, y no todos son totalmente compatibles unos con otros.
    En cuanto al error compilando el programa es raro, si utilizas la librería descrita debería funcionar,a no ser que hayan modificado la librería(es raro) .
    También he comprobado que de compilar con unas versiones a otras de arduino puede dar errores en algunos programas. Por aquel entonces compilaba con la 1.05 . Posteriormente indicaba la versión del arduino que utilizaba, de esta forma evito errores.
    Saludos
    Juan

    ResponderEliminar
  18. tengo un error en done = radio read (cadena = 6); que se puede hacer

    ResponderEliminar
  19. Hola

    Si tienes ese error significa que utilizas la última versión de la librería, no la librería que proporciono yo en el montaje.

    En las últimas librerías han cambiado la función radio-read , ahora no devuelve nada.

    Si con cambias la librería, prueba con esto:


    void loop()
    {
    delay(1);
    while(radio.available())
    {
    radio.read(dato, 6);
    Serial.println(dato);
    done=1;
    }
    if (done)
    {
    z=cadena[0];
    switch(z)
    {
    case 65:
    posicion = map(cadena[1], 0, 254, 0, 179); myservo1.write(posicion);
    posicion = map(cadena[2], 0, 254, 0, 179); myservo2.write(posicion);
    posicion = map(cadena[3], 0, 254, 0, 179); myservo3.write(posicion);
    analogWrite(analogOutPin, cadena[3]);
    break;
    }
    done=0;
    }
    }

    ResponderEliminar
    Respuestas
    1. me podrias enviar un mail con el codigo terminado?
      lauta1267@gmail.com

      Eliminar
  20. Hola

    El código se encuentra arriba, en la descripción.

    Saludos

    ResponderEliminar