Teensy unknown behaviour on interrupt

I have been using the following interrupt on my Teensy 3.5 and it's been working perfectly:

pinMode(3, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(3), SpeedPulse, RISING);

When i connect other pulse (on any other pin) which is faster than interrupt on pin 3, Interrupt on pin 3 disturbed and detect rising more rapidly.

Even without any other code, don't know why its interrupt on pin 3 is increase from 100Khz to 140Khz.

But without the sketch and maybe wiring, how can we know or find what you have not?

Sketch is very simple,

#define synPin 4
int count =0;
void setup() {
  pinMode(synPin,INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(synPin), interrupt, RISING);
}
void loop() {}

void interrupt()
{
    count++;
    if(count == 100000)
    {
    Serial.println(count);
    count = 0;
    }   
}

And when pin 4 is connected to 100Khz pulse result is ok.
Without changing code even same sketch uploaded when i connected a 2Mhz wire to Teensy any pin
, output changes from 100khz to 138khz to 150khz.

Never print from inside of an interrupt!

When writing an Interrupt Service Routine (ISR):

  • Keep it short

  • Don't use delay ()

  • Don't do serial prints

  • Make variables shared with the main code volatile

  • Variables shared with main code may need to be protected by "critical sections" (see below)

  • Don't try to turn interrupts off or on

I add one: don't trust code from Instructables!

Nick Gammon's Interrupt Tutorial, he is a good teacher!

1 Like

Do you seriously expect to be able to handle 2,000,000 interrupts per second? Have you counted how many clock cycles it takes to execute your ISR?

1 Like

Yes teensy 3.5 accuratly reading 2000000 pulses per second.

ISR has an 85 cycles overhead too.

Ok any solution ?

which input coming from what? which output?
The sketch you posted above does not contain a Serial.begin() at what baudrate?

To come closer to a solution provide more information.

To be more specific about why it is important to provide more information

Ok any solution ?

use timer2 instead of timer3 to create the 2 MHz-Signal on the same teensy on pin 27. Use shielded wiring for feeding in your 2 MHz-signal.

The sentence above is completely nonsense just to demonstrate that so many things about your setup are unclear

best regards Stefan

@StefanL38 My basic question is that, is it possible to read 2MHz clock from Teensy? If not! then "ok suggest any solution"

Going in detail, i am trying to read a microcontroller output from teensy 3.5 which have three signal output

  1. Clock 2 Mhz
  2. Sync
  3. 20 bit data

I have to read every bit of data on Clock falling edge.
Sync is in high state during data is comming.

Still non sense?

Ahaa!
Still some questions:

So does this mean there is a first Teensy 3.5 that does sending

and you have a second Teensy 3.5 that read IN this serial data?

Or does the 2 MHz clocked signal come from a different source?

It would help a lot of you would post a hand-drawn picture that shows what kind of device is sending and what kind of device is receiving the serial data-stream.
You are working on an informatic project and what is most needed in an informatic project is: information

As you are working with a Teensy. Have you considered asking in the PCJR-Forums that are especcially about Teensy-microcontrollers?

best regards Stefan

Thanks for your reply.

  1. No,Sending device is a EZCAD control card.

And below is the output from EZCAD card

  1. Yes second is teensy 3.5 .

  1. No, 2 MHz , sync and data is coming from same EZCAD card and i want to receive/decode it on teensy 3.5.

  2. And don't know why PCRJ Forum blocked on my side even try on multiple ISPs, trying to register but still same message.

now that picture shows the relevant information of what has to be done.

The condition to get ready for reading in the databits is
if sync-signal is low on the falling edge of the clock-signal

then as long as sync-signal is HIGH read in databits on the falling edge of the clock-signal

This means you can configure an interrupt for the clock-signal with invoke interrupt on FALLING.

Inside the ISR check logic level of the SYNC-input and if SYNC-input is HIGH
bitshift the value of the databit into a variable

Are you able to make the EZCAD control card send a constant value?

If not do you have a second teensy that could act as a dummy for having under control what value you are sending?
As the approach is interrupt driven for testing the read-in logic to work right you could use a lower-frequency for the clock

best regards Stefan

Yes exactly and i am on the same page but when i configure interrupt on clock falling edge it goes slow down when I digitalRead(syncPin) or digitalReadFast(sync) for checking sync pin is high/low.

Its teensy 3.5 slowness need other fast development board than teensy 3.5 ?

I don't understand what you wanto to say with that. To me it seems that your english-knowledge is limited. If this is true write your answer in a texteditor in your native language and then do copy & paste and let do google translate the translation to english.

If you do any kind of serial printing inside an ISR
serial printing is slowing down !

Again: You are working on an informatic project and most important in an informatic project is sufficient information.

In this case this sufficient information is your complete sketch that you used to test it.

If you want any kind of information that your reading in worked correct it must be done in a different way than serial printing inside the ISR

You could use a boolean flag to read in a single 20bit dataword and after reading in that single dataword set the flag-variable to true and then do the printing outside the ISR

2 MHz clock is pretty fast.
Is this a continuosly datastream at 2 MHz-clock and do you need each and every 20bits ?

If not using 3 cascaded bitshift-registers like a

CD74HCT597
High Speed CMOS Logic 8-Bit Shift Register with Input Storage

might be a solution.

Or using a teensy 4.0 which has a clock of 600 MHz

maybe using a part of the Teensy 3.5 hardware can be used for reading in the databits

best regards Stefan

That 85 cycles is on an AVR to save the state of the processor and jump to the interrupt, run that and then restore and jump back. What is in between, make as fast as you can.

Another way is to poll with the least overhead you can manage. See what kind of average frequency you can get.

Both ways have to read and at least store the data as well.

With a 180MHz Teensy 3.5, there should be a nanos() function even if the grain is 10's or 100 nanos per tick just to time sub-microsec events.

Example of polling on an AVR, I debounce button pins by reading them twice a milli into a byte that gets x2 before the read, a 0 or 1, is added. The value in binary shows 4 millis worth of pin state history. The compares are built in, the timing is when to read, less code = faster.
When the history byte shown in binary and the pin is INPUT_PULLUP,

10000000 is button up-down transition detected and stable.
00000001 is the down-up, the release.

One function in void loop() does the reads and the other functions compare the history to their trigger value to run or not in loop and loop keeps looping the driving wheel of all the functions.

If you collect digital data at regular intervals you can store it as bits.
If the interval is small compared to your timing tolerance, should be good.

@GoForSmoke Thanks for your reply and good suggestions.

My task is not to store or serial print , but i will test as you said.
But my actual task is to convert a 20 bit binary (2 Mhz Clock) to 16 bit binary (2MHz clock) and write it on other pin in real time. No storing no serial print needed.

Finaly this 16 bit with will use as Input of 16bit DAC for real time analog out.

@StefanL38 sorry for limited english knowledge!

I think your only hope of making that work would be to write the whole thing in assembler, using NO Arduino library calls of any kind, and the processor will be unable to do ANYTHING else. Even then, it could be a stretch. You will be fielding an interrupt at least EVERY 60 CPU clock cycles.

Just an idea here … it would take a lot of work to determine feasibility. Perhaps your input signal could be made to look enough like SPI to use the Teensy's hardware SPI interface. The Teensy would have to operate in SPI Slave mode. You'd probably need some external logic to make the Sync signal act as Slave Select. Because SPI operates on bytes, I'd to read 5 bytes (40 bits) at a time. That equals two of your data words. Two other thoughts that might help … use DMA to transfer from the Teensy's SPI hardware to memory … use ping-pong buffer techniques.

Well, that's a sketchy outline. The rest, as they say, is left as an exercise for the student.