убрать delay из библиотеки ds18b20

mitos
Offline
Зарегистрирован: 11.12.2011

Помогите убрать delay из библиотеки  DallasTemperature

Для работы с датчиком необходимо выдерживать временные паузы , в библиотеке это реализовано через delay() .

Но я использую эту библиотеку в часах и из за delay индикация секунд идет с пропусками .

Как я понимаю надо delay заменить на использование millis как в этом примере http://arduino.ru/tutorials/BlinkWithoutDelay.

Но написать не получается , может кто поможет переделать фрагмент кода , был бы очень благодарен.

switch (*bitResolution)
{
case 9:
delay(94);
break;
case 10:
delay(188);
break;
case 11:
delay(375);
break;
case 12:
default:
delay(750);
break;
}
 

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

В этом случае тебе нужно отключить библиотеку 1-Wire вытащить из нее нужные тебе функции (reset, write, read), написать их обычными функциями в своем скейтче, затем в этих функциях заменить задержки на свою функцию DELAY(), в которой будет обрабатываться дисплей.

step962
Offline
Зарегистрирован: 23.05.2011

А давайте с другой стороны взглянем на проблему: м.б. у вас часы реализованы криво?

Есть подозрение, что попытка убрать delay из функций работы с DS18B20 потребует существенно большей переделки, чем модификация часов. Организуйте изменение индикации через прерывание и забудьте о пропусках.

mitos
Offline
Зарегистрирован: 11.12.2011

step962, избавление от использовнания delay прошла успешно , заодно отказался в своем скетче и от использования библиотеки DallasTemperature обошелся просто onewire.

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

Было бы очень интересно взглянуть .

p.s. вместо delay(1000) использовались вот такие строки 

time_cam = millis();
  if ((millis()-time_cam) > 1000) {}

whoim
Offline
Зарегистрирован: 03.11.2011

 в работе с прерыванием вы пишете свой код отдельной функцией, переменные кроме буферов/временных выносите глобально. В сетап настраиваете таймер на вызов вашей процедуры с нужной частотой (раз в секунду?). delay в основном коде программы или библиотеках никак не влияет на частоту вызова привязанной к таймеру процедуры. Если ваша процедура значительно кушает процессорное время - делей будет "тормозить", работая больше чем положено ему в аргументе (на моем опыте).

step962
Offline
Зарегистрирован: 23.05.2011

 Чтобы такое торможение происходило, необходимо умудриться повесить свою функцию прерывания по времени на тот же таймер, который используется функциями millis/micros. Ведь delay не делает ничего иного, кроме как чтение текущего состояния системных часов через функцию micros():

void delay(unsigned long ms) {
  uint16_t start = (uint16_t)micros();
  while (ms > 0) {
    if (((uint16_t)micros() - start) >= 1000) {
      ms--;
      start += 1000;
    }
  }
}

 PS: О варианте работы функции обработки прерывания в течение миллисекунды и более даже не заикаюсь - это прямой путь к тому, чтобы угробить свою программу.

whoim
Offline
Зарегистрирован: 03.11.2011

 step962, вешалось библиотекой, поэтому хз как она там цепляется) Но было четко - убрал часть кода из процедуры по таймеру - стало работать без загонов со стороны delay в основном теле. Деталей уже не помню, так, экспериментировал. Про время работы согласен. В принципе, вывод двух десятков shiftout в своем коде и мелкие расчеты в цикле - сто раз в секунду нормально выполняются. Быстрее не пробовал, думаю не проблема тоже.

step962
Offline
Зарегистрирован: 23.05.2011

whoim пишет:

вешалось библиотекой, поэтому хз как она там цепляется)

Стандартная проблема проектов с открытым кодом. Море энтузиастов создает бесчисленные аппаратные и программные примочки, а потом, публикуя их, не утруждает себя четким описанием или хотя бы указанием на возможные побочные эффекты. А в сообществе Arduino это еще усугубляется отсутствием хоть каких-то стандартов на публикацию и совместимость (хотя бы с ядром). Обратная сторона доступности для любителей ... 

whoim
Offline
Зарегистрирован: 03.11.2011

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

Нет ли у Вас в проектах где нибудь простейшего таймера для вызова процедурки на ардуино 168/328, с примером расчета частоты?

step962
Offline
Зарегистрирован: 23.05.2011

 Тут сразу возникает вопрос - а какой диапазон частот предполагается "слушать". Вот, например, решение для области высоких частот (до 2.5 ГГц!!!). Написано, правда, на BASCOM и для несколько иного контроллера, но общими усилиями вполне можно переделать под AVR-C, а там и до Arduino-скетча недалеко.

О программировании 16-битного таймера - можно посмотреть здесь.

whoim
Offline
Зарегистрирован: 03.11.2011

 Нет, настолько дико нет нужды. 1 кгц уже устроит. Простейший таймер. Самый простейший )

Мм а как может быть частоты вызова выше частоты камня? )

whoim
Offline
Зарегистрирован: 03.11.2011

 А, аппаратно, понял. Но мне не просто ногами дрыгать, мне мелкие вычисления внутри процедурки на ардуино или си делать. То есть - программное решение.

step962
Offline
Зарегистрирован: 23.05.2011

 Перед входом микроконтроллера городим делитель частоты на микросхемах серии "74".

А по ссылкам есть и программные коды.

PS: поосновательнее смогу по теме отписаться в лучшем случае в выходные - сейчас делаю срочный перевод и сижу в форумах только в минуты отдыха (лучший из которых - смена деятельности ;))

whoim
Offline
Зарегистрирован: 03.11.2011

понял, сам срочно php колпашу. По ссылкам пробовал пару примеров - незахотели.. До выходных ) Аська если что 66945401