Problem mit Interrupt für NRF24L01+

Hallo zusammen,
im Zuge meines Quadrocopter Projekts habe ich mich einer einfachen RC auf Basis eines NRF24Lo1+ gewidmet. Ich habe eine kleine RC-Klasse programmiert, die auch solo gut funktioniert. Wenn ich diese Klasse in mein Quadrocopter Projekt einbinde, gibt es aber ein Problem.
Der Interrupt(0) ist durch den MPU besetzt. Also nehme ich für den NRF24 Interrupt(1). Da ich mit den Interrupts immer auf dem Kriegsfuß stehe, komme ich hier nicht weiter.
Der Transmitter sendet einwandfrei.

Das Problem liegt wohl daran, das der Interrupt(1) nicht das tut was er soll:

/*
 * Transmitter is RF24_IQR_Transmitter
 * 
 */

//Standard Class

#include <PID_v1.h>
#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050_9Axis_MotionApps41.h>
#include <helper_3dmath.h>
#include <Servo.h>
#include <RF24_config.h>
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

//Owen Class
#include "Config.h"
#include "QuadRC_01.h"
#include "RC.h"
#include "Motors.h"

/*  MPU variables */
MPU6050 mpu;                           // mpu interface object
uint8_t mpuIntStatus;                  // mpu statusbyte
uint8_t devStatus;                     // device status    
uint16_t packetSize;                   // estimated packet size  
uint16_t fifoCount;                    // fifo buffer size   
uint8_t fifoBuffer[64];                // fifo buffer 
Quaternion q;                          // quaternion for mpu output
VectorFloat gravity;                   // gravity vector for ypr

volatile bool mpuInterrupt = false;    //interrupt flag
volatile bool nrfInterrupt = false; 

boolean blinkState = false;

//--------------------------- end declarations and initialisations --------------------------------

//                            Interrupt PIN must be changed. !!!!!
//  Interrupt routine for IMU
void dmpDataReady() {
    mpuInterrupt = true;
}

// Interrupt handler, check the radio because we got an IRQ
void check_radio(void);

//--------------------------- end of interrupte handlers ------------------------------------------

void setup(void) {

   Serial.begin(115200);
#ifdef __AVR_ATmega2560__
	Serial1.begin(115200);
#endif

    printf_begin();

#ifdef BLUETOOTH
	Serial1.println("********************************");
	Serial1.println("*    QuadroCopter Receiver     *");
	Serial1.println("*    Bluetooth Mode      *");
	Serial1.print  ("*     ");Serial1.print(__DATE__);Serial1.print(" ");Serial1.print(__TIME__);Serial1.println("     *");
	Serial1.println("********************************");
	Serial1.flush();
#else
	Serial.println("********************************");
	Serial.println("*    QuadroCopter Receiver     *");
	Serial.print  ("*     ");Serial.print(__DATE__);Serial.print(" ");Serial.print(__TIME__);Serial.println("     *");
	Serial.println("********************************");
	Serial.flush();
#endif
    pinMode(MAIN_LED, OUTPUT);

#ifdef BLUETOOTH
	Serial1.println("Bluetooth setup done");
#else
	Serial.println("Setup done");
#endif

//  initIMU();
  RC.init();

  attachInterrupt(1, check_radio, FALLING);

}
//----------------- end of setup ------------------------------------------------------------------

void loop(void) {

unsigned long startMicros = micros();

	//getYPR();
	Motors.setMotor(RC.rxValues.throttle);

#ifdef BLUETOOTH
//	unsigned long endMicros = micros();				/// display the loop time for debug
//	Serial1.println(endMicros - startMicros, DEC);	
#else
//	unsigned long endMicros = micros();				
//	Serial.println(endMicros - startMicros, DEC);		
#endif

  blinkState = !blinkState;
  digitalWrite(MAIN_LED, blinkState);		
}
//--------------------------- end of loop ---------------------------------------------------------

