Incomprehensible Software Issue With An NRF24L01 Set-Up

Status
Not open for further replies.

Electric Potato

Well-known member
Hey yall, I've got a real nut-blaster of a problem going on over here with the nrf24, and figure maybe someone in here can help me regain some sanity. I've got a wireless midi controller that has generally been coming along swimmingly for a few weeks. It's a fairly small batch of code, about 40,000 bytes, 10,000 memory, and the wireless portion of it had been working just great. As I am now trying to finally finish it, I'm finding that seemingly insignificant changes are severing the wireless connection. I could bore you with a number of examples but I think this is the best one:

this singular if statement is in the main loop:
Code:
if(patchSlot==2){
    Serial.println(patchSlot);
      if(patchSlot2BlinkTimer>200 && !binaryFlicker){
          yellowsOn = !yellowsOn;
          patchSlot2BlinkTimer=0;
          updateBinaryLEDS(); 
 
      }
  }

If I comment this one little if statement out, wireless works fine. I press buttons on the controller and the receiver responds. If I leave the statement in, the controller just sluggishly times out as I push the buttons and the receiver never responds. What's killing me is that patchSlot is never 2, it's only ever 1, so it's not even getting between the brackets, which I can confirm with the serial monitor. So I can't understand how it can be impacting anything. Actually, what is killing me worse is that this:

Code:
if(patchSlot==2){
    Serial.println(patchSlot);
      if(patchSlot2BlinkTimer>200 && !binaryFlicker){
 
 
      }
  }


will also run fine, but THIS:
Code:
if(patchSlot==2){
    Serial.println(patchSlot);
      if(patchSlot2BlinkTimer>200 && !binaryFlicker){
           
          aLittleTeapot = !aLittleTeapot; 
 
      }
  }

WONT! This is just a dummy boolean that otherwise only exists in its declaration so how can it possibly affect the wireless connection? I should also mention that the controller is SENDING midi packets like it always does, which I can check via serial...it's just that the receiver is ignoring them. This is strictly an issue with the wireless interaction.

In short, I can take a hardware/software setup that works perfectly fine on both ends, and break it by placing aLittleTeapot within an if statement whose condition isn't met. I should also mention that just putting it in there followed by a semicolon, i.e no operator, doesn't break wireless.

