Teensy 4.1 - Problems running interrupts when overclocking

I have a T4.1 running a 4 channel trailing edge dimmer board.

There are 2 interrupts running; 1 is a hardware interrupt which fires every 10mS to indicate ac mains zero crossing point (UK 50Hz),
Code:
void zeroCrossingInt() //This is a hardware interrupt which occurs at 100Hz rate
{
  for (int i=0; i<4; i++)
    if (DimActual[i] > 0)
    digitalWrite(Dim[i], 1);

  dimTickCtr = 0;
  DimTimer1.begin(hwTimer1, DimScaler);
}
the other is a timer which fires every 100uS which gives 1% resolution for turning each channel off.

Code:
void hwTimer1() //This is a Timer Interrupt which occurs 100x for each mains half cycle = 10kHz
{
  dimTickCtr++;
  for (int i=0; i<4; i++)
    if (dimTickCtr >= DimActual[i])
  digitalWrite(Dim[i], 0); 
  DimTimer1.begin(hwTimer1, DimScaler);
}
Everything else runs in a pseudo real time operating loop which cycles every 50mS. I've had a test board running for months with an RPI changing the dimmer values every minute.

This all works great, except for the occasional flicker on the lamps, presumably when the T4.1 gets busy and I discovered that by overclocking it, the flicker disappears completely. However, when overclocked, the T4.1 crashes and reboots intermittently.

I'd always suspect my code first, but since it runs perfectly at 600MHz, I think I'm in the clear.

Anyone have any ideas what might be causing the problem?
 
What kind of Timer interrupt are you using? Usually a timer interrupt is started in your setup code and started only once. You are calling begin on every interrupt which would only be needed if the Timer works as a one-shot. And if using a one-shot, you wouldn't want to start it running again when all the lights are off. I suggest just using an interval timer: https://www.pjrc.com/teensy/td_timing_IntervalTimer.html

My other idea, what happens if you slow down the Teensy. If you make the issue happen more frequently you can trouble shoot the issue easier.
 
These can be challenging to find.

First thing I might try, if you have not already done so, is to put in the Crashreport code in and see if it captures a crash.

Something like:
Code:
  while (!Serial && millis() < 3000)
    ;  // wait for Arduino Serial Monitor
  if (CrashReport) {
    Serial.print(CrashReport);
    Serial.println("\n *** Press any key to continue ***");
    while (Serial.read() == -1)
      ;
    while (Serial.read() != -1)
      ;
  }
Note: If I am not needing Serial stuff at startup normally, I might put in the wait for serail within the if (CrashReport)
Also the waiting for Serial input is optional. In the case I copied once it crashed it would crash each time it restarted which
was a pain, so...

As for crash only at higher speeds. Could still be issue within your own code, as the timings are different and maybe there is a small window
in the code that is vulnerable, and more likely to hit or not depending on speed and the like. Maybe the issue with the lights flickering is same issue,
but manifesting itself differently.

Or maybe running at higher speeds is causing the board to overheat?
 
Another idea for you: how is controlling dimmers not unlike hobby servos? They both have a 50 hz repeat rate for you in the UK. You may be able to control your lights with 4us resolution by adapting the PWMservo library. The only sticky issue would be syncing the PWM library to your 50hz zero cross detection.

https://www.pjrc.com/teensy/td_libs_Servo.html
 
Thanks rcarr and KurtE, you've given me a number of things to follow up on.

The hwTimer didn't originally work unless I restarted it everytime it fired, so I'd assumed it was a single shot timer. It looks like that maybe wrong. If I'm starting a free running timer 5000 times a second and never stopping it, that could be an issue!

I'll report back on this thread when I've made some progress.

Thanks again for your help.
 
The use of CrashReport @KurtE suggested will indicate if there is a TEMP issue with overclocking that can get unusably hot.

What OC speed is being used?

For ref and tracking Temp monitor code looks like:
Code:
	Serial.printf("\n F_CPU=%u", F_CPU_ACTUAL );
	Serial.printf( "\tdeg  C=%u\n" , (uint32_t)tempmonGetTemp() );
 
Don't think it can be heat. I now have a setup which fails predictably within 1 second of setting a dimmer value above 0% (It runs forever with all channels set to 0%)
I have a thermal camera and it shows under 35°C.
I now start the hwTimer in setup and not in either of the interrupts. It still runs correctly at 600MHz, but fails 720MHz and 816MHz.
 
Heat not too bad at those speeds - usually. If it is heat, the CrashReport() output would indicate that. If it is Crashing through that code - there may be an 8 second delay - though with TEMP fault not sure the timing comes into play before restart.
> a Heat Crash can be caused by an instantaneous spike issue that would not be externally observable - and may not even be measured by the on die thermal measure. Though usually more likely at higher OC speeds when "cooling req'd".

The Teensy has to stay under power and have Serial USB on restart to show the report. The report information is maintained in a portion of RAM2/DMAMEM that is not cleared on Reset.

If USB Serial not available, the CrashReport output is a Stream and can go to a file on LittleFS or SD card for later recovery. Once 'read'/'displayed' the data is cleared so it won't show on following power up when the prior restart was not caused by a 'Crash'.
 
Just back from a few days away.

I've put CrashReport in, but its not recording anything. I tried sending it to the serial monitor at next start up and sending it to SD card , but neither shows up. I forced a crash by deliberately running a variable loop until it overflowed and that worked, so I know it'll record a crash.

The highest CPU temperature I've been able to record is 54°C which sounds ok.

I can cause the crash at 720MHz, 816MHz and also at 600MHz, using 'Fastest', 'Debug' or 'Smallest Code' - 'Fast' and 'Faster' both work reliably.

If all 4 channels are 0, I disable the Timer now. This makes no difference.

I'll look at the possibility of adapting PWM library to do the job, but still open to any other suggestions anyone may have.
 
Back
Top