void initIMU() {
  
    Wire.begin();

#ifndef BLUETOOTH
  	Serial.println(F("Initializing MPU6050 devices..."));
	mpu.initialize();
    Serial.println(F("Testing MPU6050 connections..."));
    Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
	Serial.println(F("Initializing DMP..."));		 // load and configure the DMP
#else
  	Serial1.println(F("Initializing MPU6050 devices..."));
	mpu.initialize();
    Serial1.println(F("Testing MPU6050 connections..."));
    Serial1.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
	Serial1.println(F("Initializing DMP..."));		 // load and configure the DMP
#endif

    devStatus = mpu.dmpInitialize();
	if(devStatus == 0){ 
		mpu.setDMPEnabled(true);
		attachInterrupt(0, dmpDataReady, RISING);
		mpuIntStatus = mpu.getIntStatus();
		packetSize = mpu.dmpGetFIFOPacketSize();   
	}
}
//--------------------------- end of initMPU ------------------------------------------------------

void getYPR(){                 // gets data from MPU and computes pitch, roll, yaw on the MPU's DMP							   

    mpuInterrupt = false;

    mpuIntStatus = mpu.getIntStatus();
    fifoCount = mpu.getFIFOCount();
    
    if((mpuIntStatus & 0x10) || fifoCount >= 1024) {       
		mpu.resetFIFO();     
    }
	else if(mpuIntStatus & 0x02) {
    
      while (fifoCount < packetSize) 
		  fifoCount = mpu.getFIFOCount();
  
      mpu.getFIFOBytes(fifoBuffer, packetSize);     
      fifoCount -= packetSize;   
      mpu.dmpGetQuaternion(&q, fifoBuffer);
      mpu.dmpGetGravity(&gravity, &q);
	  mpu.dmpGetYawPitchRoll(Motors.ypr, &q, &gravity);   
    }
}
//--------------------------- end of getYPR -------------------------------------------------------

void check_radio(void) {
	RC.read_radio();
}
//--------------------------- end of check_radio --------------------------------------------------
/*----------------------------------------------- end of QuadroCopter_Receiver Mainprogramm -----*/

Wenn ich in der Loop "Motors.setMotor(RC.rxValues.throttle);" auskommentiere, wird "check_radio" und anschließend "RC.read_radio" ausgeführt. Ich komme hier nicht weiter. Wer kann mir bitte einen Schubs geben?

Gruß Kucky

Das Problem liegt wohl daran, das der Interrupt(1) nicht das tut was er soll:

Ich denke schon, dass der Interrupt so funktioniert, wie es der Hersteller Atmel vorgesehen hat.
Daraus folgend könnte man stark vermuten, dass deine Programmlogik/Absicht nicht mit dem Datenblatt konform geht.

Es könnte sein, dass bei dir Interrupts verloren gehen.
Interrupts sind innerhalb von Interruptroutinen abgeschaltet.

Wenn ich in der Loop "Motors.setMotor(RC.rxValues.throttle);" auskommentiere

Werden in setMotors() Interrupts gesperrt?

Dass man Interruptroutinen schlank halten sollte .....
Ein check_radio() in der Interruptroutine ist also vermutlich nicht zu empfehlen.

Meist ist es Besser in der Interruptroutine nur einen Zähler oder ein Flag zu setzen und die eigentliche Arbeit im loop() erledigen zu lassen.

Man könnte auch Interrupts in der Interruptroutine erlauben...
Aber dann muss man wissen was man tut.
Stacküberläufe und Ressourcenkonflikte drohen.

Hallo,

ich vermute auch dass der Aufruf "RC.read_radio();" zu komplex ist.

Schau mal in das Datenblatt des nRF24L01+ Chip.
Wenn ich mich richtig erinnere liefert der Baustein mit der Standartinitialisierung zu drei verschiedenen Zuständen Interrupts.
"RC.read_radio();" prüft erst mal welcher dieser Zustände den Interrupt ausgelöst hat und handelt danach.

Ich vermute dir geht es bei dem Aufruf nur darum festzustellen ob Daten empfangen wurden.
Dann wäre **"RC.available();"**wohl eine schnellere Alternative.

Ich nutze diese Funktion im loop() ohne Interrupt.

Gruß Peter