Comunicación bidireccional con nRF24L

         
El nRF24L10 es un módulo de radiofrecuencia en 2,4GHz. Tiene importantes ventajas:

-Pequeño  tamaño
-Consumo reducido (alimentación con el pin de 3,3 voltios del Arduino)
-Pines tolerantes a lógica de 5 voltios.
-Alcance mayor que bluetooth y hay módulos más potentes con antenas para distancias de 1000mts.
-Puede transmitir y recibir posibilitando comunicación en ambos sentidos.
-Son muy baratos.
          En este montaje se usan dos nRF24L con sus correspondientes Arduinos
          En uno de los Arduinos se añade un potenciometo en A0 y un display LCD (i2c)
          En el otro hay un ventilador de PC que nos da por el cable azul las RPM y por el amarillo permite un control PWM de su velocidad de giro. Para medir la RPM hay que unir el cable azul a positivo con una resistencia de 4k7. Supongo que por seguridad, el ventilador nunca se para del todo aún con  PWM bajos.
           Al girar el potenciometro el nRF24L envia al segundo el valor PWM, que al ser recibido por el segundo nRF24L es suministrado al ventilador e inmediatamente retransmite al primero las nuevas RPM leidas. Estos dos valores, PWM y RPM pueden leerse en el display del primer Arduino.
           Las conexiones de los nRF24L pueden verse en el código del Arduino.
/*
Emite PWM y recibe RPM en Arduino con NRF24L01 y
comunicación bidireccional

  NRF24L01  Arduino pin
  VCC       3.3 V
  GND       GND
  CS            8
  CE            7
  MOSI      11
  MISO      12
  SCK       13
*/

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include "RF24.h"
#include <MillisTimer.h>  //libreria Millis para no usar delay()
LiquidCrystal_I2C lcd(0x20, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);//Direccion de LCD
MillisTimer timer(1100); //envia datos cada ''
float data[1];   //los datos a emitir
float orden[1]; //Ordenes que se reciben
int sensorPin0 = A0;
int sensorValue = 0;        // valor leido del potenciometro
int pwm = 0;        // valor de PWM (analog out)

RF24 NRF24L01 (7, 8);//crea objecto NRF24L01. Especifica el pin CE y CSN pins usados en Arduino
byte address[] [6] = {"pipe1", "pipe2"};//set addresses of the 2 pipes for read and write


void setup() {                   
  Serial.begin(9600);
  lcd.begin(16,2);// Indicamos medidas de LCD 
  lcd.clear();//Elimina todos los simbolos del LCD 
  lcd.setCursor(0,0);//Posiciona la primera letra despues del segmento 5 en linea 1  
  lcd.setCursor(0, 0);
  lcd.print("PWM:");
  lcd.setCursor(0, 1);
  lcd.print("RPM:"); 
  timer.setTimer();
  NRF24L01.begin();
  NRF24L01.openReadingPipe(1, address[0]);//abre canal de lectura para dirección pipe 1
  NRF24L01.openWritingPipe(address[1]);//abre canal de escritura para address pipe 2

  NRF24L01.setPALevel(RF24_PA_MAX);// potencia emisión mínimo RF24_PA_MIN o máximo RF24_PA_MAX)
  NRF24L01.setDataRate(RF24_250KBPS);//set datarate to 250kbps
  NRF24L01.setChannel(110);//set frecuencia canal 110
}

