Interrupt and servos. Can they work together?


I am using a Photon with a project that has some servos attached to : WKP, A5, A4

I am also using D2 as an interrupt input attached to it for measuring flow meter.

The servos I move with .write, and then do some delay’s to wait for them to move, and then I .Detach the servos to prevent them from BUZZING… And then start the water flow and start counting flow meter pulses…

However the flow count freezes and stops counting when in conjunction with the servos, although there is signal in the pin as checked with an oscilloscope… If I remove the servo usage completely (never attach the servos in code)… The pulse count interrupt starts working as expected.

Another issue:
I noticed that when I detach 1 of the servos, all other servos detach. And when I attach that particular servo… 2 servos get attached. As if the attach/detach command was being implemented in two servos. However the .write command does work as expected on each servo…

Any help would be very appreciated. I am tearing my hair apart!

I know there’s some issues where some pins can and can’t be used as interrupts at the same time. Could I be affected by my choice of pins?

Can you produce a minimal sketch that does show your issues and post here

I think you had several questions before and this is usually one of the responses you got to start with? Always try to provide code with your initial post!


some hints

Possible causes might be in connection with interrupt priorities (higher masking lower, or use of noInterrupts() in used libraries, …

Is it really all servos, or are just the servos on A4 & A5 joined?
This would be comprehensible, since both pins share the same timer (TIM3) which gets disabled by Servo.detach() while WKP/A7 is tied to TIM5.
You could try to substitute A4 or A5 with one of these D0/D1 (both TIM4) or RX/TX (both TIM1).

BTW: D2 also is tied to TIM3. Maybe try D4 which has no timer attached.

On second thought. Have you got three seperate instances of Servo or are you using one object for all pins (which would explain your issue too)?
Servo.detach() is implemented like this

bool Servo::detach()
  if (!this->attached())
    return false;

  HAL_Servo_Detach(this->pin); // this disables the timer even for other pins that share the same HW timer

  this->resetFields();  // this resets all instance fields 

  return true;

void Servo::resetFields(void)
  this->pin = NOT_ATTACHED;
  this->minAngle = SERVO_DEFAULT_MIN_ANGLE;
  this->maxAngle = SERVO_DEFAULT_MAX_ANGLE;
  this->trim = 0;


No. Only the ones shared in the same timer.

I will work tonight on a minimal code… I have one for testing, but needs cleaning.

I am using three separate servo instances/objects for each servo.

— So is there a way to detach one specific servo? Or attach one specific servo? Also attaching one servo attaches all the shared servos on the same timer…

Sorry I am very newbie, but will work hard on making my help request posts better.

I don’t think so for shared timer servos, but I’ve opened a GitHub issue for this

But the faulty reattaching you see might just be a misinterpretation of the effects.
Since the first detach stopped the shared timer servo too, the second did not actually detach correctly and hence just kicks back in once the shared timer get restarted.