SparkFun Forums 

Where electronics enthusiasts find answers.

All things pertaining to wireless and RF links
By thibow
#144425
Ok thank you very much for your time, it helps me a lot, I have to know better my tools, I have never used it for debugging yet.
One last thing about the code you gave (I can't test it before tomorrow but I'd like to understand everything)

you have first :
Code: Select all
   //write TX_ADDRESS register
   SPI_CSN = 0;         //CSN low
   status = spi_Send_Read(0x30);
and secondly :
Code: Select all
//read TX_ADDRESS register
   //Check that values are correct using the MPLAB debugger
   SPI_CSN = 0;         //CSN low
   status = spi_Send_Read(0x10);
for the second, I agree that "0x10" is the TX_ADDR, (according to the datasheet) but what about the "0x30" in the first snippet.. shouldn't it be RX_ADDR ?

edit:
Ok I got it, the first means that you want to write 001A AAAA on register 1 0000 which is TX_ADDR and then you simply want to read 000A AAAA that same register..
Thank you again for your help
By thibow
#144442
hmm interresting.. I got the SPI working, I guess this is due to MCLRE pull up resistor, as it's the only thing I changed and I am able to read registers now, here is how it looks like :
Code: Select all
0: 52
1: a1
2: f
3: 0
4: 1
5: 2a
6: c0
7: 0
8: 1d
9: 0
a: 31
b: 80
c: 10
d: a
e: 2a
f: c1
10: 8
11: 8a
12: 0
13: 26
14: 2
15: 90
16: 4c
17: 14
18: c
19: a0
1a: 5
1b: 68
1c: 86
1d: 2a
1e: a0
1f: 42
20: 33
21: 20
22: 10
23: 22
I'll try to guess what could be wrong, if you see anything.. Thank you very much for your help
By thibow
#144454
I have added a part of your code simply to write something in TX buffer:
Code: Select all
	Initialize(); //initialize IO, UART, SPI, set up nRF24L01 as TX
	nrf24l01_flush_tx();
	nrf24l01_flush_rx();
	nrf24l01_get_all_registers(buffer);
   for(count = 0; count < 36; count++)
       printf("%x: %x\r\n", count, buffer[count]); 
//ADDED---------------------------------------------------------
	status = spi1_send_read_byte(0x30);
	spi1_send_read_byte(0x11);
	spi1_send_read_byte(0x22);
	spi1_send_read_byte(0x33);
	spi1_send_read_byte(0x44);
	spi1_send_read_byte(0x55);
	
	printf("WRITING...\n\r");
   nrf24l01_get_all_registers(buffer);
	for(count = 0; count < 36; count++)
       printf("%x: %x\r\n", count, buffer[count]); 
//---------------------------------------------------------
OUTPUT:
Init OK0: a
1: 0
2: 3
3: 3
4: 3
5: 2
6: f
7: e
8: 0
9: 0
a: e7
b: e7
c: e7
d: e7
e: e7
f: c2
10: c2
11: c2
12: c2
13: c2
14: c3
15: c4
16: c5
17: c6
18: e7
19: e7
1a: e7
1b: e7
1c: e7
1d: 1
1e: 0
1f: 0
20: 0
21: 0
22: 0
23: 11
WRITING...
0: a
1: 0
2: 3
3: 3
4: 3
5: 2
6: f
7: e
8: 0
9: 0
a: e7
b: e7
c: e7
d: e7
e: e7
f: c2
10: c2
11: c2
12: c2
13: c2
14: c3
15: c4
16: c5
17: c6
18: e7
19: e7
1a: e7
1b: e7
1c: e7
1d: 1
1e: 0
1f: 0
20: 0
21: 0
22: 0
23: 11
I'm not sure about the test I just made.. maybe they look better now !?
By thibow
#144608
I had no time to work on the module before, so I'm just getting back to it, and it seems that I am talking to the module without any problem (once I have implemented the SPI_CSN byte that I didn't before), here is the code added :
Code: Select all
	nrf24l01_flush_tx();
	nrf24l01_flush_rx();
	nrf24l01_get_all_registers(buffer);
   for(count = 0; count < 36; count++)
       printf("%x: %x\r\n", count, buffer[count]); 
//ADDED---------------------------------------------------------
#define SPI_CSN      LATBbits.LATB6      // CSN output pin, PORTB pin 6
	   SPI_CSN = 0;         //CSN low
	status = spi1_send_read_byte(0x30);
	spi1_send_read_byte(0x11);
	spi1_send_read_byte(0x22);
	spi1_send_read_byte(0x33);
	spi1_send_read_byte(0x44);
	spi1_send_read_byte(0x55);
	   SPI_CSN = 1;               // CSN high

	printf("WRITING...\n\r");
   nrf24l01_get_all_registers(buffer);
	for(count = 0; count < 36; count++)
       printf("%x: %x\r\n", count, buffer[count]); 
