• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

DS18B20 возвращает то температуру, то -127.

И снова доброго дня.
Есть мерялка термпературы воды на крыше в бойлере.
Длиииииинный провод метров на 15, 3х0.34.
Ещё до интеграции в дом на столе показывает температуру, реагирует, потом отвалился и стал показывать -127 - то есть отключился. Потом снова включился.
Тут много спорных моментов, на которые закрыл глаза, ибо вроде работает. Длинный провод, не экранированный, в коммуникационной шахте, работает от 5 вольт (соответсвенно и возвращает как бы 5 вольт), потому что это ESP-15F - нету там ног для 3.3В, а платки есть.
В целом меня это не сильно парит, скорее чисто эстетические претензии. Но вдруг, есть более элегантное решение, чем заменять значение предыдущим стоящим например.
Или действительно где-то есть баг, который на стенде работает, а дома нет.
Код прикладываю
Код:
#include <AsyncElegantOTA.h>
#include <elegantWebpage.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <LittleFS.h>

#define WIFI_SSID "Mi MIX 2S"
#define WIFI_PASSWORD "987654321"

//#define WIFI_SSID "Gosha_SmartHome"
//#define WIFI_PASSWORD "MySmartHome"

const long utcOffsetInSeconds = 7200; // Define NTP Client to get time

WiFiEventHandler wifiConnectHandler, wifiDisconnectHandler;//, stationConnectedHandler;

const int oneWireBus = 4;    //I04// GPIO where the DS18B20 is connected to

OneWire oneWire(oneWireBus);      // Setup a oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature sensor
DeviceAddress tempDeviceAddress;

float Temp_val; // переменная температуы
byte addr[8];
byte flagDallRead;
byte data[12]; //для температуры
int  resolution = 10;
unsigned long lastTempRequest = 0;
int  delayInMillis = 0;
float temperature = 0.0;
int  idle = 0;

unsigned long previousMillis = 0;        // will store last time LED was updated
unsigned long previous_timer = 0;         //Timer_delay_storage

uint32_t currentTime, loopTime, previous_serial, prevTime_temp, start_Time;

float temperature_C;

String temperatureC_string = "";
unsigned long currentMillis;


AsyncWebServer server(80);
//-----------------------------------------------------------------------
//// Replaces placeholder with button section in your web page
String processor(const String& var){
   if(var == "TEMPERATUREC"){     // Replaces placeholder with DS18B20 values
    return temperatureC_string;
  }
    return String();
}
void WIFI_connect()
{
  WiFi.mode(WIFI_STA);
  wifi_station_set_hostname("Boiler_temp");
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.println("Connecting to AP");
}

void onWifiConnect(const WiFiEventStationModeGotIP& event) {
  Serial.println("Connected to Wi-Fi sucessfully.");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.print("RRSI: ");    Serial.println(WiFi.RSSI());
  Serial.print("Hostname - "); Serial.println(WiFi.hostname());
}

void onWifiDisconnect(const WiFiEventStationModeDisconnected& event) {
  Serial.println("Disconnected from Wi-Fi");
  WiFi.printDiag(Serial);
}

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////

float temperature_measure()
{
  if (millis() - lastTempRequest >= delayInMillis) // waited long enough??
  {
    temperature = sensors.getTempCByIndex(0);
    sensors.setResolution(tempDeviceAddress, resolution);
    sensors.requestTemperatures();
    delayInMillis = 750 / (1 << (12 - resolution));
    lastTempRequest = millis();
    return temperature;
  }
  return temperature;
}
//String readDSTemperatureC() {
//    if(temperature_C == -127.00) {
//    Serial.println("Failed to read from DS18B20 sensor");
//    return "--";
//  } else {
//    Serial.print("Temperature Celsius: ");
//    Serial.println(temperature_C);
//  }
//  return String(temperature_C);
//}
void setup() {
  Serial.begin(74880);  //115200 Start the Serial Monitor
  delay (100);
  Serial.println("I`m alive");
 if (!LittleFS.begin()) {
    Serial.println("An Error has occurred while mounting LittleFS");
    return;
  } 
  sensors.begin();                                        // Start the DS18B20 sensor
  sensors.getAddress(tempDeviceAddress, 0);
  sensors.setResolution(tempDeviceAddress, resolution);
  sensors.setWaitForConversion(false);
  sensors.requestTemperatures();
  delayInMillis = 750 / (1 << (12 - resolution));
  lastTempRequest = millis();

  WIFI_connect();
  AsyncElegantOTA.begin(&server);                     //start OTA server
 
  wifiConnectHandler = WiFi.onStationModeGotIP(onWifiConnect);
  wifiDisconnectHandler = WiFi.onStationModeDisconnected(onWifiDisconnect);

  //--------------------  server addition   -----------------------------
  // Route for root / web page
 server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {        // send index_html page to client
    request->send(LittleFS, "/index.html", String(), false, processor);
    });
  server.on("/temperature_C", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send_P(200, "text/plain", temperatureC_string.c_str());
  });
 
  server.onNotFound(notFound);
  // Start server
  server.begin();

}
void loop() {
  currentMillis = millis();
  temperature_C =  temperature_measure();
  //  temperatureC_string = readDSTemperatureC();
  temperatureC_string =  String(temperature_C);

}
 

