CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Help using enhanced shockburst for the NRF24L01
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Randy
Guest







Help using enhanced shockburst for the NRF24L01
PostPosted: Mon Oct 06, 2008 8:32 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Oct 07, 2008 7:07 am     Reply with quote

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







PostPosted: Tue Jul 28, 2009 5:25 am     Reply with quote

Does anybody manage to work the Enhanced Shockburst?
loggin



Joined: 23 Sep 2010
Posts: 10

View user's profile Send private message

PostPosted: Thu May 26, 2011 6:21 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Aug 05, 2011 5:44 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Nov 09, 2011 5:08 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Feb 03, 2012 10:43 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Jan 19, 2013 1:10 pm     Reply with quote

Quote:
// Enable PORTB.0 interrupt

why use ext int?
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sat Jan 19, 2013 5:28 pm     Reply with quote

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

View user's profile Send private message

which code
PostPosted: Sun Jan 27, 2013 11:43 am     Reply with quote

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

View user's profile Send private message

nRF24L01 can send, cannot receive RF data on PIC18F2550.
PostPosted: Wed Mar 06, 2013 9:56 am     Reply with quote

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 ! Sad
Eduardo__



Joined: 23 Nov 2011
Posts: 197
Location: Brazil

View user's profile Send private message

PostPosted: Wed Mar 06, 2013 11:18 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Mar 06, 2013 4:58 pm     Reply with quote

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

View user's profile Send private message Visit poster's website

hardware -- mixing 5V and 3.3V stuff
PostPosted: Sat Mar 16, 2013 6:39 pm     Reply with quote

Hey UenX:

Careful with mixing 5V and 3.3V stuff. Check this post I did for you:

http://www.ccsinfo.com/forum/viewtopic.php?p=173289#173289
UenX



Joined: 16 Aug 2012
Posts: 6

View user's profile Send private message

Re: hardware -- mixing 5V and 3.3V stuff
PostPosted: Thu Apr 04, 2013 11:29 am     Reply with quote

teletype-guy wrote:
Hey UenX:

Careful with mixing 5V and 3.3V stuff. Check this post I did for you:

http://www.ccsinfo.com/forum/viewtopic.php?p=173289#173289


Thank you! I'll carefully read your post and do an experiment later ( currently I'm busy with another project )
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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