and here is the output:
Init OK0: a
1: 0
2: 3
3: 3
4: 3
5: 2
6: f
7: e
8: 0
9: 0
a: e7
b: e7
c: e7
d: e7
e: e7
f: c2
10: c2
11: c2
12: c2
13: c2
14: c3
15: c4
16: c5
17: c6
18: e7
19: e7
1a: e7
1b: e7
1c: e7
1d: 1
1e: 0
1f: 0
20: 0
21: 0
22: 0
23: 11
WRITING...
0: a
1: 0
2: 3
3: 3
4: 3
5: 2
6: f
7: e
8: 0
9: 0
a: e7
b: e7
c: e7
d: e7
e: e7
f: c2
10: c2
11: c2
12: c2
13: c2
14: c3
15: c4
16: c5
17: c6
18: 11
19: 22
1a: 33
1b: 44
1c: 55
1d: 1
1e: 0
1f: 0
20: 0
21: 0
22: 0
23: 11
we see clearly that I have written :
18: 11
19: 22
1a: 33
1b: 44
1c: 55

Now I'll have a look at the slave... I don't know why it doesn't receive anything. May the bunch of wires around be a problem you think ? (even if my 2 modules are almost stuck to one another ?)

Thank you very much for your help
By thibow
#144611
Here is the code of my slave, the initialization part is exactly the same as the master module, the only thing that changes is in the "nrf24l01_initialize_debug(true, 1, false);" that init the module to RX. The initialization IO part is exactly the same for master and slave...

My LED 0 blinks at startup, this means the initialization went all right. but then it seems never to get any interruption and gets stuck to " while(!(nrf24l01_irq_pin_active() && nrf24l01_irq_rx_dr_active())); "

Here is the code. I can't see what's wrong...
Code: Select all
#include <p18F2620.H>
//#include <string.h>
#include <spi.h> 
#include "delays.h" 
#include "nrf24l01.h" 


#pragma config OSC = HS//
//#pragma config FCMEN = OFF //Fail-Safe Clock Monitor disabled
//#pragma config IESO = OFF //Oscillator Switchover mode disabled
#pragma config PWRT = ON //Power-up Timer Enable
//#pragma config BOREN = OFF //Brown-out Reset disabled in hardware and software 
//#pragma config BORV = 0 //Brown Out Reset Voltage: Maximum setting
#pragma config WDT = OFF //
//#pragma config WDTPS = 1 //Watchdog Timer Postscale Select 1:1
//#pragma config CCP2MX = PORTC //CCP2 input/output is multiplexed with RC1 
//#pragma config PBADEN = OFF // PORTB<4:0> pins are configured as digital I/O on Reset 
//#pragma config LPT1OSC = OFF //Timer1 configured for higher power operation
#pragma config MCLRE = ON //(ON)MCLR pin enabled; RE3 input pin disabled
#pragma config STVREN = ON //Stack full/underflow will not cause Reset 
#pragma config LVP = OFF //Single-Supply ICSP disabled 

void Initialize(void); 
void InitializeIO(void); 

void ToggleLED(int id); //toggle the current state of the on-board LED

//main routine
void main(void) 
{ 
   unsigned char data; //register to hold letter received and sent 
    
   Initialize(); //initialize PLL, IO, SPI, set up nRF24L01 as RX 

   //main program loop 
   while(1) 
   { 
      //wait until a packet has been received 
      while(!(nrf24l01_irq_pin_active() && nrf24l01_irq_rx_dr_active())); 
	ToggleLED(1);
      nrf24l01_read_rx_payload(&data, 1); //read the packet into data 
      nrf24l01_irq_clear_all(); //clear all interrupts in the 24L01 

      DelayUS(130); //wait for the other 24L01 to come from standby to RX 
       
      nrf24l01_set_as_tx(); //change the device to a TX to send back from the other 24L01 
      nrf24l01_write_tx_payload(&data, 1, true); //transmit received char over RF 
       
      //wait until the packet has been sent 
      while(!(nrf24l01_irq_pin_active() && nrf24l01_irq_tx_ds_active())); 

      nrf24l01_irq_clear_all(); //clear interrupts again 
      nrf24l01_set_as_rx(true); //resume normal operation as an RX  
   } 
} 

//initialize routine
void Initialize(void) 
{ 
   InitializeIO(); //set up IO (directions and functions)
   OpenSPI(SPI_FOSC_16, MODE_00, SMPMID); //open SPI1 
   nrf24l01_initialize_debug(true, 1, false); //initialize the 24L01 to the debug configuration as RX, 1 data byte, and auto-ack disabled
	DelayUS(200);
	ToggleLED(0);
} 

