  | 
	  | 
		 
	 
	
		| View previous topic :: View next topic   | 
	 
	
	
		| Author | 
		Message | 
	 
	
		
			Randy Guest
 
 
 
 
  
			
			
			
			
			
			
			
			
			
			
  
		  | 
		
			
				| Help using enhanced shockburst for the NRF24L01 | 
			 
			
				 Posted: Mon Oct 06, 2008 8:32 am     | 
				     | 
			 
			
				
  | 
			 
			
				I have working code for the NRF24L01 transceiver.  Works great if I use the transceiver as is. Can anyone shed some light on how to use enhanced shockburst with the driver I have written.  I tried enabling auto ACk and set the CRC but it doesn't seem to work.
 
 
Thanks 
 
 
NRF24L01 DRIVER
 
 	  | Code: | 	 		  
 
/**************** Preprocessor Constants ***************************************/
 
#define CONFIG             0x20
 
#define EN_AA              0x21
 
#define EN_RXADDR          0x22
 
#define SETUP_AW           0x23
 
#define SETUP_RETR         0x24
 
#define RF_CH              0x25
 
#define RF_SETUP           0x26
 
#define STATUS             0x27
 
#define RX_ADDR_P0         0x2A
 
#define TX_ADDR            0x30
 
#define RX_PW_P0           0x31
 
#define FLUSH_TX           0xE1
 
#define FLUSH_RX           0xE2
 
#define TX_PAYLOAD         0xA0
 
#define RX_PAYLOAD         0x61
 
#define NO_OP              0xFF
 
#define ZERO               0x00
 
#define EOT                0x04
 
#define PAYLOAD_SIZE       0x20 
 
#define start_transmit    {output_high(rf_CE);delay_us(20);output_low(rf_CE);}  //Pulse NRF24L01 CE pin for 20us
 
 
int1 rf_interrupt=false;                                                        // Declare interrupt flag default is false
 
static int16 rf_CE,rf_CSN;                                                      // Declare NRF24L01 SPI CE & CSN pins 
 
 
/**************** Gets The Length Of A Data Packet *****************************/
 
unsigned int* length(unsigned int *data)
 
{
 
   int *cnt;                                                                    // Declare a pointer
 
   for (cnt = data; *cnt != 0; cnt++);                                          // Loop
 
   return(cnt - data);                                                          // Return the length of the data                             
 
}
 
 
/**************** Write To NRF24L01 Configuration Register *********************/
 
void set_register(unsigned int command,unsigned int data) 
 
{
 
   output_low(rf_CSN);                                                          // Engage SPI chip select
 
   spi_write(command);                                                          // Write to register
 
   if(data!=NO_OP){spi_write(data);}                                            // Write data to register 
 
   output_high(rf_CSN);                                                         // Dis-engage SPI chip select
 
   delay_us(10);
 
}
 
 
/**************** Write To NRF24L01 Configuration Register *********************/
 
void set_register(unsigned int command,unsigned int* data) 
 
{
 
   int i,len;
 
   len=length(data);                                                            // Get the length of the data
 
   output_low(rf_CSN);                                                          // Engage SPI chip select
 
   spi_write(command);                                                          // Write to register
 
   for(i=0;i<len;i++){spi_write(data[i]);}                                      // Write data to register 
 
   output_high(rf_CSN);                                                         // Dis-engage SPI chip select
 
   delay_us(10);
 
}
 
 
/**************** Enables NRF24L01 Transmit/Receive Mode ***********************/
 
void transmit_mode(unsigned int1 enable) 
 
{
 
   output_low(rf_CE);                                                           // Disable receiver
 
   set_register(STATUS,0x7E);                                                   // Clear all interrupts
 
   if(enable)
 
   {
 
      set_register(FLUSH_TX,NO_OP);                                             // Flush TX FIFO buffer
 
      set_register(CONFIG,0x52);                                                // Power up in select transmit mode
 
   }
 
   else
 
   {
 
      set_register(FLUSH_RX,NO_OP);                                             // Flush RX FIFO buffer
 
      set_register(CONFIG,0x33);                                                // Power up in receive mode
 
      output_high(rf_CE);                                                       // Enable receiver
 
      delay_us(130);                                                            // Delay 130us
 
   }
 
}
 
 
/**************** Transmits A Single Byte **************************************/
 
void rf_transmit(unsigned int data) 
 
