Как опрашивать DS18B20 в фоне?

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
Опрос двух датчиков занимает почти секунду:
requestTemperatures: 752 ms
getTempCByIndex: 72 ms
 
Вот фрагмент кода:
      long processTime = millis();  // Проверяем, сколько времени занимает запрос к датчикам
      sensors.requestTemperatures(); // Send the command to get temperatures
      Serial.print("requestTemperatures: ");
      Serial.print(millis() - processTime);
      Serial.println(" ms");

      processTime = millis();  // Проверяем, сколько времени занимает чтение датчиков
      float tempSensor1 = sensors.getTempCByIndex(0);
      float tempSensor2 = sensors.getTempCByIndex(1);  
      Serial.print("getTempCByIndex: ");
      Serial.print(millis() - processTime);
      Serial.println(" ms");

Из-за этого неприятно лагает отзывчивость взаимодействия с интерфейсом (LCD, энкодер, кнопки), даже с использованием прерываний.

Как можно "отвлечься" на другие действия, пока датчики делают свою работу?

maksim
Offline
Зарегистрирован: 12.02.2012

Во-первых, отказаться от этой библиотеки и использовать библиотеку OneWire и научиться опрашивать датчик.

Во-вторых, изучить пример "мигаем светодиодом без delay".

В-третих, OneWire запрещает все прерывания в момент общения с датчиком, можно убрать запреты прерываний, но тогда если у вас в обработчиках прерываний жирный код, то датчик может не опроситься. В этом случае можно в обработчик добавить переменную об отмене опроса датчика, что бы не получать некорректные данные и не ждать конвертации, которой не поризойдет. 

LeXXkiev
Offline
Зарегистрирован: 20.03.2016

в-четвертых, можно запрашивать температуру не в каждом цикле loop(), а, скажем, в каждом 2000-м:

int i = 0;

void loop() {
  if (i == 0) { 
    sensors.requestTemperatures();
    sysTemp = sensors.getTempC(ds1);       
  } 
  i = i+1; if (i == 2000) i = 0;
}  
NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

запрос темпиратуры состоит из 2 частей:

1. запрс на измерение

2. запрос на получение измеренной

между ними должно пройти время так-как ацп мгновенно не работает, так вот микроконтроллер не обязательно должен "ждать" пока произойдет измерение, но для этого надо отказаться от библиотеки.

AmateurFF
Offline
Зарегистрирован: 02.02.2015

NeiroN пишет:

запрос темпиратуры состоит из 2 частей:

1. запрс на измерение

2. запрос на получение измеренной

между ними должно пройти время так-как ацп мгновенно не работает, так вот микроконтроллер не обязательно должен "ждать" пока произойдет измерение, но для этого надо отказаться от библиотеки.

Зачем отказываться от библиотеки?

1)  Запрос

sensors.setWaitForConversion(false);
sensors.requestTemperatures();
sensors.setWaitForConversion(true);
 
2) Через время, больше необходимого для преобразования, получаем результат
 
uint8_t sp[9];
sensors.readScratchPad(Thermometer[i], sp);
 
 

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

все уже разобрали, от библиотеки отказались, научились работать в фоне и даже с несколькими датчиками:

http://arduino.ru/forum/programmirovanie/pochistil-sketch-primera-raboty...

dhog1
Offline
Зарегистрирован: 01.03.2016

Мне трудно связать свой ответ с какой-либо библиотекой (обычно пишется свой код), но логика работы 18b20 говорит о следующих действиях.

1. Запускается процедура измерения температуры. Из документации следует, что для этого можно выдать соответствующую команду либо  _конкретному_  датчику, либо  _всем_ , кто на линии.

2. После этого. Если была команда для  _всех_  датчиков, следует выдержать паузу измерения (да, она немаленькая, 750 ms), сбросить 1-wire, потом опросить все датчики. Иными словами - требуем измерения от всех датчиков, выдерживаем паузу, опрашиваем все датчики уже быстро.

3. Либо отдаем команду конкретному датчику. Логика работы с 1-wire подразумевает, что вы работаете либо сразу со всеми (из одного семейства), либо с одним выбраным (ROM командой MATCH ROM) датчиком. Так вот можно отдать команду (на измерение) одному (конкретному) датчику и далее ждать результата, переодически спрашивая этот конкретный датчик о том, готов ли результат. В этом случае нужно читать бит с шины 1-wire, если результат =0, то датчик еще не закончил преобразование, если =1, то датчик закончил измерение и готов к выдаче результата. Иными словами - запустив процесс измерения на одном (конкретном) датчике, вы можете время от времени запрашивать состояние шины 1-wire, чтобы определить степень его готовности к выдачи результата измерения. В результате вы имеете возможность что-то делать между опросами датчика.

Radjah
Offline
Зарегистрирован: 06.08.2014

setWaitForConversion(false) и blink without delay, только сравнивать надо будет со временем конвертации самого медленного датчика или сделать несколько проверок.