SparkFun Forums 

Where electronics enthusiasts find answers.

All things pertaining to wireless and RF links
By thibow
#144676
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.

Thank's a lot for your help again
By thibow
#144678
I made sure my IRQ works when I am sending.. and it works..
Code: Select all
			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
By brennen
#144679
You need to remove the else before
Code: Select all
if (nrf24l01_irq_tx_ds_active()){ //see if it was sent or not and tell me..
Otherwise, you'll never see what *type* of IRQ you're getting, because the first if will always be true there.
By thibow
#144680
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...
By thibow
#144682
I'll check the RX side now. What kind of register problem are you thinking about. I can't think of any because I'm not dealing with them directly.
Thank's a lot for your help, it's really pleasant not to feel alone !
By thibow
#144684
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 :
Code: Select all
   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 :
Code: Select all
  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 !
By arhi
#145930
Hi guy's I hope I'm not digging thread that's too old but I spent bunch of hours with this and I'm starting to hit a brick wall with it :(

I have one arduino sitting 1m from my table running ping_server ( mirf library example) that looks like this
Code: Select all

void setup(){
  Serial.begin(9600);
   Mirf.cePin = 8;
   Mirf.csnPin = 9;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"serv1");
  Mirf.payload = sizeof(unsigned long);
  Mirf.config();
  Serial.println("Listening..."); 
}

void loop(){
  byte data[Mirf.payload];
  int i;
  if(!Mirf.isSending() && Mirf.dataReady()){
    Serial.print("Got packet: 0x");
    Mirf.getData(data);
    for(i=0;i<Mirf.payload;i++)
      Serial.print(data[i], HEX);
    Serial.println(".");
     
    Mirf.setTADDR((byte *)"clie1");
    Mirf.send(data);
    Serial.println("Reply sent.");
  }
}
And when I use the ping_client on another arduino everything works (client code looks like)
Code: Select all
void setup(){
  Serial.begin(9600);
  Mirf.cePin  = 7;
  Mirf.csnPin = 53;
  Mirf.spi = &MirfHardwareSpi;
  Mirf.init();
  Mirf.setRADDR((byte *)"clie1");
  Mirf.payload = sizeof(unsigned long);
  Mirf.config();
  Serial.println("Beginning ... "); 
}

void loop(){
  unsigned long time = millis();
  Mirf.setTADDR((byte *)"serv1");
  Mirf.send((byte *)&time);
  while(Mirf.isSending()){}
  Serial.println("Finished sending");
  delay(10);
  while(!Mirf.dataReady()){
    if ( ( millis() - time ) > 1000 ) {
      Serial.println("Timeout on response from server!");
      return;
    }
  }
 
  Mirf.getData((byte *) &time);
  delay(1000);
} 
And, as I say - this works ... now, I don't use arduino in my project but I use pic32.
I rewrote first the arduino code and it don't work, now I tried Brennen code and it again don't work ...

The only changes to Brennen code to run on pic32 (pic32mx460F512L, c32, mplabx) are in the nrf24l01.c:
Code: Select all
#define NRFL_SPI_CHN SPI_CHANNEL1
#define NRFL_cePin PORTAbits.RA15
#define NRFL_ceTris TRISAbits.TRISA15
#define NRFL_csnPin PORTAbits.RA14
#define NRFL_csnTris TRISAbits.TRISA14
#define NRFL_irqPin  PORTBbits.RB10
#define NRFL_irqTris TRISBbits.TRISB10

extern volatile unsigned int CoreDelay; //decreased every 10us

void delay10us(unsigned int i) {
    CoreDelay = i;
    while (CoreDelay);
}

unsigned char spi_send_read_byte(unsigned char b) {
    unsigned short txData, rxData; // transmit, receive characters

    txData = b;                        // take inputted byte and store into txData
    SpiChnPutC(NRFL_SPI_CHN, txData);  // send data
    rxData = SpiChnGetC(NRFL_SPI_CHN); // retreive over channel chn the received data into rxData
    return rxData;
}

void SpiInitDevice(int chn, int isMaster, int frmEn, int frmMaster) {
    unsigned int config = SPI_CON_MODE8 | SPI_CON_SMP | SPI_CON_ON;
    if (isMaster) {
        config |= SPI_CON_MSTEN;
    }
    if (frmEn) {
        config |= SPI_CON_FRMEN;
        if (!frmMaster) {
            config |= SPI_CON_FRMSYNC;
        }
    }
    SpiChnOpen(chn, config, 15);
}

//....
// This is added to beginning of the nrf24l01_initialize

        NRFL_ceTris  = 0;
        NRFL_csnTris = 0;
        NRFL_irqTris = 1;
        SpiInitDevice(NRFL_SPI_CHN, 1, 0, 0);
//...
void nrf24l01_clear_ce()
{
	//nrf24l01_CE_IOREGISTER &= ~nrf24l01_CE_PINMASK;
    NRFL_cePin = 0;
}

//sets the pin on the host microcontroller that is attached to the 24l01's CE pin
void nrf24l01_set_ce()
{
	//nrf24l01_CE_IOREGISTER |= nrf24l01_CE_PINMASK;
    NRFL_cePin = 1;
}

//returns true if CE is high, false if not
bool xnrf24l01_ce_pin_active()
{
/*
    if((nrf24l01_CE_IOREGISTER & nrf24l01_CE_PINMASK) != 0)
		return true;
	else
		return false;
 */
    return (NRFL_cePin)?true:false; //not sure how is this useful as CE pin is output from mcu?!
}

//sets the pin on the host microcontroller that is attached to the 24l01's CSN pin
void nrf24l01_clear_csn()
{
	//nrf24l01_CSN_IOREGISTER &= ~nrf24l01_CSN_PINMASK;
    NRFL_csnPin = 0;
}

//clears the pin on the host microcontroller that is attached to the 24l01's CSN pin
void nrf24l01_set_csn()
{
	//nrf24l01_CSN_IOREGISTER |= nrf24l01_CSN_PINMASK;
        NRFL_csnPin = 1;
}

//returns true if CSN is high, false if not
bool xnrf24l01_csn_pin_active()
{
    /*
	if((nrf24l01_CSN_IOREGISTER & nrf24l01_CSN_PINMASK) != 0)
		return true;
	else
		return false;
     */
    return (NRFL_csnPin)?true:false;
}
[/quote]

and that's all changes I made.

The main goes like this:

[code]
// config bits
//...

volatile unsigned int CoreDelay;

int main(void) {
    unsigned long ttt;

    SYSTEMConfigPerformance(GetSystemClock());
    while (!(OSCCON & 0x00000020)); 
    OpenCoreTimer(CORE_TICK_RATE);
    mConfigIntCoreTimer((CT_INT_ON | CT_INT_PRIOR_2 | CT_INT_SUB_PRIOR_0));
    INTEnableSystemMultiVectoredInt();
    CloseADC10();
    CoreDelay = 0;

    nrf24l01_initialize_debug(true, 4, false);
    nrf24l01_set_rx_addr("clie1", 5, 0);
    nrf24l01_set_rx_pw(4,0);
    nrf24l01_set_tx_addr("serv1", 5);

    ttt = 0;
    while (1) {
        ttt++;
        nrf24l01_set_as_tx();
        nrf24l01_write_tx_payload((unsigned char *)&ttt, 4, true);
        mLED_1_On();
        while (!(nrf24l01_irq_pin_active() && nrf24l01_irq_tx_ds_active()));

//////////////////////////////
//IT NEVER ARRIVES HERE!!!!!!!!!!!
//////////////////////////////

        mLED_2_On();
        nrf24l01_irq_clear_all(); //clear interrupts again
        nrf24l01_set_as_rx(true); //operation as a RX
        mLED_3_On();
        CoreDelay = 10000;
        while (CoreDelay);
    }
//...
I use arduino ping_server as receiver but there I receive nothing and pic32 is stuck in

while (!(nrf24l01_irq_pin_active() && nrf24l01_irq_tx_ds_active()));

Logic analyzer show that everything is perfectly going trough wires (SPI is 6MHz so below 8MHz limit of the module, slowing it down didn't change anything).
You do not have the required permissions to view the files attached to this post.
By arhi
#145931
Here's also the SPI decoded by saleae logic analyzer ... everything looks perfect for me, but the NRF24L01+ is constantly returning 0x0E :(

If anyone can help ..
You do not have the required permissions to view the files attached to this post.
By brennen
#145935
SPI looks OK from what I can tell. It would be really helpful if you could get a zoomed in trace when you actually try to transmit a packet (preferrably one-byte payload to make it as short as possible) such that you can see the hex values over MISO and MOSI like in the first two images above.
By arhi
#145951
That's why I added the spi_decoded.csv, it's comma separated values, each line is what's on MOSI, what's on MISO...

I'll make more snapshots in few moments and upload the pics, thanks for checking it out