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

Вопрос Не работают пара датчиков ds18b20

CoolS2

New member
Решил сделать устройство, которое будет собирать некую информацию с котла, а точнее уровень гранул через датчик SR-04 (который работает от 3.3в). Температуру бойлера и температуру котла с помощью датчиков ds18b20, которые на проводе. И все через контроллер NodeMCU.

Подключал следующим образом:


Резистор 4.7
Датчик sr-04 работает без проблем, а вот температура всегда -127.

Код:

Код:
/**
   2 dallas sensors and 1 SR-04
   using the DALLAS, SR-04 and ESP8266

   static const uint8_t D0   = 16;
   static const uint8_t D1   = 5;
   static const uint8_t D2   = 4;
   static const uint8_t D3   = 0;
   static const uint8_t D4   = 2;
   static const uint8_t D5   = 14;
   static const uint8_t D6   = 12;
   static const uint8_t D7   = 13;
   static const uint8_t D8   = 15;
   static const uint8_t D9   = 3;
   static const uint8_t D10  = 1;
*/

#include <OneWire.h>
#include <DallasTemperature.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>

//SR-04
const int trigPin = 13;  //D7
const int echoPin = 12;  //D6

//DALLAS
#define PIN_DS18B20 5 //D1
int countDallasSensors;

//VARIABLES
long SR_Duration;
int SR_Distance;
float tempBoiler;
float tempPot;
unsigned long timerStart,
         timerEnd = 5000;


//NETWORK
byte mqtt_server[] = { 192, 168, 1, 231 };
char buffer[10];
// WiFi credentials.
const char* WIFI_SSID = "#";
const char* WIFI_PASS = "#";

const char* MQTT_SSID = "#";
const char* MQTT_PASS = "#";


OneWire oneWire(PIN_DS18B20);
DallasTemperature dallasSensors(&oneWire);

void MQTTMessage(char* topic, byte* payload, unsigned int length) {

}

WiFiClient wifiClient;
PubSubClient client(mqtt_server, 1883, MQTTMessage, wifiClient);

void connectWIFI() {
  WiFi.persistent(false);
  WiFi.mode(WIFI_OFF);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  unsigned long wifiConnectStart = millis();

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);

    // Only try for 5 seconds.
    if (millis() - wifiConnectStart > 5000) {
      return;
    }
  }
}

void reconnectMQTT() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Reconnect to MQTT");
    client.connect("ESP8266 Thermostate", MQTT_SSID, MQTT_PASS);
    client.publish("outTopic", "test");
    delay(5000);
  }
}

void getDistance() {
  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Reads the echoPin, returns the sound wave travel time in microseconds
  SR_Duration = pulseIn(echoPin, HIGH);

  // Calculating the distance
  SR_Distance = SR_Duration * 0.034 / 2;
}

void getTemperature(){
  dallasSensors.requestTemperatures();
  delay(500);
  tempBoiler = dallasSensors.getTempCByIndex(0);
  tempPot = dallasSensors.getTempCByIndex(1);
}

void sendToServer(int distance, double tempBoiler, double tempPot) {
  StaticJsonDocument<500> obj;
  if(distance < 150 && distance > 0){
    obj["distance"] = distance;
  }
 
  if(tempBoiler < 150 && tempBoiler > 0){
    obj["tempBoiler"] = tempBoiler;
  }

  if(tempPot < 150 && tempPot > 0){
    obj["tempPot"] = tempPot;
  }

  char payload[256];
  serializeJson(obj, payload);
  char* s = payload;
  if (client.connect("ESP8266 Temperature and Distance")) {
    if(client.publish("ESP/ToHome", s) == true){
      Serial.println("Reported!");
    }
  }
}

void setup() {
  Serial.begin(9600);

  // Wait for serial to initialize.
  while (!Serial) { }
 
  dallasSensors.begin();
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  countDallasSensors = dallasSensors.getDeviceCount();
  connectWIFI();
 
  Serial.println("Device Started");
  Serial.println("-------------------------------------");
}

void loop() {

  if (WiFi.status() != WL_CONNECTED) {
    connectWIFI();
  }

  if (!client.connected()) {
    reconnectMQTT();
  }

  if (millis() - timerStart > timerEnd) {
   
    getDistance();
    getTemperature();
    sendToServer(SR_Distance, tempBoiler, tempPot);
   
    timerStart += timerEnd; // reset 60 sec timer

  }
  delay(1000);
  client.loop();
}
Кто поможет, в чем может быть причина?

Еще бы заодно было бы интересно узнать, если ли другой способ реализации таймера, который бы не накапливал предыдущее значение? Для долгой работы текущий таймер не подходит.
 

enjoynering

Well-known member
советую посмотреть вот эту библиотеку для HC-SR04. умеет пропускать измерения через простенький медианный фильтр (точнее расстояние) и компенсировать скорость звука в соответствии с температурой окружающей среды (точнее расстояние).
 

CodeNameHawk

