user71612: I have a fancy setup to cool my beer at a controlled temperature (you can find details and a photo here if you want). The input of my system is a temperature, the output is a servo position.
Long story short
On startup the servo is stable enough, but every time after 67s of runtime suddenly the servo starts vibrating. I have an oscilloscope and I can see that after 67s, instead of a steady 2.3 ms the length of the pulses oscillate in a small range, like between 2.300 and 2.320 ms, and it's enough of a range to be a problem.
What happens at 67s ?? Is there some kind of overflow ? I'm very puzzled because all in all my code for the pulse is very simple.
I'm having my problem on this code, branch bs18b20 of my repo. The pulse is generated line 293, with custom code.
More context
I had already asked for help right here with my setup. We had determined that using Servo.h along along with the 1Wire protocol make the interruptions used by both libraries get in the way of one another, so the servo receives bad values and vibrates too. In my last comment in this thread I said that the problem was solved, but I discovered later the problem of the servo getting unstable after some time, as exposed above.
To overcome that I changed tactics, switched my bs18b20 for a lm35 which doesn't need 1Wire, and switched back to Servo.h. It worked very well... in my electronics lab. But then (reality sucks) I found out when actually using my device in the kitchen that sometimes the temperatures start getting very wrong, and I suspect that the humidity alters the voltage reading of my lm35. And that's why I'm trying to change back again to my previous solution with a waterproof bs18b20.
While writing this, stackexchange proposed this thread with a very promising solution, I will definitely try that. Nonetheless, for the sake of it, I'm still interested in knowing what causes my problem above, so I'm posting this anyway.

user7508: Without looking into the details of your code, it looks like you are
having issues with interrupts. According to your comment, this simple
code gives a very uneven pulse length:
digitalWrite(SERVO_PIN, HIGH);
delayMicroseconds(servo_value*1000);
digitalWrite(SERVO_PIN, LOW);

The function delayMicroseconds() delays for the requested time, plus
any time taken by interrupts. Thus, if the delay is inconsistent while
servo_value does not change, it can only be because of interrupts.
Trying to understand the exact symptoms is likely to be quite hard, as
one would have to dig into the source of the libraries you are using,
and look at every ISR in there. The fact that the version delaying with
micros() only starts misbehaving after some time is probably due to
some very slow “beating” between the timing of your servo and the timing
of an interrupt. The fact that the pulse is occasionally 20 µs
longer is consistent with it having been interrupted for 20 µs,
which for an ISR would be kind of long but not insanely long.
Rather than trying to analyze in detail how the interrupts are
interfering with your servo, I would recommend sidestepping the problem
completely and driving the servo with a hardware-generated PWM signal.
That would give a very consistent pulse length, completely immune to
being disrupted by interrupts. You can achieve 0.5 µs resolution
with a 20 ms period by setting Timer 1 to fast PWM and
clocking it at 2 MHz, like this:
// Configure timer 1 for driving a servo
// on pin OC1A = PB1 = digital 9.
void setup_timer()
{
    TCCR1A = 0;           // undo the Arduino core configuration
    TCCR1B = 0;           // ditto
    ICR1   = 40000 - 1;   // period = 20 ms = 40000 timer ticks
    OCR1A  =  3000 - 1;   // pulse length = 1.5 ms = 3000 timer ticks
    TCCR1A = _BV(COM1A1)  // non-inverting PWM on OC1A
           | _BV(WGM11);  // mode 14: fast PWM, TOP = ICR1
    TCCR1B = _BV(WGM12)   // ditto
           | _BV(WGM13)   // ditto
           | _BV(CS11);   // clock @ F_CPU/8 = 2 MHz
}

Then you can change the pulse length simply by writing to OCR1A: write
one less than the desired pulse length, in units of 0.5 µs.

