I2C + Servo WTF

So:

  • I’ve got some code for interfacing with servos. It works great.
  • I’ve got some code for interfacing with some I2C sensors. It also works great.
  • I try to combine the two into a single program, and the servos stop working.

I’ve boiled down what’s going on to a few lines. It all seems very weird to me…

This code works as expected:

#include <Servo.h>
#include <Wire.h>

Servo s;

void setup()
{
  s.attach(27);

  Wire.beginTransmission(0x1E);
  Wire.send(0x00);
  Wire.send(6 << 2);
  Wire.endTransmission();
  
  s.write(170);
}

void loop()
{
}

However, if I move the s.attach() line down below the Wire calls (as in the following code), the servo doesn’t work. It just doesn’t do anything (I can move it freely by hand).

#include <Servo.h>
#include <Wire.h>

Servo s;

void setup()
{
  Wire.beginTransmission(0x1E);
  Wire.send(0x00);
  Wire.send(6 << 2);
  Wire.endTransmission();
  
  s.attach(27);
  s.write(170);
}

void loop()
{
}

Is this a known issue? Am I required to call servo.attach() before making any calls to Wire?

I’ve noticed that if I send a different byte on the line with Wire.send(6 << 2) – for example doing Wire.send(0x00) instead, somehow that makes code snippet 2 work!@$!@#$

Am I missing something totally obvious here? WTF is going on? Is there some crosstalk between I2C and some of the servo timers? Do I have to wait some amount of time after doing certain things? What’s going on?!

Does servo.attach() call Wire.begin() internally?

If so, remove that code, and call Wire.begin() (only once) in setup().

Does servo.attach() call Wire.begin() internally?

No.

inserting wire.begin() before using wire commands should do it :)

sigh. That fixes it. Thank you very much :-).

It's the simple things you miss when you're banging your head against a problem at 2 in the morning =/.