{
 
   transmit_mode(true);                                                         // Enable transmit mode
 
   output_low(rf_CSN);                                                          // Engage SPI chip select
 
   spi_write(TX_PAYLOAD);                                                       // Select tx payload register
 
   spi_write(data);                                                             // Write data to tx payload register
 
   spi_write(EOT);                                                              // End of transmission 
 
   output_high(rf_CSN);                                                         // Dis-engage SPI chip select
 
   start_transmit;                                                              // Start transmission 
 
   transmit_mode(false);                                                        // Enable receive mode 
 
   delay_ms(50);                                                                // Delay 50ms
 
}
 
 
/**************** Transmits A String Of Data ***********************************/
 
void rf_transmit(unsigned char *string) 
 
{
 
   int i,len=0;
 
   len=length(string);                                                          // Get the length of the data to transmit
 
   transmit_mode(true);                                                         // Enable transmit mode
 
   output_low(rf_CSN);                                                          // Engage SPI chip select
 
   spi_write(TX_PAYLOAD);                                                       // Select tx payload register
 
   for(i=0;i<len;i++){spi_write(string[i]);}                                    // Write data to tx payload register
 
   spi_write(EOT);                                                              // End of transmission
 
   output_high(rf_CSN);                                                         // Dis-engage SPI chip select
 
   start_transmit;                                                              // Start transmission 
 
   transmit_mode(false);                                                        // Enable receive mode
 
   delay_ms(50);                                                                // Delay 50ms
 
}
 
 
/**************** Receive RF Data **********************************************/
 
unsigned int* rf_receive() 
 
{
 
      int i;
 
      static int rf_rx_buffer[PAYLOAD_SIZE]={0};                                // Declare a receive buffer  
 
      rf_interrupt = false;                                                     // Clear interrupt flag
 
      output_low(rf_CE);                                                        // Disable receiver
 
      output_low(rf_CSN);                                                       // Engage SPI chip select
 
      spi_write(RX_PAYLOAD);                                                    // Initialize RX payload register
 
      for(i=0;i<=PAYLOAD_SIZE;i++)                                        
 
      {
 
         rf_rx_buffer[i]=spi_read(RX_PAYLOAD);                                  // Copy data from NRF24L01 to buffer
 
         if(rf_rx_buffer[i]==EOT){rf_rx_buffer[i]=ZERO;break;}                  // Stop when EOT found
 
      }
 
      output_high(rf_CSN);                                                      // Dis-engage SPI chip select  
 
      transmit_mode(false);                                                     // Enable receive mode 
 
      return rf_rx_buffer;                                                      // Return received payload
 
}
 
 
/**************** Checks The Status Register ***********************************/
 
void check_interrupt() 
 
{
 
   int i,reg;
 
   output_low(rf_CSN);                                                          // Engage SPI chip select
 
   for(i=0;i<5;i++){reg=spi_read(0x07)&0xFF;}                                   // Read 5 chars of data from NRF24L01 RX register
 
   output_high(rf_CSN);                                                         // Dis-engage SPI chip select  
 
   if(reg>>6){rf_interrupt = true;}                                             // If RX_DR set,set data ready flag
 
   else{set_register(STATUS,0x7E);}                                             // Clear all interrupts
 
} 
 
 
/**************** Initialize NRF24L01 Chip *************************************/
 
void setup_rf(unsigned int16 CE,unsigned int16 CSN,unsigned int* address,unsigned int CH,unsigned boolean Mbps,unsigned int dBm) 
 
{
 
   rf_CE=CE;                                                                    // Define CE pin
 
   rf_CSN=CSN;                                                                  // Define CSN pin
 
   setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_XMIT_L_TO_H|SPI_CLK_DIV_64);             // Setup hardware spi
 
   output_low(rf_CE);                                                           // Disable receiver
 
   set_register(CONFIG,0x31);                                                   // Power down chip
 
   set_register(RF_CH,CH);                                                      // Set RF channel 
 
   set_register(RF_SETUP,(Mbps<<3)|(dBm<<1)|0x01);                              // Set data rate and power level
 
   set_register(SETUP_AW,0x03);                                                 // Set address width to 5 bytes
 
   set_register(EN_AA,0x00);                                                    // Disable auto acknowledgement
 
   set_register(SETUP_RETR,0x05);                                               // Set auto retransmission for 5 tries
 
   set_register(TX_ADDR,address);                                               // Set transmit address
 
   set_register(RX_ADDR_P0,address);                                            // Set receive address
 
   set_register(EN_RXADDR,0x01);                                                // Enable RX address 0 
 
   set_register(RX_PW_P0,PAYLOAD_SIZE);                                         // Set RX payload to receive up to 32 characters 
 
   transmit_mode(false);                                                        // Enable receive mode
 
}
 
 
 
 
 | 	  
 
 
