Teensy 3.6 max interrupt frequency

Status
Not open for further replies.

opauly

Member
Hello,

I am trying to execute an interrupt to send data over an nRF24L01+ radio as Tx, and this interrupt is triggered by a rising edge from a PWM signal coming from a Teensy 3.2. The idea is to generate this "clock" frequency from the Teensy 3.2 and "sync" many other Teensy 3.6 to send data.

The issue is that if I take the clock over 615 Hz, the interrupt starts to jump or lose rising edges. The way I prove this is by printing the difference in microseconds between the last two receptions in the Rx, and over 615 Hz is when this difference goes over the expected (using 1 kHz, I get 1627 us when it should be 1000 us).

Any idea on what could be the issue?

Thanks!
 
A code showing the issue would be needed to get/give a good answer.

The T_3.6 can easily respond to interrupts well beyond 1KHz if not a MHz or more depending on what code is in _isr()
 
This is the code running in the Tx:

Code:
#include <Audio.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include "Bloquecito.h"

// must be a number from 1 - 6 identifying the PTX node
#define WHICH_NODE 1

AudioInputI2S i2s1;
AudioOutputI2S i2s2;
Bloquecito b;

AudioConnection patchCordEntradaBloquecito(i2s1, 0, b, 0);
AudioConnection patchCordBloquecitoSalida(i2s1, 0, i2s2, 0);
AudioControlSGTL5000 sgtl5000_1;

RF24 radio(15, 16);

 unsigned char total_data[256];
 unsigned char total_data_timestamp[32];
 unsigned char sample_in_bytes[4];
 unsigned char time_in_bytes [4];
 unsigned char prueba_dato = 0x20;

 uint32_t time;
 uint32_t time_read;

//Clock signal interrupt pin
const int clock_pin =21;
const int clock_pin_2 =22;
const int ledPin = 13;

int rec[1] = {0};

// CHANGE AS REQUIRED
const int payload = 64;
uint32_t numbers[payload] = {0x10101010, 0x11111111, 0x12121212, 0x13131313,
                            0x14141414, 0x15151515, 0x16161616, 0x17171717,
                            0x21212121, 0x22222222, 0x23232323, 0x24242424,
                            0x25252525, 0x26262626, 0x27272727, 0x28282828,
                            0x31313131, 0x32323232, 0x33333333, 0x34343434,
                            0x35353535, 0x36363636, 0x37373737, 0x38383838,
                            0x41414141, 0x42424242, 0x43434343, 0x44444444,
                            0x45454545, 0x46464646, 0x47474747, 0x48484848,
                            0x51515151, 0x52525252, 0x53535353, 0x54545454,
                            0x55555555, 0x56565656, 0x57575757, 0x58585858,
                            0x61616161, 0x62626262, 0x63636363, 0x64646464,
                            0x65656565, 0x66666666, 0x67676767, 0x68686868,
                            0x71717171, 0x72727272, 0x73737373, 0x74747474,
                            0x75757575, 0x76767676, 0x77777777, 0x78787878,
                            0x81818181, 0x82828282, 0x83838383, 0x84848484,
                            0x85858585, 0x86868686, 0x87878787, 0x88888888};
                            
const uint64_t wAddress[] = {0x7878787878LL, 0xB3B4B5B6F1LL, 0xB3B4B5B6CDLL,
                             0xB3B4B5B6A3LL, 0xB3B4B5B60FLL, 0xB3B4B5B605LL};
                             
// Pull the address from the above array for this node's pipe                            
const uint64_t PTXpipe = wAddress[ WHICH_NODE - 1 ];


void setup()
{
  Serial.begin(19200);
  
  //SPI custom pins
  SPI.setMOSI(7);
  SPI.setMISO(12);
  SPI.setSCK(14);
  SPI.begin();

  radio.begin();
  radio.openWritingPipe(PTXpipe);
  radio.setChannel(108);
   radio.setAutoAck(true);
  radio.enableAckPayload();
  radio.enableDynamicPayloads();
 // radio.setAutoAck(0);
  radio.setDataRate(RF24_1MBPS);
  //radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();

  pinMode (clock_pin, INPUT_PULLUP);
  pinMode (clock_pin_2, INPUT_PULLUP);
  attachInterrupt (clock_pin, isr_message, RISING);
  pinMode (ledPin, OUTPUT);


  for(int i=0; i<28; i++){
   total_data_timestamp[i] = total_data[i]; 
  }

}

void loop()
{
/* 
 *  data []is also 32 bit aligned in memory, so data can be fetched in pairs of
 *  16 bits. 
 *  The number of samples  placed in each block is 128.
 *  
 */
 for(int i = 0; i < payload; i++){
  /* Using numbers array instead of sampled data for testing purposes */
     b.uint32_t_to_byte (numbers[i], sample_in_bytes);
   
    for (int j = 0; j < 4; j++) {
      total_data[4*i +j] = sample_in_bytes[j];  
    }
   
  }
}

void isr_message() {
time = micros();
  b.uint32_t_to_byte (time, time_in_bytes);

for(int j=28; j<32;j++){
   total_data_timestamp[j] = time_in_bytes [j-28];
  }

 b.byte_to_uint32_t(time_in_bytes, &time_read); 

 radio.write(&total_data_timestamp[0], 32);
 radio.txStandBy();

  time = micros();
  b.uint32_t_to_byte (time, time_in_bytes);

}
 
Without the hardware and libraries that sketch won't run locally.

The problem though is likely the time the _isr takes is over 1/625 == 0.0016 seconds to deal with the time and then get that message through radio.write().

Meaning the next _isr() is blocked from starting as the prior has not completed. Such code shouldn't typically be placed in an _isr()

That time should show if this is commented out in setup() :: // attachInterrupt (clock_pin, isr_message, RISING);

and this placed in loop():
Code:
	uint32_t timeA = micros();
	isr_message();	
	timeA = micros() - timeA;
	Serial.print( "timeA=");
	Serial.println( timeA);
	delay(250);
 
I have a Teensy 3.6 servicing MPU-9250 interrupts at 32KHz. But I had to pay a lot of attention to how much time was required to transfer data. Even running the SPI port at 20MHz the timing is tight. That rather than the Teensy 3.6 CPU clock was the limiting factor.

I think that the Teensy SPI library defaults to a 4MHz clock. But that assumes the clock source can be evenly divided to get 4MHz so depending on clock system settings the actual SPI clock could be lower.
 
Status
Not open for further replies.
Back
Top