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 :
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 ?)
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…
#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;
}
Do you have an LED on the TX side that blinks when you get the TX_DS interrupt? If the TX doesn’t give a TX_DS interrupt, then the RX is certainly not going to assert an RX_DS interrupt.
Hi Brennen, thank’s for your answer, on the TX side, I have an UART message that tells me it is sent :
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");
}
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 ?
Have you checked the IRQ pin at the RX to see if it is asserted (GND) after the TX sends a packet? I highly doubt that wires will cause you to not get a packet if the boards are close to one another.
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…
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.
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…)
Well I do not have any UART on the slave as I only have one RS232 adaptor and I need it to be able to send a character. However I was able to get an oscilloscope and I have clearly seen that RX IRQ isn’t going low, as well as TX IRQ… there’s something wring with that. I’ll test your code on the TX to make sure that the IRQ isn’t working properly.
I made sure my IRQ works when I am sending… and it works…
data = ReadUSART(); //get data from UART
printf("\n merci");
nrf24l01_write_tx_payload(&data, 1, true); //transmit received char over RF
while(!(nrf24l01_irq_pin_active() && nrf24l01_irq_tx_ds_active()));
if (nrf24l01_irq_pin_active()){
printf("\n IRQ pin active");
}
if (nrf24l01_irq_tx_ds_active()){ //see if it was sent or not and tell me..
printf("\n TX_DS active");
} else
if (nrf24l01_irq_max_rt_active()){
printf("\n Max RT active");
} else {
printf("Something's wrong");
}
output:
wait
wait<--------- here I type in a character on my keyboard
merci
IRQ pin active
TX_DS active
count:0
count:1000
count:2000
count:3000
count:4000
count:5000
count:6000
count:7000
count:8000
count:9000
count:10000
count:11000
count:12000
count:13000
count:14000
count:15000
count:16000
count:17000
count:18000
count:19000data: ?
wait
wait
I’ll modify my program for the TX to send continuously and have a look at the RX side to try to understand what’s wrong with IRQ
I realized this afterwards, I have edited my previous post, the TX_DS is active.
However, when I type in one character it works, well it sends something, and goes waiting for another character, but then if I type in a character (for the second time) it gets stuck (obviously on while(!(nrf24l01_irq_pin_active() && nrf24l01_irq_tx_ds_active())); )
EDIT: This was a bug, it doesn’t get stuck anymore…
So it sounds like you’ve proven the TX is working as expected, so the problem almost certainly lies in the RX (unless there’s some kind of register settings problem that I can’t see).
One of my major problem could have come to the fact that “#include <stdio.h>” was missing in RX code…
Here is where I am (this is close to the end !)
I’ve modified the TX code to keep sending and receiving, this module doesn’t have any UART, just the LED blinking as I’m sure it works well.
I sends a ‘a’, get into RX mode, waits a while for something to receive, and loops even if it didn’t receive anything.
The RX module has UART, it tells me if the init went all right, tells me it’s waiting for a packet to receive, then tells me what it has received. It goes then in TX mode to send the ‘a’, it tells me the IRQ state and loops.
Here is the main while loop of RX module :
while(1)
{
CheckErrorsUSART();
printf("\n wait");
//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
printf("\ndata received: %c",data);
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
printf("\n\rsending...");
//wait until the packet has been sent
while(!(nrf24l01_irq_pin_active() && nrf24l01_irq_tx_ds_active()));
if (nrf24l01_irq_pin_active()){
printf("\n IRQ pin active");
}
if (nrf24l01_irq_tx_ds_active()){ //see if it was sent or not and tell me..
printf("\n TX_DS active");
}
if (nrf24l01_irq_max_rt_active()){
printf("\n Max RT active");
}
nrf24l01_irq_clear_all(); //clear interrupts again
nrf24l01_set_as_rx(true); //resume normal operation as an RX
}
and the output :
Init OK
wait
data received: a
sending...
IRQ pin active
TX_DS active
wait
Init OK
wait<--- gets stuck here
So it receives the ‘a’ properly, sends properly the data back, but gets stuck on the second iteration…
edit: :o Wait I just realized it resets after sending… it shouldn’t !