Moderator
Команда форума
  • void getTemperature(){
  • dallasSensors.requestTemperatures();
  • delay(500);
  • tempBoiler = dallasSensors.getTempCByIndex(0);
tempPot = dallasSensors.getTempCByIndex(1);
Если количество датчиков находит верно, то 500 мс может быть недостаточно для окончания преобразования.
 

CoolS2

New member
советую посмотреть вот эту библиотеку для HC-SR04. умеет пропускать измерения через простенький медианный фильтр (точнее расстояние) и компенсировать скорость звука в соответствии с температурой окружающей среды (точнее расстояние).
Спасибо, попробую!
 

Moseich

Member
Попробуйте другой пин - у меня подобное было. Китайские NodeMCU могут преподносить сюрпризы.
 

CodeNameHawk

Moderator
Команда форума
Не знаю, какую библиотеку (DallasTemperature.h) вы используете.

Я использую Arduino-Temperature-Control-Library-master
 

CodeNameHawk

Moderator
Команда форума
Я использую Arduino-Temperature-Control-Library-master
В ней надо инициализировать
Код:
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
 

CoolS2

New member
Поменял резистор на 1ком и температуру показало, так же вместо своего таймаута использовал ESP.deepSleep();
И вроде бы все работало, поставил на рабочее место. Температура дошла до 45 градусов и снова -127.
Пока что буду тестировать дальше, спасибо все за советы и помощь!
 

CoolS2

New member
Появился ещё один вопрос, когда контроллер находится не рядом с роутером, mqtt получает не все сообщения. Есть ли какая проверка, чтобы проверить все ли сообщения пришли
 

CoolS2

New member
Тему можно закрыть, все работает, в итоге заменил резистор на 1ком (писал выше). Изменил метод отправки данных, в итоге скетч такой:

Код:
/**
   Датчик SR-04P для определения остатка гранул в бункере, датчики температуры для котла и бойлера
   static const uint8_t D0   = 16;
   static const uint8_t D1   = 5;
   static const uint8_t D2   = 4;
   static const uint8_t D3   = 0;
   static const uint8_t D4   = 2;
   static const uint8_t D5   = 14;
   static const uint8_t D6   = 12;
   static const uint8_t D7   = 13;
   static const uint8_t D8   = 15;
   static const uint8_t D9   = 3;
   static const uint8_t D10  = 1;
*/

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

//SR-04
const int trigPin = 13;  //D7
const int echoPin = 12;  //D6

//DALLAS
#define PIN_DS18B20 5 //D1
int countDallasSensors;

//VARIABLES
long SR_Duration;
int SR_Distance;
float tempBoiler;
float tempPot;

//NETWORK
byte mqtt_server[] = { 192, 168, 1, 231 };
char buffer[10];
// WiFi credentials.
const char* WIFI_SSID = "#";
const char* WIFI_PASS = "#";

const char* MQTT_SSID = "#";
const char* MQTT_PASS = "#";


OneWire oneWire(PIN_DS18B20);
DallasTemperature dallasSensors(&oneWire);

void MQTTMessage(char* topic, byte* payload, unsigned int length) {

}

WiFiClient wifiClient;
PubSubClient client(mqtt_server, 1883, MQTTMessage, wifiClient);

void connectWIFI() {
  WiFi.persistent(false);
  WiFi.mode(WIFI_OFF);
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASS);

  unsigned long wifiConnectStart = millis();

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);

    // Only try for 5 seconds.
    if (millis() - wifiConnectStart > 5000) {
      return;
    }
  }
}

void reconnectMQTT() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Reconnect to MQTT");
    client.connect("ESP8266 Thermostate", MQTT_SSID, MQTT_PASS);
    client.publish("outTopic", "connecting..");
    delay(5000);
  }
}

void getDistance() {
  // Clears the trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Reads the echoPin, returns the sound wave travel time in microseconds
  SR_Duration = pulseIn(echoPin, HIGH);

  // Calculating the distance
  SR_Distance = SR_Duration * 0.034 / 2;
}

void getTemperature(){
  dallasSensors.requestTemperatures();
  delay(1000);
  tempBoiler = dallasSensors.getTempCByIndex(0);
  tempPot = dallasSensors.getTempCByIndex(1);
}

void sendToServer(int distance, double tempBoiler, double tempPot, int countDallasSensors) {
  client.publish("outTopic", "connected");
  if(distance < 150 && distance > 0){
    client.publish("ESP/ToHome/distance", String(distance).c_str());
  }
  if(tempBoiler < 150 && tempBoiler > 0){
    client.publish("ESP/ToHome/tempBoiler", String(tempBoiler).c_str());
  }
  if(tempPot < 150 && tempPot > 0){
    client.publish("ESP/ToHome/tempPot", String(tempPot).c_str());
  }

  client.publish("ESP/ToHome/countDallasSensors", String(countDallasSensors).c_str());
  Serial.println("Reported!");
  delay(1000);
}

void toDeepSleep(){
    client.disconnect();
    WiFi.disconnect();
    delay(1000);
    Serial.println("Sleeping..");
    delay(20);
    ESP.deepSleep(60e6);
   
}

void setup() {
  Serial.begin(9600);

  // Wait for serial to initialize.
  while (!Serial) { }
 
  dallasSensors.begin();
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  countDallasSensors = dallasSensors.getDeviceCount();
  connectWIFI();
 
  Serial.println("Device Started");
  Serial.println("-------------------------------------");
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    connectWIFI();
  }

  if (!client.connected()) {
    reconnectMQTT();
  }

  if (client.connected()) {
    getDistance();
    getTemperature();
    sendToServer(SR_Distance, tempBoiler, tempPot, countDallasSensors);
    toDeepSleep();
  }
  client.loop();
}
Спасибо за помощь!
 
Сверху Снизу