I have an Arduino with a servo, INA219 (current and voltage sensor) and 2 DS18B20 connected to it.
DS18B20 are connected in full-power mode with 5k resistor connected between DATA line and +5V.
I use DallasTemperature library: https://github.com/milesburton/Arduino-Temperature-Control-Library
I get the temperature readings, but the problem is that my servo is jittering slightly almost every time temperature reading is done. If I disconnect DATA line from pin 2 (where it's normally connected) then servo is not moving anymore and everything is fine.
Any ideas what might be causing it? I would expect servo interfering with OneWire readings, not the other way around :)
Here is the full code: https://pastebin.com/xcES4PVT
Here is the minimal example with which I can reproduce the problem:
#include <DallasTemperature.h>
#include <Servo.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
Servo myservo;
long previousMillis = 0;
long tempRequestedMillis = 0;
bool tempRequested = false;
void setup(void)
{
// start serial port
Serial.begin(115200);
Serial.println("Dallas Temperature IC Control Library Demo");
myservo.attach(9);
// Start up the library
sensors.begin();
sensors.setWaitForConversion(false);
}
void loop(void)
{
unsigned long currentMillis = millis();
if (!tempRequested && currentMillis - previousMillis > 2000) {
previousMillis = currentMillis;
sensors.requestTemperatures(); // Send the command to get temperatures
tempRequestedMillis = currentMillis;
tempRequested = true;
} else if (tempRequested && currentMillis - tempRequestedMillis > 2000) {
Serial.println(sensors.getTempCByIndex(0));
tempRequested = false;
}
}
2 Answers 2
Arduino's Servo library on AVR uses interrupts; if interrupts are disabled for any amount of time, the servos will twitch.
1-Wire protocol (used by DS18B20) needs to disable interrupts for the protocol to work. Therefore, servos glitch.
There is a great explanation of the problem here: https://learn.adafruit.com/neopixels-and-servos/overview , just mentally replace "Neopixel library" with "OneWire library". Their TiCo_Servo library sounds just like what you want.
-
That was it! After using TiCoServo library there are no issues! Thanks a lot!Leonti– Leonti2018年02月03日 11:53:17 +00:00Commented Feb 3, 2018 at 11:53
-
The OneWire library was poorly implemented IMO. It globally disables all interrupts when it only really needs to disable interrupts on the data line. If other interrupts are well behaved and return quickly, it won’t disrupt the One wire timing. I don’t know how to turn my avr code into an Arduino library, but there’s an alternative implementation in my digital thermometer project. github.com/rubberduck203/digital-thermometerRubberDuck– RubberDuck2018年02月03日 14:05:21 +00:00Commented Feb 3, 2018 at 14:05
Reading a DS18B20 the naive way takes up to 1500ms because you have to trigger a temperature conversion, then wait for it to complete.
If you have them full-powered, you better trigger the conversion, continue with your program and read the result 2 seconds later, when it's done. You can also trigger the conversion on all connected DS18B20 simultaneously by using the Skip ROM command before sending the Convert T command.
Please see the documentation of Maxim/Dallas' library how to do that.
-
I tried to use
setWaitForConversion
which shouldn't wait for conversion and then read the results 2 seconds later - still the same problem. I've attached the minimal code which has the problem, would you mind taking a look at it?Leonti– Leonti2018年02月03日 02:52:32 +00:00Commented Feb 3, 2018 at 2:52 -
Looks okay, are you sure you aren't accidentally running the old code?Janka– Janka2018年02月03日 03:04:54 +00:00Commented Feb 3, 2018 at 3:04
serial.print
statements