Любопытный случай смерти ds18b20 случился сегодня.
Имеется новое устройство на esp8266. К нему, на GPIO2, подключено 2 (в перспективе 3) датчика ds18b20 и вентилятор. Логика работы: опрашиваем датчики (по 2 сек на каждый), если разность температур датчиков превышает 1 градус вкл. вентилятор. Откл. вентилятора если разность температур стала менее нуля. Все это под системой логирования и с веб- интерфейсом. Ранее отработало дней 5 на отладке с одним датчиком. Вчера запустил с двумя в боевых условиях, и вот утром вижу.
Лог циклический, инфы ранее 8:28 нет. Данные за 7:00 вроде корректны, за 8:00 бредятина, датчики на балконе. Судя по логу вентилятор периодически включался и отключался, похоже показания скакали. При осмотре выяснилось что новый датчик коротит линию. Проработав правильно всю ночь до 7:00. Его закоротка выглядит для системы как корректный 0 градусов по всем датчикам. Это видно в таблице в 9:00. Код в студию:
void StartConvertDS18b20(AdrDS18b20 addr)
{
ds.reset();
ds.select(addr); // обращаемся по адресу
ds.write(0x44, 1); //Команда на конвертацию 1 -паразитное питание
}
bool GetConvertDS18b20(AdrDS18b20 addr, int16_t* Val)
{
ds.reset()
ds.select(addr); // обращаемся по адресу
ds.write(0xBE, 1); // чтение из памяти
for (int i = 0; i < 9; i++) {
data[i] = ds.read ();
}
ds.reset_search();
*Val = ((data[1] << 8) | data[0]);//=======Пересчитываем в температуру
return ds.crc8(data, 8)==data[8];
}
Ниче необычного, контроль CRC присутствует но проблему не выявляет. Повторюсь, между StartConvertDS18b20 и GetConvertDS18b20 аж 2 секунды, я не спешу.
Оперативно дорабатываю
bool GetConvertDS18b20(AdrDS18b20 addr, int16_t* Val)
{
if(!ds.reset())
return false;
ds.select(addr); // обращаемся по адресу
ds.write(0xBE, 1); // чтение из памяти
.......
Теперь хоть не выдает ложные нули.
Отключаю проблемный датчик - работает корректно.
Отсюда вывод - в примерах кода по теме необходимо добавить проверку ds.reset().
Ну а датчик - похоже совсем сдох.
Но как могли получится температуры 65,5С по исправному датчику - загадка. И как с таким боротся?
М.б. 65535 было в результате вычислений преобразовано в 65.5?
хммм.... Это мысль интересная, восстановить по 65,5 что с шины приехало.. Получается 0х0418 вроде... это в десятичной 1048*0,0625=65,5 Не полегчало (((
Не, не вопреки. Это пересчет из буфера в родной формат ds18b20. Цена младшего разряда 0,0625С. Он собственно везде и использован кроме вывода в html. В строку конвертится так.
Она интересна только в плане оценки динамики, сразу видно греемся или охлаждаемся. Смотри, сразу видно что греемся последние 2 часа. А без дробной - не видно
Это время через сеть по SNTP берется. После ресета его сразу нет, значене 0 что для юникстайма есть 0:0:0 1-1-1970. Ну и +2часа для часового пояса. Оно при логировании в первую строку идет. Эта строка собственно - поправка dTim1601457723 к времени чтоб получить текущее 30-09-2020 11:00:00. С точностью до часа, а минуты в 0. Это чтоб отработали действия которые обычно при смене часа. А дальше уже вторая поправка dTim1333 и время точное становится. Весь лог
01-01-1970 02:00:09 dTim1601457723
30-09-2020 11:00:00 Температура: Внутри=17.2С
30-09-2020 11:00:04 dTim1333
30-09-2020 11:34:34 New Client.
30-09-2020 11:34:34 Client disconnected.
30-09-2020 11:34:34
30-09-2020 11:34:37 New Client.
30-09-2020 12:00:00 Температура: Внутри=17.5С
30-09-2020 12:33:52 New Client.
30-09-2020 12:33:52 Client disconnected.
30-09-2020 12:33:52
30-09-2020 12:33:52 New Client.
30-09-2020 13:00:00 Температура: Внутри=17.5С
30-09-2020 13:24:04 New Client.
30-09-2020 13:24:04 Client disconnected.
30-09-2020 13:24:04
30-09-2020 13:24:04 New Client.
Кстати кварц esp8266 порадовал. Корректирую каждые 20мин по SNTP и ни разу более 1сек коррекция не обнаружилась.
Logik, ну я изо всех сил надеялся, что ты понимаешь, что я пашутил. )))
Так я ж и посмеялся сразу. А затем разъяснил извращения алгоритма, они не очень очевидны. Правда еще момент забыл указать. SNTP не хочет стабильно в фоне работать. Точней она вроде как работает, а вебсервер уже через раз. Потому я ее раз в 20 минут запускаю, жду 9 секунд, получаю время, а после стоплю. Так нормас вроде. Может конечно нормас, пока не попаду на этот процесс ))
Ну,по крайней мере, ты теперь понимаешь, что не все так просто с далласами. А то ты мне ж не верил, что мои, из одной партии, после -38 прекращают работать праильно . При корректнейшей некуда CRC.
Так то ж совсем другое. У тя на экстремальной температуре и датчик сам себе только СRC считал. Думаю ему питалова не хватало.
Посмотрел CRC, по буферу из всех нулей дает 0.
там реализация
static const uint8_t PROGMEM dscrc_table[] = {
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
//
// Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM
// and the registers. (note: this might better be done without to
// table, it would probably be smaller and certainly fast enough
// compared to all those delayMicrosecond() calls. But I got
// confused, so I use this table from the examples.)
//
uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len)
{
uint8_t crc = 0;
while (len--) {
crc = pgm_read_byte(dscrc_table + (crc ^ *addr++));
}
return crc;
}
Так что не удивительно, что CRC сошлось на закороченной линии. Удивительно другое CRC верно при "температуре" 65,5С. Это ж явно не ноль, причем значение с исправного датчика. Выходит один датчик линию коротил, а это дало два эффекта: 1. Температуру 0 по всем датчикам что не ловит СRC. Зато это ловит проверка ds.reset() которой как правило нет в примерах. Решаемо в общем, но нужно делать. 2. Температура заведомо неверная с неисправного и с исправного датчиков при верном CRC. Вот это не понятно, и не ясно как бороться.
давно пользую этот код на ардуино, отлично работает, а тут нужда появилась использовать его на ESP32, помогите поправить код, пожалуйста !
А это ничего, что у ESP32 и Arduino с прерываниями всё совсем неодинаково? Возьмите обычный скетч из примеров. А вообще их здесь куча разных летало, при чём в этой же теме.
А это ничего, что у ESP32 и Arduino с прерываниями всё совсем неодинаково? Возьмите обычный скетч из примеров. А вообще их здесь куча разных летало, при чём в этой же теме.
ну извините что не оправдал ваших надежд, не на столько я силен в программировании.. третий день ищу код без задержек для esp32, найти не смог ((( все что попадается, или с delay или не работает, если подскажите где есть такое, буду премного благодарен !
или, если поможете, без словоблудия, готов отблагодарить материально.
А это ничего, что у ESP32 и Arduino с прерываниями всё совсем неодинаково? Возьмите обычный скетч из примеров. А вообще их здесь куча разных летало, при чём в этой же теме.
ну извините что не оправдал ваших надежд, не на столько я силен в программировании.. третий день ищу код без задержек для esp32, найти не смог ((( все что попадается, или с delay или не работает, если подскажите где есть такое, буду премного благодарен !
или, если поможете, без словоблудия, готов отблагодарить материально.
Вы тему-то прочитайте. ЭТУ. Там есть примеры неблокирующих функций опроса датчиков. Без использования таймеров.
AlexZR, просто все содержание ISR из своего фрагмента поместите в фунцию... dsPoll(), например. Потом возьмите "blink без delay" и вместо мигания светодиодом вызывайте dsPoll().
Можно, конечно, на ESP-шный таймер подвесится, но если остальное написано без делеев получасовых, то и этот простой способ будет неплохо работать.
Только OneWire обновить надо, старые релизы с ESP-шками не совместимы.
просто все содержание ISR из своего фрагмента поместите в фунцию... dsPoll(), например. Потом возьмите "blink без delay" и вместо мигания светодиодом вызывайте dsPoll().
спасибо! я вас понял, а вот с этим что делать ?
void setup(void) {
Serial.begin(57600);
WDTCSR = (1 << WDCE) | (1 << WDE); //установить биты WDCE WDE (что б разрешить запись в другие биты
WDTCSR = (1 << WDIE) | (1 << WDP2) | (1 << WDP1); // разрешение прерывания + выдержка 1 секунда
}
Вызывайте эту функцию любым таймером, хоть на миллис, раз в секунду. При первом вызове будет подаваться команда на микросхему, при втором - считываться температура, которая помещается в глобальную переменную temperature, из которой ее можно взять в любой момент
void getTemperature()
{
static bool flagDall = true; // Признак операции
if (flagDall)
{
ds.reset();
ds.write(0xCC); // Обращение ко всем датчикам
ds.write(0x44); // Команда на конвертацию
}
else
{
int temp;
ds.reset();
ds.select(addr);
ds.write(0xBE); // Считывание значения с датчика
temp = (ds.read() | ds.read() << 8); // Принимаем два байта температуры
temperature = round((float)temp / 16.0);
}
flagDall = !flagDall; // Инверсия признака операции для следующей итерации
}
Матьтваю, тебе лень открыть и почитать даташит? Дело 1 минуты. Ты вопрос свой по клавишам долбишь дольше, чем можно прочитать в оф. документации. Задумайся уже.
Любопытный случай смерти ds18b20 случился сегодня.
Имеется новое устройство на esp8266. К нему, на GPIO2, подключено 2 (в перспективе 3) датчика ds18b20 и вентилятор. Логика работы: опрашиваем датчики (по 2 сек на каждый), если разность температур датчиков превышает 1 градус вкл. вентилятор. Откл. вентилятора если разность температур стала менее нуля. Все это под системой логирования и с веб- интерфейсом. Ранее отработало дней 5 на отладке с одним датчиком. Вчера запустил с двумя в боевых условиях, и вот утром вижу.
Лог циклический, инфы ранее 8:28 нет. Данные за 7:00 вроде корректны, за 8:00 бредятина, датчики на балконе. Судя по логу вентилятор периодически включался и отключался, похоже показания скакали. При осмотре выяснилось что новый датчик коротит линию. Проработав правильно всю ночь до 7:00. Его закоротка выглядит для системы как корректный 0 градусов по всем датчикам. Это видно в таблице в 9:00. Код в студию:
Ниче необычного, контроль CRC присутствует но проблему не выявляет. Повторюсь, между StartConvertDS18b20 и GetConvertDS18b20 аж 2 секунды, я не спешу.
Оперативно дорабатываю
Теперь хоть не выдает ложные нули.
Отключаю проблемный датчик - работает корректно.
Отсюда вывод - в примерах кода по теме необходимо добавить проверку ds.reset().
Ну а датчик - похоже совсем сдох.
Но как могли получится температуры 65,5С по исправному датчику - загадка. И как с таким боротся?
М.б. 65535 было в результате вычислений преобразовано в 65.5?
М.б. 65535 было в результате вычислений преобразовано в 65.5?
хммм.... Это мысль интересная, восстановить по 65,5 что с шины приехало.. Получается 0х0418 вроде... это в десятичной 1048*0,0625=65,5 Не полегчало (((
Похоже, что сюда приехали FF FF из шины.
*Val = ((data[1] << 8) | data[0]);
//=======Пересчитываем в температуру
Или температура не здесь пересчитывается, вопреки комментарию?
Не, не вопреки. Это пересчет из буфера в родной формат ds18b20. Цена младшего разряда 0,0625С. Он собственно везде и использован кроме вывода в html. В строку конвертится так.
Если бы приехало 0xffff то имели бы 65535*0,0625=.. что не похоже
не знаю как нарот, а я вапще 4 дробных бита отбрасываю, присваивая результат сразу к int8_t. Дробная часть температуры мне нах не нужна.
int8_t temp = (FDallasMemory[1] << 4) | (FDallasMemory[0] >> 4);
Она интересна только в плане оценки динамики, сразу видно греемся или охлаждаемся. Смотри, сразу видно что греемся последние 2 часа. А без дробной - не видно
01-01-1970 02:00:09 dTim1601457723
30-09-2020 11:00:00 Температура: Внутри=17.2С
01-01-1970 02:00:09 dTim1601457723
30-09-2020 11:00:00 Температура: Внутри=17.2С
Нихрена чота не 2 часа разница :)
Чесно говоря, мне что -34.5 С, что просто -34 С - один дубак. хоть и греемся типа :)
)))
Это время через сеть по SNTP берется. После ресета его сразу нет, значене 0 что для юникстайма есть 0:0:0 1-1-1970. Ну и +2часа для часового пояса. Оно при логировании в первую строку идет. Эта строка собственно - поправка dTim1601457723 к времени чтоб получить текущее 30-09-2020 11:00:00. С точностью до часа, а минуты в 0. Это чтоб отработали действия которые обычно при смене часа. А дальше уже вторая поправка dTim1333 и время точное становится. Весь лог
01-01-1970 02:00:09 dTim1601457723
30-09-2020 11:00:00 Температура: Внутри=17.2С
30-09-2020 11:00:04 dTim1333
30-09-2020 11:34:34 New Client.
30-09-2020 11:34:34 Client disconnected.
30-09-2020 11:34:34
30-09-2020 11:34:37 New Client.
30-09-2020 12:00:00 Температура: Внутри=17.5С
30-09-2020 12:33:52 New Client.
30-09-2020 12:33:52 Client disconnected.
30-09-2020 12:33:52
30-09-2020 12:33:52 New Client.
30-09-2020 13:00:00 Температура: Внутри=17.5С
30-09-2020 13:24:04 New Client.
30-09-2020 13:24:04 Client disconnected.
30-09-2020 13:24:04
30-09-2020 13:24:04 New Client.
Кстати кварц esp8266 порадовал. Корректирую каждые 20мин по SNTP и ни разу более 1сек коррекция не обнаружилась.
Logik, ну я изо всех сил надеялся, что ты понимаешь, что я пашутил. )))
Logik, ну я изо всех сил надеялся, что ты понимаешь, что я пашутил. )))
Так я ж и посмеялся сразу. А затем разъяснил извращения алгоритма, они не очень очевидны. Правда еще момент забыл указать. SNTP не хочет стабильно в фоне работать. Точней она вроде как работает, а вебсервер уже через раз. Потому я ее раз в 20 минут запускаю, жду 9 секунд, получаю время, а после стоплю. Так нормас вроде. Может конечно нормас, пока не попаду на этот процесс ))
Поменял датчика, работает.
01-01-1970 02:00:09 New Client.
01-01-1970 02:00:09 HTTP cmd: GET /4/aut
01-01-1970 02:00:09 Client disconnected.
01-01-1970 02:00:09
01-01-1970 02:00:09 dTim1601472611
30-09-2020 15:00:00 Температура: Внутри=15.8С
Но собственно выпал с поля зрения мысль о важности контроля результата ds.reset(). Чтоб отлавливать такие баги.
Ну,по крайней мере, ты теперь понимаешь, что не все так просто с далласами. А то ты мне ж не верил, что мои, из одной партии, после -38 прекращают работать праильно . При корректнейшей некуда CRC.
Так то ж совсем другое. У тя на экстремальной температуре и датчик сам себе только СRC считал. Думаю ему питалова не хватало.
Посмотрел CRC, по буферу из всех нулей дает 0.
там реализация
Так что не удивительно, что CRC сошлось на закороченной линии. Удивительно другое CRC верно при "температуре" 65,5С. Это ж явно не ноль, причем значение с исправного датчика. Выходит один датчик линию коротил, а это дало два эффекта: 1. Температуру 0 по всем датчикам что не ловит СRC. Зато это ловит проверка ds.reset() которой как правило нет в примерах. Решаемо в общем, но нужно делать. 2. Температура заведомо неверная с неисправного и с исправного датчиков при верном CRC. Вот это не понятно, и не ясно как бороться.
Я у себя после чтения скрэчпада проверяю весь пакет - если сплошняком нули, то сигнализирую ошибку. А вот второй вариант - выглядит мистикой.
Весело тут у вас
Статейка по фейковые DS18B20 «Почти все» датчики DS18B20, приобретенные не у официальных дистрибьюторов, являются подделками, клонами
+ там же в статье есть скетч для проверки.
давно пользую этот код на ардуино, отлично работает, а тут нужда появилась использовать его на ESP32, помогите поправить код, пожалуйста !
давно пользую этот код на ардуино, отлично работает, а тут нужда появилась использовать его на ESP32, помогите поправить код, пожалуйста !
А это ничего, что у ESP32 и Arduino с прерываниями всё совсем неодинаково? Возьмите обычный скетч из примеров. А вообще их здесь куча разных летало, при чём в этой же теме.
ну извините что не оправдал ваших надежд, не на столько я силен в программировании.. третий день ищу код без задержек для esp32, найти не смог ((( все что попадается, или с delay или не работает, если подскажите где есть такое, буду премного благодарен !
или, если поможете, без словоблудия, готов отблагодарить материально.
вот три датчика на esp обрабатываются, проблем нет )))
код нужен для одного датчика, опрос 1-2 раза в секунду, главное условие, без тормозов для остального кода...
А это ничего, что у ESP32 и Arduino с прерываниями всё совсем неодинаково? Возьмите обычный скетч из примеров. А вообще их здесь куча разных летало, при чём в этой же теме.
ну извините что не оправдал ваших надежд, не на столько я силен в программировании.. третий день ищу код без задержек для esp32, найти не смог ((( все что попадается, или с delay или не работает, если подскажите где есть такое, буду премного благодарен !
или, если поможете, без словоблудия, готов отблагодарить материально.
код нужен для одного датчика, опрос 1-2 раза в секунду, главное условие, без тормозов для остального кода...
существует 99 способов, к примеру паразитируя на ШИМ, устроит? (один пин займу)
помех приему от такого способа подключения нет ? при использования ШИМ на ардуино, от помех мне избавиться до конца не удалось (((
помех приему от такого способа подключения нет ? при использования ШИМ на ардуино, от помех мне избавиться до конца не удалось (((
можно проверить, подключением к точке по WIFI и сбрасывая показания датчика в базу к примеру
ладно, буду курить тему дальше...
ладно, буду курить тему дальше...
да что там курить, даже простейший таймер на миллисе решает эту проблему, вачдог всё таки ценный ресурс однако
лишний раз убеждаюсь в мудрости русских пословиц, "хочешь сделать хорошо - сделай сам" )))
эх.. если бы я еще знал, что такое "вачдог" )))
ушел на западные форумы, там точно помогут !
AlexZR, просто все содержание ISR из своего фрагмента поместите в фунцию... dsPoll(), например. Потом возьмите "blink без delay" и вместо мигания светодиодом вызывайте dsPoll().
Можно, конечно, на ESP-шный таймер подвесится, но если остальное написано без делеев получасовых, то и этот простой способ будет неплохо работать.
Только OneWire обновить надо, старые релизы с ESP-шками не совместимы.
спасибо! я вас понял, а вот с этим что делать ?
лишний раз убеждаюсь в мудрости русских пословиц, "хочешь сделать хорошо - сделай сам" )))
эх.. если бы я еще знал, что такое "вачдог" )))
ушел на западные форумы, там точно помогут !
так сделано уже - функция в строках с 16 до 30, а по какому таймеру ее вызывать без разницы
Вызывайте эту функцию любым таймером, хоть на миллис, раз в секунду. При первом вызове будет подаваться команда на микросхему, при втором - считываться температура, которая помещается в глобальную переменную temperature, из которой ее можно взять в любой момент
И никаких блокировок
Да ничего не делать, выкинуть весь вачдог авр-овский.
вот теперь мне все более менее стало ясно ))) я благодарен всем за уделенное время и помощь!
не подскажите где скачать правильную, а то я с ними уже запутался (((
Да можно в менеджере библиотек обновить, думаю.
https://github.com/PaulStoffregen/OneWire/blob/master/util/OneWire_direc... - если в этом файле ESP32 упоминается, то все ок.
благодарю! буду пробовать..
лишний раз убеждаюсь в мудрости русских пословиц
А что, были сомнения?
ушел на западные форумы, там точно помогут !
Заграница - она, конечно, поможет. Только вот русские пословицы что говорят?
сделал так, поправьте если что..
если с точностью до градуса устраивает, то почему бы и нет )))
да, устраивает, еще вопрос, есть смысл отказаться от float ?
еще вопрос, как правильно запитать ds18b20, 3.3 вольта или 5 вольт ?
еще вопрос, как правильно запитать ds18b20, 3.3 вольта или 5 вольт ?
Зачем задавать вопросы, ответы на которые Вам и так известны? В даташите что написано?
залил прошивку, все равно, что то не так (((
да, устраивает, еще вопрос, есть смысл отказаться от float ?
Как я уже писал, вот мне, например, глубоко по-барабану, скока сейчас на улице, -27 или -27.2 °С Тяпнуть для сугреву хочется одинаково.
все знают только дураки...
все знают только дураки...
Нет. Всё знают только васерманы. Дураки не умеют читать и не хотят учицца.
так научите, подскажите, откуда столько негатива, понимаю, жизнь не удалась, но не настолько же...
Матьтваю, тебе лень открыть и почитать даташит? Дело 1 минуты. Ты вопрос свой по клавишам долбишь дольше, чем можно прочитать в оф. документации. Задумайся уже.