Testato / SoftwareWire

Creates a software I2C/TWI bus on every pins
GNU General Public License v3.0
148 stars 33 forks source link

Problem with servo's #21

Open wjbraat opened 5 years ago

wjbraat commented 5 years ago

Hi, I am a happy user of your library. Yesterday I ran into a problem however. I was using a software I2C on pins D12 (SDA) en D13 (SCL). This works fine. When I attached a group of 6 servo's (pin D3-D5-D6-D9-D10-D11)) to the controller the problem occurred. The servo's on D9, D10 and D11) connected to PortB (same Port as SDA-D12 and SCL-D13) these servo's started oscillating. This also happens when the servo-objects are not written to.

When I moved the software I2C to PortC (A0-SDA and A1-SCL) the problem was gone.

Does the timing of SoftwareWire interfere with the servo timing?

Kind Regards, Willem Braat (Netherlands)

wjbraat commented 5 years ago

I am using an Arduino Pro Mini (5V) on 16 MHz.

Koepel commented 5 years ago

Yes, it does interfere. Thank you for reporting this issue and for your clear explanation.

It is the same issue as issue https://github.com/Testato/SoftwareWire/issues/5

The Servo library uses one timer with one interrupt. In the interrupt routine the PWM signals are written to the pins. To do that, the interrupt must run at a high rate. The SoftwareWire library reads a register, changes a bit, and writes the register back. That is not safe.

The OneWire/OneWire.cpp library uses noInterrupt() and interrupt() every time a register is changed. We have to add that as well.

Can you use a different port to avoid it?

wjbraat commented 5 years ago

Thanks you for the quick response. When I moved the software I2C to PortC (A0-SDA and A1-SCL) the problem was solved!

Regards, Willem

wjbraat commented 5 years ago

It is not often that one uses all 6 PWM ports. For this design it was necessary. So, the workaround is quite simple: don't run SoftwareWire on a port that drives a servo... :-) Willem