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(); } }