aZholtikov

Active member
Вставлю свои "5 копеек". По моему опыту DS18B20 работает от 3.3 вольта прекрасно. Правда не далее чем 3 метра провода при питании от ESP.
Несколько лет назад были попытки замерить температуру воды в скважине 42 метра (от нечего делать...). Датчик с тремя AA (все залито силиконом). Наружу GND и DATA до ESP. Ну вообщем показало... :) Но это была "разовая акция". :)
 

pvvx

Активный участник сообщества
Вставлю свои "5 копеек". По моему опыту DS18B20 работает от 3.3 вольта прекрасно. Правда не далее чем 3 метра провода при питании от ESP.
Несколько лет назад были попытки замерить температуру воды в скважине 42 метра (от нечего делать...). Датчик с тремя AA (все залито силиконом). Наружу GND и DATA до ESP. Ну вообщем показало... :) Но это была "разовая акция". :)
А температуру воды от насоса скважины на поверхности было не померять? Прям она так меняется при откачке :)
 

pvvx

Активный участник сообщества
и какая температура на глубине 42 метра?
По воздуху на моем участке (север Ленобласти):
weather.gif


Расчет средней температуры воздуха вперед на год от указанной на шкале даты:

1679099441677.png
Вот такая вода и течет со скважины в -5 метров, а далее зависит от грунта и на -50 метров в пределе на градус теплее...
Т.к. "скважина" самоистекающая до +10 см от поверхности, то путем малой докачки можно греть зимой подпол, а летом использовать как кондиционер :p
 

pvvx

Активный участник сообщества
Вот тут неправильно.
Резистор подтяжки где стоит?
Почитайте что такое схема с открытым коллектором.
Чтобы хотя-бы частично убрать выбросы кабеля необходимы сопротивления ниже "волнового сопротивления среды" на обоих концах. А это близко к 376.73 Ом для волнового сопротивления вакуума.
В итоге это общая нагрузка около 188 Ом на выходы чипов. И при 5 В это 27 мА.
 

pvvx

Активный участник сообщества
А для полного согласования кабеля требуются сопротивления ещё ниже. В итоге советы припаять на другой конец резистор не катят. Для этого люди давно используют токовую петлю, у которой размахи по напряжению значительно ниже 5 В и сопротивления терминаторов тоже ниже :p
Или для ардуинщиков другие физические законы?
 

pvvx

Активный участник сообщества
@CodeNameHawk И т.к. даже у UTP Cat.5 волновое 100 Ом, что означает терминаторы по 100 Ом с обоих концов и нагрузка для постоянного тока от 50 Ом, то вразумительных и советов TC никаких не дать, кроме как менять всю схему, или систему, или датчики...
 

pvvx

Активный участник сообщества
Возможно попробовать как-то работать DS18B20 на кабель более 3-х метров (этого нет в его документации) c помощью DS2480B, установив в нем "flexible speed" для регулирования токов нарастания поменьше, чтобы ограничить всякие выбросы и искажения на кабеле...
DS18B20 имеет транзистор, в открытом состоянии с сопротивлением 100 Ом и рекомендуемую подтяжку в 4.7 кОм.
1679126769874.png
 

CodeNameHawk

Moderator
Команда форума
Тут все намного проще, резистор разместить возле самой есп, чем ближе тем лучше.
И конечно не на +5 в а к +3.3 в.
У меня на есп подключены 6 таких датчиков, работают очень стабильно, правда резистор уменьшил до 1ком, с 4.7 ком были сильно завалены фронты импульсов.
 

pvvx

Активный участник сообщества
У меня на есп подключены 6 таких датчиков, работают очень стабильно, правда резистор уменьшил до 1ком, с 4.7 ком были сильно завалены фронты импульсов.
Т.е. датчики теперь показывают свой нагрев от работы на шине с 1 кОм (на внутреннем сопротивлении MOSFET в 100 Ом при передаче "0" бита), а не окружающую температуру?
ИФК от этого транзистора достаточно хорошо влияет на показания...
 

pvvx

Активный участник сообщества
Чтобы DS18B20 мог выполнять точное преобразование температуры, необходимо обеспечить достаточную мощность по линии DQ, когда происходит преобразование температуры. Поскольку рабочий ток DS18B20 составляет до 1,5 мА, линия DQ не будет иметь достаточного напряжения из-за подтягивающего резистора 5 кОм. Эта проблема особенно актуальна, если несколько DS18B20 подключены к одному и тому же DQ и пытаются выполнить преобразование одновременно.
Есть два способа убедиться, что DS18B20 имеет достаточный ток питания во время активного цикла преобразования. Во-первых, обеспечить сильную подтяжку на линии DQ всякий раз, когда происходят температурные преобразования или копирование в E2-память. Этого можно добиться, используя полевой МОП-транзистор, чтобы подтянуть линию DQ непосредственно к источнику питания, как показано на рис. 2. Линия DQ должна быть переключена на сильную подтяжку максимум в течение 10 мкс после выдачи любого протокола, который включает копирование в E2. память или инициирует преобразование температуры. При использовании режима паразитного питания вывод VDD должен быть заземлен.

1679144190749.png
Т.е. на время передач по шине ключ должен быть выключен.
А второй способ - внешнее питание датчика, а не от шины.
В итоге во всех вариантах PDF нет указаний, что резистор подтяжки может быть менее 4.7 кОм.
В PDF от DALLAS указано - подтягивающий резистор около 5 кОм при 3.3..5 В, независимо от кол-ва датчиков на шине.
 

CodeNameHawk

Moderator
Команда форума
от этого транзистора достаточно хорошо влияет на показания...
Насколько хорошо?
Выйдет за предел точности датчика?
Во время измерения нет передачи данных - нет нагрева транзистора, следующий опрос только через три секунды, датчик остынет.
Запустите измерения двух датчиков с разными подтяжками и покажите результаты, слов много а дел ноль.
 

pvvx

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

pvvx

Активный участник сообщества
DS18B20 - это не термометр, а так, дурной древний чип для Ардуинщиков.

Для корпусов TO-92 транзисторов указывают 312C/W и обычно сноска - * при монтаже на печатную плату.
Другие даташиты на TO-92 указывают - 3mW/С, что совпадает.

Измерение 12 бит на DS18B20 идет: Temperature Conversion Time - 750 ms.
Даташиты указывают потребляемый при этом ток до 1.5 мА
5В*1.5мА = 7.5 mW
Т.е. в момент измерения, почти секунду температура кристалла поднимается на +2.5 С.
Далее даже считать лень.
 

pvvx

Активный участник сообщества
@CodeNameHawk что ещё интересует по данному датчику?
Он СMOS, что означает низкие частоты и большие емкости в кристалле. Т.е. не терпит прямого подключения к выводам ESP, у которых фронт переключения менее 3 нс с учетом внешней емкости вывода DS18B20.
Т.е. запросто запудрид ему мозги в нутре...
Включать без последовательного резистора от ESP на шину 1-wire не рекомендуется. Особенно если линия с длинным проводом.
 

CodeNameHawk

Moderator
Команда форума
Можно и питание не по документации пустить. Это тоже проверять?
Приятно, когда собеседник отвечает сразу по существу вопроса.
Всю энергию в тело, на работу ни грамма.
Т.е. в момент измерения, почти секунду температура кристалла поднимается на +2.5 С.
Кто сказал, почему вы ему верите?
И даже если это так, а пусть даже греется на 5 градусов(выдумывать то не сложно), то производитель не дурак и это учитывает, калибровка это называется.
 
Сверху Снизу