[Aporte] Arduino + nRF24L01 + 18D20

Hola,

Les comparto el uso del modulo nRF24L01+ con arduino y un Sensor te temperatura 18B20.

Diagrama del Transmisor y Sensor

Temperatura%2B%2B%2Barduino.jpg


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.

Diagrama_de_receptor.jpg


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:

Temperatura.png



Saludos!
 
Última edición por un moderador:
Atrás
Arriba