Всем доброго времени суток! Нужна помощь знающих людей. Делаю выносной термодатчик для системы умного дома по протоколу 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); }
1. Вам принципиально использовать аналоговый датчик? Не смотрели в сторону ds18b20? 2. Обратите внимание, что схема, приведенная Вами в ссылке, предусматривает использование 5 вольт. ESP8266 к 5 вольтам, мягко говоря, не толерантен.
Функция steinhart: Код (C++): float steinhart(float t) AnalogRead возвращает int. У Вас: Код (C++): float data = steinhart(analogRead(A0)); Нужно корректно преобразовывать типы данных. Поменяйте хотя бы на так: Код (C++): float data = steinhart( (float) analogRead(A0));
Вы бы еще вывод последовательного порта выложили бы. И куда подключен верхний резистор делителя? Идем дальше. У Вас есть строки: Код (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 используете?