All I can surmise is that this has to do with memory in some way, but I have no idea how. And this is just one example...I can actually leave THIS if statement in without changing a thing, and remove a completely unrelated chunk of code from later on, and wireless works fine. Similarly, I originally declared AudioMemory(10) because I planned to use the DAC to emit info tones, but ended up not needing it. I found that by removing this declaration (during a time when wireless wasn't working) wireless started working again. I figured I had solved the problem, but after adding some new variables, some if statements, and maybe a timer, wireless was back to being problematic.

Am I missing something? Have I totally lost it? I hope someone can help me get my pants back on here because I'm nearing the point of wandering the streets to a melancholy jazz soundtrack
 
Last edited:
Don't know what your specific problem is but i can say that i have had the problem of "too much Serial" which freezes my sketch and won't allow it to run, where commenting out one serial print line or another allows it to run. In other words, if I ask for just a bit too much serial out, everything stops working. I still don't know why and it hasn't happened to me for a while but then I don't ask for gobs of serial out anymore either! I have always assumed I tripped a memory limit of some kind.
 
Hm.. that's a good thought. I removed the Serial prints and Serial writes but unfortunately it's still not right...I've done some more tests and am even more perplexed. Here are three examples:

This DOES NOT screw up the wireless connection:
Code:
if(patchSlot==2){
  
      if(patchSlot2BlinkTimer>200 && !binaryFlicker){
       
 
      }
  }

This DOES screw up the wireless connection:
Code:
if(patchSlot==2){

      if(patchSlot2BlinkTimer>200 && !binaryFlicker){
       
        aLittleTeapot = !aLittleTeapot;
 
      }
  }

and finally, this DOES NOT screw up the wireless connection:
Code:
if(patchSlot==2){

      if(patchSlot2BlinkTimer>200 && !binaryFlicker){
       
        
 
      }
  }

aLittleTeapot = !aLittleTeapot;

so if this trivial expression is inside of an if statement that is never true, wireless stops working. If it's just sitting right in the main block of the loop then it doesn't interfere with anything. Again, this boolean value doesn't serve any purpose anywhere in the program. And again, this is just one example of this behavior...I could leave in the 2nd example and delete a chunk of code elsewhere and wireless would work again. I'm sure there's something to learn from this but I just can't figure it out. It definitely seems to be something broad
 
I'm pretty sure that the compiler will completely optimize away an empty if statement, so it won't ever read or compare the variables used in the if statement itself.

In your first post you were able to run the code when there was a statement inside the outer if, but nothing in the inner if statement. To me that would suggest that it's tripping over something in the inner if statement. You could try separating the inner if expression into two if statements, one for each variable. That might narrow the issue down to a single variable.
 
I saw a PJRC note the other day that if the Interrupts are disabled when the serial buffer fills - it may stall and not pick up. Not sure if you have other code or any place this could be happening. This may apply more to what onehorse saw if at all, as it may have been 'SERIAL' and not common to 'USB Serial'.

I'd be tempted to start with :: Files / Examples / Timerone / Interrupt sketch and see if that runs showing a healthy Teensy - and then extend it in the direction you want and see if/when it dies. It is a small bit of code you can drop on your example and see if the timer and blink works and Serial keeps printing.
 
Ah that's a good point about the compiler whollender, I guess some of those examples make more sense in light of that...well at any rate if I remove the "&& !binaryFlicker" wireless does actually work again:eek:...however I feel like there's some kind of seedy underbelly that I'm missing here because binaryFlicker at the moment simply gets set to false pre-setup...so there's nothing outlandish that could be going on with it; it's just a simple constant boolean. With something this innocuous screwing my wireless up I feel like there's a bigger problem at hand.
But like I said, I don't think this is a particularly demanding project in terms of memory or processing...so I don't know why I'd be hitting any limits...I've got 7 electret mics that send notes when you blow on them, but only 1 is ever getting sampled at any given time, otherwise they're just checked each cycle for a threshold cross with 7 analogReads. Aside from that there's a couple digital reads on a couple buttons and an occasional 6 LED refresh.
 
Last edited:
defragster, I'm not overtly using any interrupts in my sketch; the audio from the mics is just being casually sampled at whatever speed the loop runs at since it doesn't end up being audible anyway. I disabled interrupts before sending wireless data (then re-enabled) as an experiment and it froze my T3.1 on the sketches where wireless hadn't been working correctly. On sketches where wireless works fine, disabling interrupts didn't appear to have any effect...not sure if that's useful or not. IhavenoideawhatImdoingdog.gif
 
Better Description

Hey guys, here is what I hope will be a clearer demonstration of the problem I'm having:

(these variables appear nowhere else except this declaration and the main loop chunk below)
Code:
boolean aLittleTeapot=false;
int dummyNum = 1;

If this chunk is plopped in the main loop of my wireless midi controller code, the controller works fine (as you'd expect since these are useless variables):

Code:
  Serial.println("1");
  Serial.println(aLittleTeapot);
  aLittleTeapot = !aLittleTeapot;

however THIS minor change causes wireless to stop working:
Code:
  Serial.println(dummyNum);<-----I've just swapped the String for an int
  Serial.println(aLittleTeapot);
  aLittleTeapot = !aLittleTeapot;

Importantly, NOTHING else stops working besides wireless connectivity. The controller continues cheerfully Serial printing data, responding to buttons and mics, and doing everything it's supposed to, with the exception of being sluggish due to constantly timing out waiting for affirmation from the receiver for the packets it's sending. dummyNum and aLittleTeapot both print in the monitor just fine, with the values they're supposed to be. And again, these variables do nothing related to the midi controller in any way, they're just dummies.

What's more, if I comment out the 2nd and 3rd lines, wireless is back to working fine. But if I leave in either the 2nd or the 3rd, it breaks again, i.e:

this doesn't mess with wireless connectivity:
Code:
    Serial.println(dummyNum);

but this does:
Code:
    Serial.println(dummyNum);
     aLittleTeapot = !aLittleTeapot;

here is one final thing that might matter: if I declare dummyNum as a "const int" instead of just an "int", then I CAN print it without severing the wireless connection, i.e this code chunk does not break my wireless connection:

Code:
boolean aLittleTeapot=false;
const int dummyNum = 1;

loop(){
  Serial.println(dummyNum);
  Serial.println(aLittleTeapot);
  aLittleTeapot = !aLittleTeapot;

//controller related code here
}

A whale of thanks to anyone who can help me figure this out...I feel like I'm butting up against something but I don't know what it is...
 
Hmm.. how many variables you are using, and how many of them on the stack ?
This sounds a bit like a stack-corruption. Can you - for a test - try to use less variables/array-space and check again ?
Which Teensy is it ? LC or 3.0, 3.1 ?
 
thanks Frank, it's a Teensy 3.1... I'll try reducing some variables and let you know what happens...I don't feel like they're exceptionally excessive, although I do have 23 timers going, which is a record for me
 
Hm, okay, the 3.1 has 64KB.. you'd use really much space..
Another possible reason could be access behind array-bounds.. the usual suspects.. uninitialized vaiables..and so on.
Do you use malloc() ?
 
Frank, I think you could right about being out of bounds with an array...I'd been sending 8-rowed byte arrays, and now having switched to sending individual bytes the problem seems (tentatively) to have disappeared (though it doesnt solve my problem cause I need to send arrays). Possibly I'm misunderstanding the sizes of things: I've been sending an array such as this:

Code:
 byte dataArray[] = {0,0,0,0,0,0,0,0};

by using this code (I'm leaving lines out that I don't think pertain to this problem) :

Code:
//this is in the controller code 
radio.stopListening();

    bool ok = radio.write( &dataArray, sizeof(dataArray) );

    radio.startListening();
    
	unsigned long started_waiting_at = millis();
	bool timeout = false;
	while ( ! radio.available() && ! timeout ) {
	delay(5); 
	if (millis() - started_waiting_at > 200 )
			timeout = true;
	}
			if ( timeout ){}
			else{
                                byte receipt[8];
				radio.read( &receipt, sizeof(receipt) );

			}

and receiving/sending a ping back the same way:

Code:
//this is in the reciever code
       done = radio.read( &dataArray, sizeof(dataArray) );  	

       radio.stopListening();
  
  	radio.write( &dataArray, sizeof(dataArray) );
  
  	radio.startListening();

...is there something incorrect about the sizes of these sends and arrays? I'll keep trying different things in the meantime
 
Last edited:
Code:
//this is in the controller code 
radio.stopListening();

    bool ok = radio.write( &dataArray, sizeof(dataArray) );

    radio.startListening();
    
	unsigned long started_waiting_at = millis();
	bool timeout = false;
	while ( ! radio.available() && ! timeout ) {
	delay(5); 
	if (millis() - started_waiting_at > 200 )
			timeout = true;
	}
			if ( timeout ){}
			else{
[B]                                [SIZE=4]reciept=[8][/SIZE];[/B]
				radio.read( &receipt, sizeof(receipt) );

			}
This might be your problem. I can't work out how that even compiles? What are you trying to do here?
 
Hey Cosford, sorry, I butchered that declaration in posting it here, it's a byte array; I edited the post so it's straight now. Anyway I was trying to replace this line that reads the ping back from the reciever and confirms the data was sent and recieved:

Code:
	unsigned long got_time;
	radio.read( &got_time, sizeof(unsigned long) );

or rather adapt it to what I perceived to possibly be the correct way for sending an 8 item array of bytes. My wireless connection works with it in there (when it's not sassing me like I described above).
 
Last edited:
Ah, that makes a little more sense; although:

Code:
                                byte reciept[8];
				radio.read( &receipt, sizeof(receipt) );

Note the mis-spelling? I'm still suprised that compiles though, unless you've declared receipt somewhere else, in which case, it may explain your issues?
 
Cripes...that was another typo, I edited the post again, sorry about that, I'm surprised you noticed that though! I gotta remember i before e except after c.
 
Problem Fixed

For posterity's sake, I should mention that I solved this god-forsaken problem yesterday...it did turn out to be an array writing out-of-bounds, but not one related to my wireless code. It was an array of random numbers that should have been declared as [1000] instead of [999]. Please excuse my thrashing about and thanks for the help :cool:
 
Hey, we all learned from it, so thank you for posting the resolution!

This is the sort of stuff that can easily brick an MCU and confuse anyone that doesn't have a debugger running alongside.
 
Glad you sorted it.

Bit of a golden rule, if something really stupid like that happens when you're trying to debug your program (unrelated in both hardware and software code breaks something else), buffer overflow is a good contender for the cause.
 
Status
Not open for further replies.
Back
Top