void loop() {
                            //TRANSMITE analógico0 (pwm) al otro Arduino
  delay(10);
  NRF24L01.stopListening();
//  delay(10);
  if(timer.checkTimer()){  //Transmite los datos cada 5''
   delay(10);   
   sensorValue = analogRead(sensorPin0);      // lee analógico 0:
   pwm = map(sensorValue, 0, 1023, 0, 255);   // map it to the range of the analog out:
   data[0]=pwm; 
   lcd.setCursor(4, 0); lcd.print("   "); 
   lcd.setCursor(4, 0);lcd.print(pwm);
   NRF24L01.write(data, sizeof(data));//Envia dato al otro Arduino
  }



                     //RECIBE ordenes desde el Arduino

  NRF24L01.startListening();
  delay(10);
  if (NRF24L01.available()){          //¿Hay transmision desde el otro Arduino?
    NRF24L01.read(orden,sizeof(orden));
    int rpm=orden[0];  //para quitar decimales
    lcd.setCursor(4, 1); lcd.print("     "); 
    lcd.setCursor(4, 1);lcd.print(rpm);
    Serial.print("PWM= ");
    Serial.print(data[0]);
    Serial.print("----"); 
    Serial.print("RPM= ");
    Serial.println(orden[0]);  
    NRF24L01.stopListening();
  }
}
/*
Recibe PWM y emite RPM en Arduino con NRF24L01 y
comunicación bidireccional

  NRF24L01  Arduino pin
  VCC       3.3 V
  GND       GND
  CS           8
  CE           7
  MOSI      11
  MISO      12
  SCK       13
*/

#include <SPI.h>
#include "RF24.h"
#include <MillisTimer.h>  //libreria par aevitar uso de delay()
const int analogOutPin = 3; // Salida control PWM
byte outputValue = 0;        // valor del PWM

MillisTimer timer(1000); //envia datos cada 1''
float data[1];
float orden[2];

//Medir RPM ventilador PC 4 hilos
// pin 2 cable azul rpm
unsigned long lastPulseTime;
unsigned long pulseInterval;
unsigned long lastUpdateTime;


RF24 NRF24L01 (7, 8);//crea objecto NRF24L01. Especifica pines CE y CSN  en Arduino
byte address[] [6] = {"pipe1", "pipe2"};//set addresses of the 2 pipes for read and write


//  Deteccion del pulso de rotacion
void senseRotation( void ) {
unsigned long cur = micros ();
unsigned long dif = cur - lastPulseTime; //  diferencia entre la bajada previa
pulseInterval = (pulseInterval - (pulseInterval >> 2)) + (dif >> 2); 
lastPulseTime = cur;
}



void setup() {
  Serial.begin(9600);
  timer.setTimer();
  lastPulseTime = 0; pulseInterval = 0;
  attachInterrupt (0, senseRotation, FALLING ); //  0 = D2, FALLING = falling
  NRF24L01.begin();
  //Abre "the pipes" para recibir y emitir desde placa 1
  NRF24L01.openWritingPipe(address[0]);               //abre escritura pipe 1
  NRF24L01.openReadingPipe(1, address[1]);          //abre lectura pipe 2
//set RF power output to minimum, RF24_PA_MIN (change to RF24_PA_MAX if required)
  NRF24L01.setPALevel(RF24_PA_MAX);  NRF24L01.setDataRate(RF24_250KBPS);  //velociad a 250kbps
  NRF24L01.setChannel(110);    //Usar canal 110
}


void loop() {
unsigned long cur = millis ();
if (cur - lastUpdateTime > 60){                      // 60ms actualiza intervalo LED
  uint16_t rpm = 60000000 / (pulseInterval * 2);     // Encuentra RPM
  orden[0]=rpm;
  Serial.print("---");Serial.println(rpm);
  lastUpdateTime = cur; lastUpdateTime = cur;
}

                        //TRANSMITE button change to the other Arduino
delay(10);
NRF24L01.stopListening();
if(timer.checkTimer()){           //Transmite los datos cada 1''
   delay(10);
//  orden[0]=rpm;
   orden[1]=02;
   NRF24L01.write(orden, sizeof(orden));//send LOW state to other Arduino board
  }



                       //RECIBE cambios desde el Arduino que genera datos de pwm
  NRF24L01.startListening();
  delay(10);
  if (NRF24L01.available()){             
    NRF24L01.read(data,sizeof(data));
    outputValue=data[0];
    analogWrite(analogOutPin, outputValue);
    Serial.print("PWM= " );
    Serial.print(data[0]);
    Serial.println("");   
    NRF24L01.stopListening();
  }
}
         

Menu