ESP8266 с термодатчиком NTC3950

Тема в разделе "ESP8266, ESP32", создана пользователем Илья Мирошниченко, 13 дек 2019.

  1. Всем доброго времени суток!
    Нужна помощь знающих людей.
    Делаю выносной термодатчик для системы умного дома по протоколу MQTT. Сам протокол освоил, данные на сервер OpenHAB поступают, в консоли отображаются. Но есть проблема с самими значениями.
    На ESP8266-12 пытаюсь подключить аналоговый терморезистор NTC3950 100кОм. Схема подключения - отсюда. Номинал последовательного резистора 276кОм (в коде указал). Далее, по модифицированному B-уравнению Стейнхарта-Харта вычисляю из сопротивления температуру. Но вместо комнатной температуры получаю отрицательные, около -17 градусов (колеблется, т.е. датчик работает, esp значения получает). Если датчик нагреваю (зажимаю пальцами) - температура повышается до околонулевой.
    Похоже, что для ESP используются другие коэффициенты, либо алгоритм. Кто может подсказать?
    Код (C++):
    /*
    Basic MQTT example
      - connects to an MQTT server
      - publishes "hello world" to the topic "outTopic"
      - subscribes to the topic "inTopic"
    */


    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>

    #define B 3950 // B-коэффициент
    #define SERIAL_R 276000 // сопротивление последовательного резистора, 123 кОм
    #define THERMISTOR_R 100000 // номинальное сопротивления термистора, 100 кОм
    #define NOMINAL_T 25 // номинальная температура (при которой TR = 100 кОм)

    const char* ssid = "mywifi";
    const char* pass = "12345678";

    // Update these with values suitable for your network.
    IPAddress server(192, 168, 0, 104);

    void callback(const MQTT::Publish& pub) {
      // handle message arrived
    }

    WiFiClient wclient;
    PubSubClient client(wclient, server);

    void setup() {
      // Setup console
      Serial.begin(115200);
      delay(10);
      Serial.println();
      Serial.println();

      pinMode(A0, INPUT);

      client.set_callback(callback);
    }

    void loop() {
      if (WiFi.status() != WL_CONNECTED) {
        Serial.print("Connecting to ");
        Serial.print(ssid);
        Serial.println("...");
        WiFi.begin(ssid, pass);

        if (WiFi.waitForConnectResult() != WL_CONNECTED)
          return;
        Serial.println("WiFi connected");
      }

      if (WiFi.status() == WL_CONNECTED) {
        if (!client.connected()) {
          if (client.connect("arduinoClient")) {
            gogogo();
      //client.subscribe("inTopic");
          }
        }

        if (client.connected())
          gogogo();
          delay(500);
          client.loop();
      }
    }

    float steinhart(float t) {
      Serial.print("in=");
      Serial.print(t);
      float steinhart;
      float tr = 1023.0 / t - 1;
      tr = SERIAL_R / tr;
      Serial.print(", R=");
      Serial.print(tr);
      Serial.print(", t=");
      steinhart = tr / THERMISTOR_R; // (R/Ro)
      steinhart = log(steinhart); // ln(R/Ro)
      steinhart /= B; // 1/B * ln(R/Ro)
      steinhart += 1.0 / (NOMINAL_T + 273.15); // + (1/To)
      steinhart = 1.0 / steinhart; // Invert
      steinhart -= 273.15;
      steinhart += 45;
      return steinhart;
    }

    void gogogo () {
      float data = steinhart(analogRead(A0));
      client.publish("/ESPThermo/temp/Analog",(String)data);
      Serial.println((String)data);
    }
     
  2. alp69

    alp69 Форумчанин

    1. Вам принципиально использовать аналоговый датчик? Не смотрели в сторону ds18b20?
    2. Обратите внимание, что схема, приведенная Вами в ссылке, предусматривает использование 5 вольт. ESP8266 к 5 вольтам, мягко говоря, не толерантен.
     
  3. asam

    asam Гик

    Подключите делитель к 3.3В вольтам и будет счастие.
     
  4. SergeiL

    SergeiL Оракул Модератор

    Функция steinhart:
    Код (C++):
    float steinhart(float t)
     
    AnalogRead возвращает int. У Вас:
    Код (C++):
      float data = steinhart(analogRead(A0));
    Нужно корректно преобразовывать типы данных.
    Поменяйте хотя бы на так:
    Код (C++):
      float data = steinhart( (float) analogRead(A0));
     
  5. SergeiL

    SergeiL Оракул Модератор

    Вы бы еще вывод последовательного порта выложили бы.
    И куда подключен верхний резистор делителя?

    Идем дальше.
    У Вас есть строки:
    Код (C++):
    float steinhart(float t) {
      Serial.print("in=");
      Serial.print(t);
      float steinhart;
      float tr = 1023.0 / t - 1;
      tr = SERIAL_R / tr;
      Serial.print(", R=");
      Serial.print(tr);
     
    Вы понимаете, что тут делается?
    Даю подсказку: АЦП на ESP8266 работает в диапазоне 0.0В - 1.0В

    UPD: Часть модулей (NODEMCU LoLin v3) идет с делителем повышающим диапазон 0.0В - 3.3В
    Поэтому вопрос: Какой модуль ESP используете?
     
    Последнее редактирование: 13 дек 2019