//initialize IO pins
void InitializeIO(void)
{
	ADCON1 = 0x0F; //disable AD converter functionality on PORTA
	CMCON = 0x07; //disable comparators on PORTA

	TRISAbits.TRISA0 = 0; //make PORTA.0 an output to control LED
	PORTAbits.RA0 = 1; //turn on LED0
	TRISAbits.TRISA1 = 0; //make PORTA.1 an output to control LED
	PORTAbits.RA1 = 1; //turn on LED1

	TRISBbits.TRISB7 = 1; //make sure that PORTB.7 INPUT since it is IRQ pin
	TRISBbits.TRISB6 = 0; //make sure that PORTB.6 OUTPUT since it is CSN pin
	TRISBbits.TRISB5 = 0; //make sure that PORTB.5 OUTPUT since it is CE pin
	PORTBbits.RB6 = 1; //set CSN bit

	TRISCbits.TRISC3 = 0; //make sure that PORTC.3 OUTPUT since it is SCK pin
	TRISCbits.TRISC4 = 1; //make sure that PORTC.4 INPUT since it is SDI pin
	TRISCbits.TRISC5 = 0; //make sure that PORTC.5 OUTPUT since it is SDO pin

	TRISCbits.TRISC6 = 0; //make sure that PORTC.6 OUTPUT since it is TX pin UART
	TRISCbits.TRISC7 = 1; //make sure that PORTC.7 INPUT since it is RX pin UART

	//TRISC = 0x91; //make CSN, CE, SCK, MOSI (SDO), and TX outputs
}	  

//toggles on-board LED
void ToggleLED(int id) 
{ 
	if (id==1)
   	PORTAbits.RA1 = ~PORTAbits.RA1;
	else 
	PORTAbits.RA0 = ~PORTAbits.RA0;
}    
By thibow
#144613
Hi Brennen, thank's for your answer, on the TX side, I have an UART message that tells me it is sent :
Code: Select all
	nrf24l01_write_tx_payload(&data, 1, true); //transmit received char over RF	
			//wait until the packet has been sent or the maximum number of retries has been reached

while(!(nrf24l01_irq_pin_active() && nrf24l01_irq_tx_ds_active()));
			if (nrf24l01_irq_tx_ds_active()){ //see if it was sent or not and tell me..
				printf("\n Sent");
			} else {
				printf("\n Something's wrong");
			}
It tells me "Sent"
By thibow
#144665
No more idea about my trouble ? I've check my connections carefully and both modules are wired the same way..

You have never answered about the trouble I could have because of the wires around the RF module.. Do you think this could cause the receiver not to receive anything ?

Thank you
By thibow
#144670
Thank you for your suggestion, I have just check with a multimeter (I don't have any oscilloscope) and the IRQ pin is never low, it keeps being at 3.1v..

edit:
Wait, I just check with the TX IRQ pin that should be low when it has transmitted, and the pin only goes from 3.2V to 3.1 for a second, and then back to 3.2V...
By brennen
#144672
If the RX IRQ pin never goes low, then it's not getting the packet. You should also verify that the CE pin is logic high for the RX constantly, or else the radio won't be turned on.

For the TX, it is expected that the IRQ will only drop momentarily. That is because your code clears the interrupt almost as soon as it is asserted.
By thibow
#144673
Thank you for your help.
I have noticed a change to RX IRQ when I send a packet. Just like TX IRQ, it seems to be floating (around 3.2V) and then when I send a packet it stops floating around 3V... for a second, and then goes floating again.. Something happens obviously..

TX CE is low (close to 0) and goes high when it has sent, and then goes low again (as expected).
RX CE pin is 3.2V (logic high I assume) and seems to be floating as well, but just like IRQ, something happens (it stops floating) when I send a character..

My pin declaration seems to be all right though..

EDIT: :shifty: ok now RX IRQ pin is kept low (close to 0V..)
By brennen
#144675
To test if you are reading the RX IRQ pin correctly, then in place of this code
Code: Select all
   while(!(nrf24l01_irq_pin_active() && nrf24l01_irq_rx_dr_active())); 
   ToggleLED(1);
substitute this code
Code: Select all
   while(!(nrf24l01_irq_pin_active());
   ToggleLED(1);

   printf("IRQ is ");
   
   if(nrf24l01_irq_rx_dr_active())
      printf("RX_DR\n");
   else if(nrf24l01_irq_tx_ds_active())
      printf("TX_DS\n");
   else if(nrf24l01_irq_max_rt_active())
      printf("MAX_RT\n");
   else
      printf("unknown\n");
This will print out the IRQ type when IRQ is asserted, assuming you have everything set up properly.

NOTE: I did *not* compile this code, so it may contain syntax errors.