Hola,
Les comparto el uso del modulo nRF24L01+ con arduino y un Sensor te temperatura 18B20.
Diagrama del Transmisor y Sensor
Codigo:
El receptor:
Consta de un Microcontrolador LPC1114 que utiliza la arquitectura ARM CORTEX M0, cuando se reciba un dato por medio del modulo nRF24L01+, este enviara los datos por serial para poder crear un log de temperatura y por medio de excel graficaremos los resultados.
Codigo principal:
Libreria:
.h
.c
Resultado:
Saludos!
Les comparto el uso del modulo nRF24L01+ con arduino y un Sensor te temperatura 18B20.
Diagrama del Transmisor y Sensor
Codigo:
Código:
#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 3
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
#define CE_pin 8
#define CSN_pin 7
#define IRQ_pin 2
#define MOSI_pin 11
#define MISO_pin 12
#define SCK_pin 13
#define W 1
#define R 0
///////////////
//Comandos
//////////////
#define CONFIG B00000000 //CONFIG
#define EN_AA B00000001 //EN_AA
#define EN_RXADDR B00000010 //EN_RXADDR
#define SETUP_AW B00000011 //SETUP_AW
#define STATUS B00000111
#define RX_PW_P0 B00010001
#define RX_PW_P1 B00010010
#define R_RX_PAYLOAD B01100001
#define W_TX_PAYLOAD B10100000
#define FLUSH_TX B11100001
#define FLUSH_RX B11100010
#define RX_ADDR_R0 B00001010
#define TX_ADDR B00010000
byte RXADRESS[5]={0xC3,0xC2,0xC2,0xC2,0xC2};
byte TXADRESS[5]={0xC3,0xC2,0xC2,0xC2,0xC2};
//The global variables used by everyone
byte data_in[5], data2, data3;
byte buffer[7];
byte nn;
int TempValue;
void setup(){
Serial.begin(115200);//start Serial
Serial.println("Conectando...");
delay(100);
sensors.begin();
nRF24L01_init();
}
void loop(){
while(1){
sensors.requestTemperatures();
Serial.print("Temperature is ");
Serial.println(sensors.getTempCByIndex(0));
TempValue=sensors.getTempCByIndex(0)*100;
buffer[0]=TXADRESS[0];
buffer[1]=TXADRESS[1];
buffer[2]=TXADRESS[2];
buffer[3]=TXADRESS[3];
buffer[4]=TXADRESS[4];
buffer[5]=(TempValue>>8)&0xFF;
buffer[6]=TempValue&0xFF;
nRF24L01_Send_Commands_RXTXPAYLOAD(W_TX_PAYLOAD,buffer,7,W);
nRF24L01_Send_Commands_RWregisters(STATUS,0,R);
nRF24L01_Send_Commands_RWregisters(STATUS,(data_in[1]|0x10),W);
delay(1000);
}
}
void nRF24L01_init(void){
/*
Inicializa Pines
*/
pinMode(CE_pin, OUTPUT);//chip enable set as output
pinMode(CSN_pin, OUTPUT);//chip select pin as output
pinMode(MOSI_pin, OUTPUT);//SPI data out
pinMode(MISO_pin, INPUT); //SPI data in
pinMode(SCK_pin, OUTPUT);//SPI clock out
pinMode(IRQ_pin,INPUT);
Serial.println("Inicializacion de Pines");
SPI.setBitOrder(MSBFIRST);//SPI Most Significant Bit First
SPI.setDataMode(SPI_MODE0);// Mode 0 Rising edge of data, keep clock low
SPI.setClockDivider(SPI_CLOCK_DIV2);//Run the data in at 16MHz/2 - 8MHz
digitalWrite(CE_pin, HIGH);//RX mode
digitalWrite(CSN_pin, HIGH);//SPI idle
SPI.begin();//start up the SPI library
Serial.println("nRF Listo!");
nRF24L01_Send_Commands_RWregisters(RX_PW_P0,B00000111,W);
nRF24L01_Send_Address(RX_ADDR_R0,RXADRESS,W);
nRF24L01_Send_Address(TX_ADDR,TXADRESS,W);
nRF24L01_Send_Commands_RWregisters(EN_AA,B00111111,W);
nRF24L01_Send_Commands_RWregisters(CONFIG,B00110010,W);
}
void nRF24L01_Send_Commands_RWregisters(byte cmd,byte value,byte rw){
digitalWrite(CSN_pin, LOW);
data_in[0] = SPI.transfer((cmd|(rw<<5)));
data_in[1] = SPI.transfer(value);
digitalWrite(CSN_pin, HIGH);
}
void nRF24L01_Send_Commands_RXTXPAYLOAD(byte cmd,byte *value,int n,int rw){
int i_;
if(rw==W){
Serial.print("Write data = ");
nRF24L01_Send_Commands_flushRXTX(FLUSH_TX);
}
digitalWrite(CSN_pin, LOW);
data_in[0] = SPI.transfer(cmd);
for(i_=0;i_<n;i_++){
if(rw==W){
data_in[0] = SPI.transfer(*value);
Serial.print(*value,HEX);
}else{
*value = SPI.transfer(0);
}
value++;
}
digitalWrite(CSN_pin, HIGH);
if(rw==W){
Serial.println(" ");
digitalWrite(CE_pin, LOW);//pull CE pin LOW
delay(0.1);
digitalWrite(CE_pin, HIGH);//pull CE pin LOW
}else{
nRF24L01_Send_Commands_flushRXTX(FLUSH_RX);
}
}
void nRF24L01_Send_Commands_flushRXTX(byte cmd){
digitalWrite(CSN_pin, LOW);
data_in[0] = SPI.transfer(cmd);
digitalWrite(CSN_pin, HIGH);
}
void nRF24L01_Send_Address(byte cmd,byte *adr,byte rw){
int _i=0;
digitalWrite(CSN_pin, LOW);
data_in[0] = SPI.transfer((cmd|(rw<<5)));
for(_i=0;_i<5;_i++){
data_in[1] = SPI.transfer(*adr);
adr++;
}
digitalWrite(CSN_pin, HIGH);
}
int nRF24L01_Interrupt(){
int rep=0;
if(digitalRead(IRQ_pin)==0){
rep=1;
}
return rep;
}
El receptor:
Consta de un Microcontrolador LPC1114 que utiliza la arquitectura ARM CORTEX M0, cuando se reciba un dato por medio del modulo nRF24L01+, este enviara los datos por serial para poder crear un log de temperatura y por medio de excel graficaremos los resultados.
Codigo principal:
Código:
///////////////////////////////////////////////////////////
/*
*//**
*@file Main.c
*@Company Ucursos
*@brief
* Firmware para obtener la temperatura por medio de un modulo
* de radiofrecuencia nRF24L01
*@Version 1.2
*@date 13/09/2014
*@author ucursos.blogspot.com
*/
///////////////////////////////////////////////////////////
#include <lpc11xx.h>
#include "SetClock48Mhz.h"
#include "SetUart.h"
#include "nRF24L01.h"
#include "TickTimer.h"
/*________________Defines____________________*/
/*________________Variables____________________*/
uint8_t buffer[7];
//uint16_t t;
uint8_t nn;
uint8_t resp;
uint16_t varTemperature;
float Temperature;
/*********************************************************************//**
* @brief Funcion Principal
* @param[in] None
* @return None
**********************************************************************/
int main (void){
/*Incializa el reloj a 48Mhz*/
SetClockTo48Mhz();
/*Incializa el UART a 115200*/
SetUartTo(115200);
printf("COM Open = 115200 baudrate\r\n");
/*Incializa el nRF24L01+*/
nRF24L01_init(Mode_RX);
printf("Temperature Celsius \r\n");
while(1){
/*Espera si ha recibido algun dato*/
if(nRF24L01_Interrupt()==1){
resp=nRF24L01_Receive_Data(buffer,sizeof(buffer));
//printf("Pipe %u : ",resp);
//for(nn=0;nn<5;nn++){
//printf("%X ",buffer[nn]);
//}
//printf("\r\n");
varTemperature=((buffer[5]<<8)|buffer[6]);
if(varTemperature>0x8000){
Temperature=((float)((0xFFFF-varTemperature))/100)*-1;
}else{
Temperature=(float)varTemperature/100;
}
printf("%0.2f\r\n",Temperature);
for(nn=0;nn<5;nn++){
buffer[nn]=0;
}
}
}
}
Libreria:
.h
Código:
#define Active 1
#define NoActive 0
#define pinCSN_init LPC_GPIO0->DIR |= (1<<2)
#define pinCE_init LPC_GPIO0->DIR|=(1<<1)
#define pinIRQ_init LPC_GPIO0->DIR&=~(1<<11)
#define pinCSN_desactive DesActiveSSP0
#define pinCSN_active ActiveSSP0
#define pinCE_state_desactive LPC_GPIO0->DATA|=(1<<1)
#define pinCE_state_active LPC_GPIO0->DATA&=~(1<<1)
#define pinIRQ_state (LPC_GPIO0->DATA & (1<<11))
#define Mode_RX 2
#define Mode_TX 3
#define W 1
#define R 0
///////////////
//Comandos
//////////////
#define CONFIG 0x00 //CONFIG
#define EN_AA 0x01 //EN_AA
#define EN_RXADDR 0x02 //EN_RXADDR
#define SETUP_AW 0x03 //SETUP_AW
#define STATUS 0x07
#define RX_PW_P0 0x11
#define RX_PW_P1 0x12
#define RX_PW_P2 0x13
#define R_RX_PAYLOAD 0x61
#define W_TX_PAYLOAD 0xA0
#define FLUSH_TX 0xE1
#define FLUSH_RX 0xE2
#define RX_ADDR_R0 0x0A
#define TX_ADDR 0x10
uint8_t nRF24L01_Receive_Data(uint8_t *value,uint8_t n);
void nRF24L01_return_address(uint8_t *value,uint8_t _dir);
void nRF24L01_Send_Data(uint8_t *value,uint8_t n);
uint8_t nRF24L01_Interrupt(void);
void nRF24L01_Send_Commands_flushRXTX(uint8_t cmd);
void nRF24L01_Send_Commands_RXTXPAYLOAD(uint8_t cmd,uint8_t *value,uint8_t n,uint8_t rw);
void nRF24L01_Send_Address(uint8_t cmd,uint8_t *adr,uint8_t rw);
void nRF24L01_Send_Commands_RWregisters(uint8_t cmd,uint8_t value,uint8_t rw);
void nRF24L01_init(uint8_t mode);
.c
Código:
#include <LPC11xx.h>
#include "nRF24L01.h"
#include "TickTimer.h"
#include "SPI.h"
uint8_t data_in[5];
uint8_t RXADRESS[5]={0x17,0x17,0x17,0x17,0x17};
uint8_t TXADRESS[5]={0xE7,0xE7,0xE7,0xE7,0xE7};
/*********************************************************************//**
* @brief Funcion para checar el Pin de IRQ del modulo nRF24L01+
* @param[in] None
* @return rep: Regresa 1 si se activo el pin IRQ
* Regresa 0 si no se activo el pin IRQ
**********************************************************************/
uint8_t nRF24L01_Interrupt(void){
uint8_t rep=0;
if(!pinIRQ_state){
rep=1;
}
return rep;
}
/*********************************************************************//**
* @brief Funcion para eliminar el buffer de TX o RX
* @param[in] cmd: Comando para eliminar el buffer de TX o RX
* @return None
**********************************************************************/
void nRF24L01_Send_Commands_flushRXTX(uint8_t cmd){
pinCSN_active;
data_in[0] = SPI_Transmit(cmd);
pinCSN_desactive;
}
/*********************************************************************//**
* @brief Funcion para leer o escribir en el modulo nRF24L01+
* @param[in] cmd: Comando para activar la transmision o recepcion
* @param[in] *value: Buffer donde se almacenara o enviara los datos.
* @param[in] n: Tamaño del buffer
* @param[in] rw: Varable que indica si sera escritura o lectura
* @return None
**********************************************************************/
void nRF24L01_Send_Commands_RXTXPAYLOAD(uint8_t cmd,uint8_t *value,uint8_t n,uint8_t rw){
int i_;
if(rw==W){
nRF24L01_Send_Commands_flushRXTX(FLUSH_TX);
}
pinCSN_active;
data_in[0] = SPI_Transmit(cmd);
for(i_=0;i_<n;i_++){
if(rw==W){
data_in[0] = SPI_Transmit(*value);
}else{
*value = SPI_Transmit(0);
}
value++;
}
pinCSN_desactive;
if(rw==W){
pinCE_state_active;
delay_ms(100);
pinCE_state_desactive;
}else{
nRF24L01_Send_Commands_flushRXTX(FLUSH_RX);
}
}
/*********************************************************************//**
* @brief Funcion para enviar la direccion
* @param[in] cmd: Comando para activar el transmisor o receptor
* @param[in] *adr: Buffer donde se almacenara la direccion
* @param[in] rw: Varable que indica si sera escritura o lectura
* @return None
**********************************************************************/
void nRF24L01_Send_Address(uint8_t cmd,uint8_t *adr,uint8_t rw){
uint8_t _i=0;
pinCSN_active;
data_in[0] = SPI_Transmit((cmd|(rw<<5)));
for(_i=0;_i<5;_i++){
data_in[1] = SPI_Transmit(*adr);
adr++;
}
pinCSN_desactive;
}
/*********************************************************************//**
* @brief Funcion para enviar comandos a los registros
* @param[in] cmd: Comando para activar el transmisor o receptor
* @param[in] value: valor de registro del comando
* @param[in] rw: Varable que indica si sera escritura o lectura
* @return None
**********************************************************************/
void nRF24L01_Send_Commands_RWregisters(uint8_t cmd,uint8_t value,uint8_t rw){
pinCSN_active;
data_in[0]=SPI_Transmit((cmd|(rw<<5)));
data_in[1]=SPI_Transmit(value);
pinCSN_desactive;
}
/*********************************************************************//**
* @brief Funcion para enviar un buffer de datos
* @param[in] *value: Datos del buffer de datos a enviar
* @param[in] n: Tamaño del buffer a enviar
* @return None
**********************************************************************/
void nRF24L01_Send_Data(uint8_t *value,uint8_t n){
nRF24L01_Send_Commands_RXTXPAYLOAD(W_TX_PAYLOAD,value,n,W);
nRF24L01_Send_Commands_RWregisters(STATUS,0,R);
nRF24L01_Send_Commands_RWregisters(STATUS,(data_in[1]|0x10),W);
}
/*********************************************************************//**
* @brief Funcion para devolver el valor de la direccion de TX o RX
* @param[in] *value: Datos del buffer de datos a recibir
* @param[in] _dir: Direccion de TX o RX
* @return None
**********************************************************************/
void nRF24L01_return_address(uint8_t *value,uint8_t _dir){
uint8_t _x_=0;
if(_dir==1){
for(_x_=0;_x_<sizeof(TXADRESS);_x_++){
(*value++)=TXADRESS[_x_];
}
}else{
for(_x_=0;_x_<sizeof(TXADRESS);_x_++){
(*value++)=RXADRESS[_x_];
}
}
}
/*********************************************************************//**
* @brief Funcion para obtener los datos de una recepcion de datos
* @param[in] *value: Datos del buffer de datos a recibir
* @param[in] n: Numero de datos a recibir
* @return None
**********************************************************************/
uint8_t nRF24L01_Receive_Data(uint8_t *value,uint8_t n){
nRF24L01_Send_Commands_RWregisters(STATUS,0,R);
data_in[2]=((data_in[1]&0x0E)>>1);
nRF24L01_Send_Commands_RXTXPAYLOAD(R_RX_PAYLOAD,value,n,R);
nRF24L01_Send_Commands_RWregisters(STATUS,0x40,W);
return data_in[2];
}
/*********************************************************************//**
* @brief Fucnion de Inicializacion
* @param[in] mode: Modo de inicio del Modulo TX o RX
* @return None
**********************************************************************/
void nRF24L01_init(uint8_t mode){
pinCSN_init;
pinCE_init;
pinIRQ_init;
pinCE_state_desactive;
pinCSN_desactive;
SPI_Init();
nRF24L01_Send_Commands_RWregisters(CONFIG,0,R);
if(mode==Mode_RX){
nRF24L01_Send_Commands_RWregisters(RX_PW_P0,0x07,W);
nRF24L01_Send_Commands_RWregisters(RX_PW_P1,0x07,W);
nRF24L01_Send_Commands_RWregisters(RX_PW_P2,0x07,W);
nRF24L01_Send_Commands_RWregisters(EN_RXADDR,0x07,W);
nRF24L01_Send_Commands_RWregisters(EN_AA,0x3F,W);
nRF24L01_Send_Commands_RWregisters(CONFIG,0x33,W);
}else{
nRF24L01_Send_Commands_RWregisters(RX_PW_P0,0x05,W);
nRF24L01_Send_Address(RX_ADDR_R0,RXADRESS,W);
nRF24L01_Send_Address(TX_ADDR,TXADRESS,W);
nRF24L01_Send_Commands_RWregisters(CONFIG,0x32,W);
}
}
Resultado:
Saludos!
Última edición por un moderador: