18b20 не стабильно работает -127
- Войдите на сайт для отправки комментариев
Доброго времени суток коллеги. Уже не первый год воюю с датчиками 18b20. Что на esp8266 что на разных ардуинах, проблема все та же. Периодически при замере температуры датчики выдают -127. В данный момент у меня два устройства для экспериментов. ESP в качестве датчика умного дома. На ней висит два датчика на одном проводе. Питание полноценное но 3.3, что посути в норме. Подтяжка стоит 4.7к. Провод в сумме 2 метра (витая пара). Периодически, примерно раз в 10 замеров, проскакивают приславутые -127. Скетч сейчас показать не могу, но он основан на примерах библиотеки DallasTemperature. Задержки на опрос прописаны в самой библиотеке, но я сам добавляю задержку две секунды. Результата ноль. Приходится фильтровать результаты.
Второе устройство, это контроллер твердотопливного котла. В коде прописано два датчика 18b20 и одна термопара. 18b20 стоят на разных пинах. Но имею все ту же проблему. Периодически -127. Экспериментировал с разной точностью датчика, разными задержками, все без толку. Причем алгоритм таков, что контроллер термопарой меряет температуру дымохода и в зависимости от нее шимом тормозит вентилятор, чтоб не перестарался, когда тяга ещё плохая. а при перегреве вентилятор отключается при помощи реле. Так вот что я заметил. ошибки чаще выскакивают когда дымоход холодный. Хотя термопара ж к 18б20 никакого отношения не имеет. И плюс включение вентилятора тоже добавляет вероятность ошибок.
И третье, если запустить симуляцию этого кода в протеусе, там почти постоянно -127.
Вот сам код:
#include "max6675.h" #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS_1 13 #define ONE_WIRE_BUS_2 12 OneWire oneWire_in(ONE_WIRE_BUS_1); OneWire oneWire_out(ONE_WIRE_BUS_2); DallasTemperature sensor_in(&oneWire_in); DallasTemperature sensor_out(&oneWire_out); #define pump 8 #define air 2 #define fan 9 int thermoDO = 4; int thermoCS = 5; int thermoCLK = 6; int pipe; int pipemax = 105; int pipemin = 40; int waterneed = 55; int waterin; float waterout; float wateroutt; int error; int fanspeed = 0; byte fans; boolean rejim; int regulator; MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO); void setup() { lcd.init(); // Print a message to the LCD. lcd.backlight(); lcd.setCursor(3,0); lcd.print("Kotel Kontrol"); lcd.setCursor(5,1); lcd.print("V k3.0"); lcd.setCursor(3,2); lcd.print("Powered by:"); lcd.setCursor(6,3); lcd.print("Jink"); delay (2000); // use Arduino pins pinMode(pump, OUTPUT); digitalWrite(pump, HIGH); pinMode(air, OUTPUT); digitalWrite(air, HIGH); pinMode(fan, OUTPUT); analogWrite (fan, 255); // wait for MAX chip to stabilize delay(500); sensor_in.begin(); sensor_out.begin(); sensor_in.setResolution(9); sensor_out.setResolution(9); lcd.clear(); rejim = false; error = 0; } void loop() { pipe = thermocouple.readCelsius(); delay (200); if (pipe >= pipemax) { digitalWrite(air, HIGH); } if (pipe <= pipemax-10 && waterout <= waterneed-2) { digitalWrite(air, LOW); } fans = map(pipe, -10, 300, 180,50); analogWrite (fan, fans); sensor_in.requestTemperatures(); sensor_out.requestTemperatures(); waterin = sensor_in.getTempCByIndex(0); wateroutt = sensor_out.getTempCByIndex(0); if (wateroutt > -50){ waterout = wateroutt; error = 0; } else { error ++; while (error >= 180) { digitalWrite(air, HIGH); DispUpdate(); } } if (waterout >= 30 && pipe >= 50 ) { rejim = true; } if (rejim == true && pipe <= 25 && waterout <= 26 ) { while (1 ) { digitalWrite(air, HIGH); digitalWrite(pump, LOW); lcd.clear(); lcd.setCursor(0,0); lcd.print("PUSTO"); delay (10000); } } if (waterout >= waterneed+1) { digitalWrite(air, HIGH); } if (waterout <= waterneed-2 && pipe <= pipemax-20) { digitalWrite(air, LOW); } regulator = analogRead (A1); waterneed = map(regulator, 0, 1023, 35,70); DispUpdate(); //Функция обновления дисплея } void DispUpdate(void) //Функция обновления дисплея { lcd.clear(); lcd.setCursor(0,0); lcd.print("pipe "); lcd.print(pipe); lcd.setCursor(11,0); lcd.print("rejim "); lcd.print(rejim); lcd.setCursor(0,1); lcd.print("fans "); lcd.print(fans); lcd.setCursor(0,2); lcd.print("out "); lcd.print(waterout); lcd.setCursor(10,2); lcd.print("er "); lcd.print(error); lcd.setCursor(0,3); lcd.print("need"); lcd.print(waterneed); }
#define DEVICE_DISCONNECTED_C -127
Это строка из DallasTemperature.h
опрашивать датчики так, и всё будет гуд
#define DEVICE_DISCONNECTED_C -127
Это строка из DallasTemperature.h
Это то понятно. Но датчик то работает. Ошибка появляется раз из десяти замеров.
#define DEVICE_DISCONNECTED_C -127
Это строка из DallasTemperature.h
а с какой частотой ты его др.чишь?
Спасибо за код. Вечером буду у котла попробую. Только при проверке допишу, чтоб ошибки посчитало. Вот только хочется универсальности. Не хочу привязываться к конкретному датчику. Есть как то возможность как у меня привязаться к пину, с горячей заменой датчика?
Я давно делал соседу погодный регулятор для котла.
Мерял раз в 5 секунд с усреднением по десяти измерениям.
Естественно всякие случайные -127, если они были, срезались сразу.
И естественно не 12 битный режим.
Вообще особо роли не играет. Хоть раз в секунду, хоть раз в пять минут. Пробовал по всякому. Грешу всеже на библиотеку даллас темприче. Вечером попробую без нее. С ней просто удобный код получается. Да и в ней задержки по даташиту прописанны. Проверял.
есть. только даччик должен быть на проводе один. при чтении даешь команду SkipROM и читаешь свой единственный подключенный датчик. Згарел - включаешь другой такой же, программа разницы не заметит
С напряжением проблема, а виновата опять библиотека.
Я то тоже режу ошибочные. а счетчик их считает. Если было определенное количество ошибок подряд (в моем случае 90), то котел уходит в ошибку и останавливается. Такое бывает редко, но бывает. Чаще всего при холодном дымоходе. Как прогреется, то ошибки редко. Подряд проскочат максимум 4, а так 1.
при чтении даешь команду SkipROM и читаешь свой единственный подключенный датчик.
Спасибо
С напряжением проблема, а виновата опять библиотека.
Поясните пожалуйста. В чем может быть проблема с питанием. Оно полноценное а не паразитное. Провод 2 метра. Ситуация одинаковая на разных ардуинах и на ЕСП 8266. То есть, что 5 вольт, что 3,3, разницы никакой.
Перебирайте питание, провода и разъемы, проверьте нет ли влаги на лапках, чудес не бывает. ИМХО.
На задержки датчику нас-ть (кроме самого первого замера), дальше он возвращает последний результат сохраненный в регистрах.
На предмет помех, отключите цепь вентилятора и посмотрите как будет работать.
Все на пайке. Повторюсь, устройства разные пробовал. Один из них просто меряет и шлет по MQTT. Но все же на котле с выключенным вентилятором действительно ошибок меньше в разы. Появилась идея попробовать повесить кондер на питание датчика. В общем метод научного тыка в действии))). Но с другой стороны в Протеусе та же фигня. Какие там помехи то?!
Берете код для датчика, запускаете его, считаете ошибки. Если их нет, добавляете функционал, пока ошибки не начнут проявляться. Если есть сразу, то дербаните всю сеть, пока не исчезнут. Конденсатор вешаю всегда, возле самого дальнего датчика.
Рядом с большими моторами ловили проблемы на DS-ках... Наводки там по DQ были что ли...
Докладываю первые испытания. Собрал на уне тестовый стенд. Накидал скетч из примера Dallas Temperature на два пина. Повесил два датчика и LCD с I2C. В скетче прописал два счетчика ошибок. Пока полет нормальный. Никаких кондеров не вешал. Только полноценное питание датчиков и подтяжка 4,7. Кстати ради эксперимента один из датчиков питается от цифрового пина. Пока полет нормальный. Проблем нет. После обеда попытаюсь тоже самое повесить на ESP. Если все будет хорошо, то буду добавлять обвязку и код. Похоже что все таки это помехи. Хотя, надо попробовать на нано собрать. На котле именно Нано.
С ESP8266 тоже все работает. Что то интересное! Может партия датчиков нормальная? Это судя по маркировке что на котле, что тут у меня на стенде одна и та же партия.
я не пойму, в чём проблема получить адрес датчика в стандартном примере? Дело одной минуты. Вы собираетесь каждый день датчики менять? По-моему нужно один раз все настроить и забыть про эти датчики. У меня проблемы ушли полностью, когда стал применял такой код (#2). Хотя датчики подключены физически довольно коряво. сеть звездой (что нельзя по идее) 4 жильным телефонным проводом . Лучей 7 наверное, длиной метров по 10.
Это имеет смысл только при одном датчике на линии. Если их несколько, то сортируются по возрастанию адреса, что почти наверняка, при замене, приведет к несоответствию точки измерения датчику. А значит, считали, сверили с записанными в епром, если все соответствуют, продолжаем работу дальше. Если нет, считываем, прописываем вновь считанные в епром, требуем идентификации - последовательно по точкам нагреть каждый датчик и записать его признак в епром. Как-то так, для универсальности. Может проще можно, но чет не придумывается.
Написал новый скетч. Полностью пересобираю контроллер управления котлом. Пока вроде работает. На выходных поставлю на котел, посмотрим что выйдет))))
По размещению датчиков. Для меня психологически критична максимальная ремонтопригодность. Каждый датчик на своем пине. Их три. Все можно на горячую выдернуть и всунуть, и все пока что работает.