IMPLEMENTING THE DRIVER
 
 	  | Code: | 	 		  
 
 
#include <16F873.h>
 
#device PASS_STRINGS=IN_RAM 
 
#FUSES NOWDT, XT, NOPUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
 
#use delay(clock=4M)
 
#use rs232(baud=9600, parity=N ,xmit=PIN_C6,rcv=PIN_C7, bits=8)
 
 
 
#include <nrf24L01.c>
 
#define BUFFER_SIZE 32 
 
 
/************************ Global Variables *************************************/
 
 
const int address[5]={0xE7,0xE7,0xE7,0xE7,0xE7};                                // Declare address array
 
static int packet[BUFFER_SIZE];
 
int1 data=false;
 
 
/**************** Process Data Packet ******************************************/
 
void process_packet(unsigned int* data) 
 
{
 
  printf("DATA IN: %s\r",data);
 
}
 
 
/**************** Process Data Packet ******************************************/
 
#INT_RDA
 
void rs232()
 
{
 
  gets(packet);
 
  data=true;
 
}
 
 
/**************** Interrupt Request ********************************************/
 
#int_ext
 
void interrupt_request() 
 
{
 
  check_interrupt();
 
}
 
 
/************************ Main Loop ********************************************/
 
void main()
 
{  
 
   setup_rf(PIN_C1,PIN_C2,address,2,0,3);                                       // Initialize RF transceiver
 
   enable_interrupts(INT_RDA);
 
   ext_int_edge(H_TO_L);                                                        // Enable interrupt on high to low transition
 
   enable_interrupts(INT_EXT);                                                  // Enable PORTB.0 interrupt
 
   enable_interrupts(GLOBAL);                                                   // Enable global interrupts                                                               
 
   while(true)                                                                  // Loop forever
 
   {
 
     if(rf_interrupt){process_packet(rf_receive());}                            // Check to see if data has been received, if so process data
 
     if(data)
 
     {
 
         data=false;
 
         rf_transmit(packet);
 
     }
 
   }
 
}
 
 | 	 
  | 
			 
		  | 
	 
	
		  | 
	 
	
		
			dan king
 
 
  Joined: 22 Sep 2003 Posts: 119
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Tue Oct 07, 2008 7:07 am     | 
				     | 
			 
			
				
  | 
			 
			
				check out this link, they have tutorials for using the NRF24L01 transceiver and one of the tutorials sets up and uses the auto ack. I just started working with this a couple days ago and everything works pretty well. I even enabled the auto ack after getting the demo link working and have been impressed with the retransmit feature.
 
 
The sample code was easily ported to CCS C.
 
 
http://www.diyembedded.com/
 
 
Dan | 
			 
		  | 
	 
	
		  | 
	 
	
		
			Laalaa Guest
 
 
 
 
  
			
			
			
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Tue Jul 28, 2009 5:25 am     | 
				     | 
			 
			
				
  | 
			 
			
				| Does anybody manage to work the Enhanced Shockburst? | 
			 
		  | 
	 
	
		  | 
	 
	
		
			loggin
 
 
  Joined: 23 Sep 2010 Posts: 10
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Thu May 26, 2011 6:21 am     | 
				     | 
			 
			
				
  | 
			 
			
				Hello to all!
 
I'm to use the same topic. I've got a question about sending and receiving. I used the code above and I marked that if I send for example 5 bytes from Tx to Rx there is a kind of problem - 0th byte is the same at the receiver but 1st, 2nd and etc. are not the same, i.e. there's an error. More detailed - in receiving mode for example 2nd received byte from 10 receivings, 6-7 times is the same byte which I send by TX side (no error) but other times exist an error (not receive the same byte). I use IRQ pin for detecting interrupts. Except this the code work fine. Is it possible exists any dependence by SPI ? Any suggestions? Sorry if I couldn't explain it more detailed. Thanks in advance.
 
