ServoTimer1 and delay(): incompatible?

Hi, new here, please excuse me if I’ve posted this in the wrong place!

I was trying to use the code to talk to the HMC6352 digital compass at the same time as the ServoTimer1 library when I ran into some issues… after some trial and error I’ve narrowed it down (I think) to this odd behavior: once you have invoked ServoTimer1.attach(), any call to delay() will halt Arduino.

Bug reproducing code:

// Bug repeat code for ServoTimer1 library and delay
// Demonstrates how delay halts Arduino once ServoTimer1.attach has been invoked 

#include <ServoTimer1.h>

ServoTimer1 servo1;

void setup()
{
  pinMode(1,OUTPUT);
  Serial.begin(9600);
  Serial.println("Before first delay");
  delay(20);
  Serial.println("After first delay");
  Serial.println("Before attach");
  servo1.attach(9);                     // comment this line in and out to see the second delay hang or not
  Serial.println("After attach");
  Serial.println("Before detach");
  servo1.detach();                         // detaching the servo before the delay does NOT help
  Serial.println("After detach");
  Serial.println("Before second delay");
  delay(20);
  Serial.println("After second delay");
}

void loop()
{
  Serial.println("Made it to the loop!");
  delay(500);
}

This is not the code I started with, just a little sketch which reproduces the same behavior. If you comment in or out the line with the attach() command, you will see (in Serial Monitor) that Arduino halts, or not, at the delay() command which follows. I’ve tried this with more processing between attach() and delay(), or even looping back before delay() and gotten the same results.

Since ServoTimer1 deals with hardware timers in Arduino, I figure it’s not out of the realm of the possible that it messes up delay… but perhaps I’m committing some typical newbie mistake and you guys can set me straight in a jiff.

Incidentally, my original code seems to be happy without any delays (i thought I needed to give the HMC6352 some time before reading the heading data, but apparently not), so this is not urgent. I just thought I’d share and be enlightened.

UPDATE: Thought I’d mention that I had to apply the patch quoted below to ServoTimer1.cpp to get the library to compile. I don’t know if it’s significant!

Ok,

Looking at the datasheet(s) for both the Atmega 8 and atmega16, I think the error is partially coming from the fact that the register bit “TICIE1” does not exist in the Atmega168.

Changing lines 42-43 to this lets Arduino build the library:

#if defined(__AVR_ATmega168__)

TIMSK0 &= ~( _BV(OCIE1A) | _BV(OCIE1B) | _BV(TOIE1) );




D

Hum, doesn't seem to inspire much comment :-)

Did some more experimenting, and I'm here to report two new facts:

  1. Switching ServoTimer1 out for Servo library causes the problem to go away.
  2. millis() is just as dead as delay() once a servo has been attached using ServoTimer1 library, it returns 0 no matter what.

I suspect the death of millis() is probably what hands Arduino on delay() calls. No time keeping, so delay loops forever.

This is what your are looking for :

#if defined(__AVR_ATmega168__)
    //TIMSK0 &= ~(_BV(TICIE1) | _BV(OCIE1A) | _BV(OCIE1B) | _BV(TOIE1) );
    TIMSK1 &= ~(_BV(ICIE1) | _BV(OCIE1A) | _BV(OCIE1B) | _BV(TOIE1) );
#else
    TIMSK &= ~(_BV(TICIE1) | _BV(OCIE1A) | _BV(OCIE1B) | _BV(TOIE1) );
#endif

Thanks for your reply, but I made the change you suggest to ServoTimer1.cpp and I still hang on delay() with the demo code in my initial post, and other sketches using ServoTimer1 library.

It must be something else...

It seems to be a probleme with ServoTimer1.o.

Arduino seems not to update the .o when the .cpp is updated.

First remove the ServoTimer1.o, then re-upload your sketch.

Thank you for your persistence :-)

Alas, that has not solved the problem either. I have removed ServoTimer1.o, re-compiled my sketch, uploaded it and I still hang on delay().