MQS vs pin interrupts

PE4WJ

Member
Hi all,

In my project (see https://pe4wj.wordpress.com/2024/02/20/qmac-hf-90-free-tune-conversion/ ), I am using MQS on a Teensy 4.0 (and find the quality pretty decent when using it to drive an external amplifier), in conjunction with a rotary encoder that is setup to trigger interrupts on pin changes, using Ben Buxton's very nice rotary library. Now, whenever an interrupt fires due to the rotary encoder being rotated, there is a loud click in the MQS output which is not there when using a Teensy audio shield. I therefore suspect some kind of contention in the hardware peripherals within the chip. Any pointers?

Many thanks in advance!

Wouter Jan
 
I tried with a PT8211, but same issue there. I guess I will have to use polling instead of interrupts for the encoder.

Wouter Jan
 
Ben Buxton's Rotary library uses attachInterrupt(). Now it is possible to change the interrupt priority of attachInterrupt(), see this thread and this thread.
NVIC_SET_PRIORITY(IRQ_GPIO6789, 255); should do the trick. Standard priority is 128, 255 is lower priority.
However, I don't know whether the MQS audio object uses GPIO interrupts as well (don't think so), so your mileage may vary...

Paul
 
Last edited:
Looked at that library briefly. I only see attachInterrupt within this example, not the actual library code.

So many things are wrong with that example!

1: attachInterrupt() uses hard-coded interrupt numbers for Arduino Uno. Should use digitalPinToInterrupt() as documented on Arduino's site.

2: rotate() function is called as interrupt, and in turn calls Serial.println(). Can crash if other non-interrupt code is also calling Serial.print().

3: stores result in a global variable not declared as volatile.

If your program was created by adapting that example, might be a good idea to show us your code. Interrupts are tricky to use correctly. This library doesn't help with any of that... it becomes your problem. We can help, but only if we see your code. Best to share the whole program, because small details like whether variable are declared with volatile can make a big difference.
 
Hi Paul,

No I did not use the example code verbatim, but the encoder handling is probably an area where my code can be improved. Understood on the shortcomings of the example code!

I can confirm that setting interrupt priority to 255 as suggested has fixed the audio click issue, thanks a lot!

The source code for my project (of which I am sure it can be improved as I am not a software engineer by trade), is available here: https://github.com/pe4wj/hf90f/tree/cw

Best regards,

Wouter Jan
 
Looked very briefly at your code. There's a lot going on within that rotate() function. It does many String operations, and calls a display() function which calls other stuff that looks like it might take quite some time.

If you're happy with how things are working using the interrupt priority change, maybe best to leave well enough alone. But if you ever do consider restructuring your program, I'd recommend minimizing the work done within any functions that get called from interrupts. You probably should just update a volatile count variable and set a volatile boolean flag. Then in the main program, monitor that flag and copy the count and reset the flag (get to temporarily disable interrupts so you always are assured to not miss another update) and then do all that extra work of comparing strings and updating your display from non-interrupt code.
 
Many thanks Paul! So, I made the rookie mistake of trying to do a lot of time consuming operations within the ISR! Even though it works now, I agree it's not good practice. So, since the code is in need of restructuring anyway, I will take your advice on board when doing so.

Thanks!

Wouter Jan
 
Back
Top