Best Regards! | 
			 
		  | 
	 
	
		  | 
	 
	
		
			princejude
 
 
  Joined: 07 Aug 2010 Posts: 72
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Fri Aug 05, 2011 5:44 am     | 
				     | 
			 
			
				
  | 
			 
			
				Hello to all,
 
Pls i will like to use this Randy's nRF24L01 Driver in my project. But i have some questions.
 
 
My observation from the implementing the driver sample code is that the nRF24L01 will transmit data receive through the PIC MCU serial (RS232 USART) port:
 
 
 	  | Code: | 	 		  /************ Process Data Packet *************************/
 
#INT_RDA
 
void rs232()
 
{
 
  gets(packet);
 
  data=true;
 
}
 
  | 	  
 
 
and 
 
 
 	  | Code: | 	 		  
 
if(data)
 
     {
 
         data=false;
 
[b] rf_transmit(packet);[/b]
 
 } 
 
 | 	  
 
 
Now the question is how can i edit this code to transmit my own  specified data like character, integer or string(eg 0x02, 'A', "HELLO WORLD").
 
The aim of my project is to build a simple RF remote control. And the operation is that the Transmitter will transmit some integer or strings (0x01,0x02) (if some button press)to the Receiver and if Receiver receives 0x01 it will ON first LED and if it receives 0x02 it will ON the second LED. | 
			 
		  | 
	 
	
		  | 
	 
	
		
			carkissm
 
 
  Joined: 09 Nov 2011 Posts: 1
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Wed Nov 09, 2011 5:08 am     | 
				     | 
			 
			
				
  | 
			 
			
				I need connect the module NRF24L01 to pic18f2550, anyone have the schematic for help me.
 
 
 
thanks. | 
			 
		  | 
	 
	
		  | 
	 
	
		
			Eduardo__
 
 
  Joined: 23 Nov 2011 Posts: 197 Location: Brazil 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Fri Feb 03, 2012 10:43 am     | 
				     | 
			 
			
				
  | 
			 
			
				Dear princejude.
 
 
It´s simple to transmit a "HELLO WORLD" string with nRF24L01+
 
I made a driver for that.
 
 
See at http://www.ccsinfo.com/forum/viewtopic.php?t=47351&highlight=nrf24l01
 
 
You can use the command:    	  | Code: | 	 		  | RF24_TX_putbuffer(false,11, "HELLO WORLD"); //Transmit 11bytes data(text string) to actual address(default_config address) | 	  
 
 
But it requires   a    	  | Code: | 	 		  | #device PASS_STRINGS=IN_RAM | 	    directive at the begining of your uC programm. _________________ Eduardo Guilherme Brandt | 
			 
		  | 
	 
	
		  | 
	 
	
		
			zamzam23
 
 
  Joined: 25 Aug 2010 Posts: 47
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Sat Jan 19, 2013 1:10 pm     | 
				     | 
			 
			
				
  | 
			 
			
				 	  | Quote: | 	 		  // Enable PORTB.0 interrupt
 
 | 	  
 
why use ext int? | 
			 
		  | 
	 
	
		  | 
	 
	
		
			ckielstra
 
 
  Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Sat Jan 19, 2013 5:28 pm     | 
				     | 
			 
			
				
  | 
			 
			
				 	  | zamzam23 wrote: | 	 		   	  | Quote: | 	 		  // Enable PORTB.0 interrupt
 
 | 	  
 
why use ext int? | 	  Zamzam, don't waste your time. The code as posted by Randy is full of bugs and a bad starting point for your own project. Better have a look at one of the other two projects mentioned in this thread that have proved to be working. | 
			 
		  | 
	 
	
		  | 
	 
	
		
			zamzam23
 
 
  Joined: 25 Aug 2010 Posts: 47
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				| which code | 
			 
			
				 Posted: Sun Jan 27, 2013 11:43 am     | 
				     | 
			 
			
				
  | 
			 
			
				Which code do you advise for me? do you have any?
 
 
Eduardo__'s code is very complex and I don't know if it is working or not. | 
			 
		  | 
	 
	
		  | 
	 
	
		
			UenX
 
 
  Joined: 16 Aug 2012 Posts: 6
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				| nRF24L01 can send, cannot receive RF data on PIC18F2550. | 
			 
			
				 Posted: Wed Mar 06, 2013 9:56 am     | 
				     | 
			 
			
				
  | 
			 
			
				Hi Eduardo.
 
