Arduino: чтение DS18B20 мешает сервоприводу

У меня есть Arduino с сервоприводом, INA219 (датчик тока и напряжения) и двумя подключенными к нему DS18B20.

DS18B20 подключены в режиме полной мощности с резистором 5 кОм, подключенным между линией DATA и +5 В.

Я использую библиотеку DallasTemperature: https://github.com/milesburton/Arduino-Temperature-Control-Library

Я получаю показания температуры, но проблема в том, что мой сервопривод слегка трясется почти каждый раз, когда выполняется измерение температуры. Если я отключу линию DATA от контакта 2 (куда он обычно подключен), сервопривод больше не будет двигаться, и все будет в порядке.

Есть идеи, что может быть причиной этого? Я ожидал, что сервопривод будет мешать показаниям OneWire, а не наоборот :)

Вот полный код: https://pastebin.com/xcES4PVT

Вот минимальный пример, с помощью которого я могу воспроизвести проблему:

    #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

Обсуждение

возможно, что-то занимает слишком много времени в цикле... начните с закомментирования всех операторов serial.print, @jsotola

У меня та же проблема, что и у Леонтия. НО в моем случае у меня есть Duemilanove и ЖК-экран, который занимает контакты 9 и 10, которые, как я прочитал, являются необходимыми в Duemilanove для работы с этой библиотекой. Есть ли возможность использовать другие пины? Есть ли другая библиотека, использующая другие контакты? У меня свободны: А1,А2,А3,11,12 и 13..., @Juan Vivo


2 ответа


Лучший ответ:

6

Библиотека сервоприводов Arduino на AVR использует прерывания; если прерывания отключены на какое-то время, сервоприводы будут дергаться.

Протокол 1-Wire (используемый DS18B20) требует отключения прерываний для работы протокола. Поэтому сервоприводы дают сбой.

Здесь есть отличное объяснение проблемы: https://learn.adafruit.com/neopixels-and-servos/overview , просто мысленно замените «библиотеку Neopixel» на «библиотеку OneWire». Их библиотека TiCo_Servo звучит как раз то, что вам нужно.

,

Вот и всё! После использования библиотеки TiCoServo проблем не возникает! Большое спасибо!, @Leonti

Библиотека OneWire была плохо реализована, по моему мнению. Она глобально отключает *все* прерывания, когда ей действительно нужно отключить только прерывания *на линии данных*. Если другие прерывания ведут себя хорошо и быстро возвращаются, это не нарушит синхронизацию One Wire. Я не знаю, как превратить мой код avr в библиотеку Arduino, но в моем проекте цифрового термометра есть альтернативная реализация. https://github.com/rubberduck203/digital-thermometer, @RubberDuck


1

Считывание DS18B20 простым способом занимает до 1500 мс, поскольку необходимо запустить преобразование температуры, а затем дождаться его завершения.

Если они у вас полностью заряжены, вам лучше запустить преобразование, продолжить программу и прочитать результат через 2 секунды, когда она будет завершена. Вы также можете запустить преобразование на всех подключенных DS18B20 одновременно, используя команду Skip ROM перед отправкой команды Convert T.

Как это сделать, смотрите в документации библиотеки Maxim/Dallas.

,