71612: <p>I have a fancy setup to cool my beer at a controlled temperature (you can find details and a photo <a href="https://gitlab.com/guillaume.deshors/brewing_thermometer" rel="nofollow noreferrer">here</a> if you want). The input of my system is a temperature, the output is a servo position.</p>
<p><strong>Long story short</strong></p>
<p>On startup the servo is stable enough, but every time after 67s of runtime suddenly the servo starts vibrating. I have an oscilloscope and I can see that after 67s, instead of a steady 2.3 ms the length of the pulses oscillate in a small range, like between 2.300 and 2.320 ms, and it's enough of a range to be a problem.</p>
<p>What happens at 67s ?? Is there some kind of overflow ? I'm very puzzled because all in all my code for the pulse is very simple.</p>
<p>I'm having my problem on <a href="https://gitlab.com/guillaume.deshors/brewing_thermometer/-/blob/bs18b20/thermometre/thermometre.ino" rel="nofollow noreferrer">this code</a>, branch bs18b20 of my repo. The pulse is generated line 293, with custom code.</p>
<p><strong>More context</strong></p>
<p>I had already asked for help <a href="https://arduino.stackexchange.com/questions/80700/arduino-uno-pwm-output-and-servo-plugged-on-it-becomes-unstable-if-i-use-1wi/80701?noredirect=1#comment180410_80701">right here</a> with my setup. We had determined that using Servo.h along along with the 1Wire protocol make the interruptions used by both libraries get in the way of one another, so the servo receives bad values and vibrates too. In my last comment in this thread I said that the problem was solved, but I discovered later the problem of the servo getting unstable after some time, as exposed above.</p>
<p>To overcome that I changed tactics, switched my bs18b20 for a lm35 which doesn't need 1Wire, and switched back to Servo.h. It worked very well... in my electronics lab. But then (reality sucks) I found out when actually using my device in the kitchen that sometimes the temperatures start getting very wrong, and I suspect that the humidity alters the voltage reading of my lm35. And that's why I'm trying to change back again to my previous solution with a waterproof bs18b20.</p>
<p>While writing this, stackexchange proposed <a href="https://arduino.stackexchange.com/questions/49421/arduino-reading-ds18b20-interferes-with-servo">this thread</a> with a very promising solution, I will definitely try that. Nonetheless, for the sake of it, I'm still interested in knowing what causes my problem above, so I'm posting this anyway.</p>
 7508: <p>Without looking into the details of your code, it looks like you are
having issues with interrupts. According to your comment, this simple
code gives a very uneven pulse length:</p>
<pre class="lang-cpp prettyprint-override"><code>digitalWrite(SERVO_PIN, HIGH);
delayMicroseconds(servo_value*1000);
digitalWrite(SERVO_PIN, LOW);
</code></pre>
<p>The function <code>delayMicroseconds()</code> delays for the requested time, <em>plus
any time taken by interrupts</em>. Thus, if the delay is inconsistent while
<code>servo_value</code> does not change, it can only be because of interrupts.
Trying to understand the exact symptoms is likely to be quite hard, as
one would have to dig into the source of the libraries you are using,
and look at every ISR in there. The fact that the version delaying with
<code>micros()</code> only starts misbehaving after some time is probably due to
some very slow “beating” between the timing of your servo and the timing
of an interrupt. The fact that the pulse is occasionally 20 µs
longer is consistent with it having been interrupted for 20 µs,
which for an ISR would be kind of long but not insanely long.</p>
<p>Rather than trying to analyze in detail how the interrupts are
interfering with your servo, I would recommend sidestepping the problem
completely and driving the servo with a hardware-generated PWM signal.
That would give a very consistent pulse length, completely immune to
being disrupted by interrupts. You can achieve 0.5 µs resolution
with a 20 ms period by setting Timer 1 to fast PWM and
clocking it at 2 MHz, like this:</p>
<pre class="lang-cpp prettyprint-override"><code>// Configure timer 1 for driving a servo
// on pin OC1A = PB1 = digital 9.
void setup_timer()
{
    TCCR1A = 0;           // undo the Arduino core configuration
    TCCR1B = 0;           // ditto
    ICR1   = 40000 - 1;   // period = 20 ms = 40000 timer ticks
    OCR1A  =  3000 - 1;   // pulse length = 1.5 ms = 3000 timer ticks
    TCCR1A = _BV(COM1A1)  // non-inverting PWM on OC1A
           | _BV(WGM11);  // mode 14: fast PWM, TOP = ICR1
    TCCR1B = _BV(WGM12)   // ditto
           | _BV(WGM13)   // ditto
           | _BV(CS11);   // clock @ F_CPU/8 = 2 MHz
}
</code></pre>
<p>Then you can change the pulse length simply by writing to <code>OCR1A</code>: write
one less than the desired pulse length, in units of 0.5 µs.</p>