Using your library, nRF24L01 can send, but cannot receive RF data on a PIC18F2550. 
 
The same code ( config, init ) works well  on PIC16F887.
 
Supply voltage for nRF24L01 is 3.6V, PIC uses 5V
 
 
Now it (my nRF24L01+ 2550 circuit ) only works ( being able to receive data ) when I plug my  PIC programmer circuit on it. Such a strange behavior !
 
 
I believe that 's a hardware problem ( especially voltage problem ),  but I still can not figure it out after using all of my debugging tricks.
 
 
If you have any PIC18F2550 there, could you please do a test on it?
 
 
Thank you !     | 
			 
		  | 
	 
	
		  | 
	 
	
		
			Eduardo__
 
 
  Joined: 23 Nov 2011 Posts: 197 Location: Brazil 
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Wed Mar 06, 2013 11:18 am     | 
				     | 
			 
			
				
  | 
			 
			
				Are you using software or hardware Spi?
 
Try software spi also!
 
 
What is the supply voltage?
 
It must be between 2.5 and 3.6V.
 
 
I´ve used hardware/software SPI with success in PIC18F24J11(with DMA), PIC18F24J11(with DMA), PIC16F876A(no DMA) 
 
 
I´ve used software SPI with success in PIC16F628A
 
 
 
Good Luck! _________________ Eduardo Guilherme Brandt | 
			 
		  | 
	 
	
		  | 
	 
	
		
			UenX
 
 
  Joined: 16 Aug 2012 Posts: 6
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				 | 
			 
			
				 Posted: Wed Mar 06, 2013 4:58 pm     | 
				     | 
			 
			
				
  | 
			 
			
				 	  | Eduardo__ wrote: | 	 		  Are you using software or hardware Spi?
 
Try software spi also!
 
 
What is the supply voltage?
 
It must be between 2.5 and 3.6V.
 
 
I´ve used hardware/software SPI with success in PIC18F24J11(with DMA), PIC18F24J11(with DMA), PIC16F876A(no DMA) 
 
 
I´ve used software SPI with success in PIC16F628A
 
 
 
Good Luck! | 	  
 
 
Thank you. I'm using software SPI. I believe SPI is working properly, cause the transmitting tasks got no problem. And the receiving feature also works when I plug my PIC programmer  on the circuit. I've tried with hardware SPI, though.
 
 
 
Supplying a 5V voltage for the PIC, I've tried with all voltage from 1.9 to 3.6 for nRF24 ( I use a LM317 Voltage Regulator IC )
 
 
The nRF24L01's datasheet said it has 5V tolerant inputs, but didnt say whether it can create a 5V voltage on its outputs.
 
 
Some people also mention something related to my problem :
 
 
http://www.microchip.com/forums/m451409.aspx
 
https://forum.sparkfun.com/viewtopic.php?f=13&t=4904&start=0
 
 
I've also tried using the same voltage for PIC and nRF24 ( 3.21V ) and it worked like a charm on my  PIC18F4550 breadboard. But no lucks when I try to reassemble it again. Transmitting is always OK, but nothing happens at Receiving mode.
 
 
Now i have no way to explain to my thesis advisor ( this is part of my final year project at university ). A little sad :D
 
 
May be i will do another test after finishing this project to figure this problem out ( make some PCBs with unique adjustable voltage for both PIC and nRF24 ) and post back the result here.
 
 
Thanks again. | 
			 
		  | 
	 
	
		  | 
	 
	
		
			teletype-guy
 
 
  Joined: 11 Oct 2005 Posts: 8 Location: AZ 
			
			 
			 
			
			 
			
			
			
			
			
  
		  | 
		 | 
	 
	
		  | 
	 
	
		
			UenX
 
 
  Joined: 16 Aug 2012 Posts: 6
  
			
			 
			 
			
			
			
			
			
			
			
  
		  | 
		
			
				| Re: hardware -- mixing 5V and 3.3V stuff | 
			 
			
				 Posted: Thu Apr 04, 2013 11:29 am     | 
				     | 
			 
			
				
  | 
			 
			
				
 
 
Thank you! I'll carefully read your post and do an experiment later ( currently I'm busy with another project ) | 
			 
		  | 
	 
	
		  | 
	 
	
		 | 
	 
 
  
	 
	    
	   | 
	
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
  | 
   
 
  
Powered by phpBB © 2001, 2005 phpBB Group
  
		 |