ESP, IoT Метеостанция народного мониторинга

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
161
3
@p-a-h-a,
ESP-01s отправляет температуру на Blynk. Я вставил в этот код Ваши строчки для экономии батареи. Сейчас подключено питание 2хАА (ионистор идёт). При отправки данных (3сек) потребление 70мА, потом сон на 5 мин (пока для теста) потребление 20мкА. Две недели теста на батареи сейчас 2,7В. Посмотрите пожалуйста этот код всё ли правильно и на месте вставлено? Может еще можно уменьшить потребление во сне?

C++:
//блок для include
//-----------------------------------------------
#include <DallasTemperature.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
//-----------------------------------------------

//-----------------------------------------------
//блок для define
//-----------------------------------------------
#define BLYNK_PRINT Serial
#define ONE_WIRE_BUS 0 // тут прописать свой GPIO куда подключен сенсор
//-----------------------------------------------

//-----------------------------------------------
//блок для глобальных перменных
//-----------------------------------------------
float temp = NAN; //температура

char auth[] = "********";
char ssid[] = "********";
char pass[] = "********";
//-----------------------------------------------

//-----------------------------------------------
//блок определений
//-----------------------------------------------
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
//-----------------------------------------------
// Пин питания датчика
int Vout = 2;      
//ADC_MODE (ADC_VCC);

void setup()
{
  pinMode(Vout, OUTPUT);
  digitalWrite(Vout, HIGH);
  int tryingToConnect = 5; // количество попыток соединиться с blynk сервером если не удается соединиться    

  Serial.begin(115200);                  
   
  sensors.requestTemperatures();
  delay(1000);
  temp = sensors.getTempCByIndex(0);            
   
  //Настройка блинк
  Blynk.config(auth);

  //Подключаемся к WiFi сети
  Blynk.connectWiFi(ssid, pass);

  while(!Blynk.connect() && tryingToConnect != 0) // пока есть попытки долбимся на сервер
  {
    tryingToConnect--;
    Serial.print("an attempt to join a number = ");                      
    Serial.println(tryingToConnect);
  }

  delay(3000); // пауза в 3 секунд, что бы до сна, все успело отправиться                
 
  Serial.println("Sleep mode ON");
  //Все отправили или нет, а заснуть нужно. Бай-бай!!!
  ESP.deepSleep(60000000 * 5); //глубокий сон 5 минуты для теста, потом поставить сколько нужно
}

void loop()
{
  //TODO        
}

//Когда произошел коннект с блинк сервером выполняется этот метод (функция)
BLYNK_CONNECTED()
{                          
// Blynk.notify("I`m send data of server"); // для наладки, потом закоментировать
  Serial.println();
  Serial.println("I`m send data of server");
  //Отправляем данные на сервер
  Blynk.virtualWrite(V2, temp); // тут прописать свои виртуальные шпильки        
  digitalWrite(Vout, LOW);
   int voltInt = ESP.getVcc();
  // long volt = voltInt*VCC_ADJ;
}
 

enemy_krs

★✩✩✩✩✩✩
28 Май 2019
104
37
я бы убрал задержки, первую после инициализации датчика и перенес опрос датчика в функцию BLYNK_CONNECTED()
вторая пауза в 3 секунды тоже много, суммарно ваш код будет выполняться больше 4 секунд, а может за 0,4
таким макаром батарей не хватит и на месяц
 

enemy_krs

★✩✩✩✩✩✩
28 Май 2019
104
37
я думаю сосем можно убрать, проверяй опытным путем )
 

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
161
3
@enemy_krs,
Спасибо. С задержкой 3 сек буду экспериментировать. Вот переделал по Вашему совету. Правильно?
C++:
/*************************************************************
  
//-----------------------------------------------
//блок для include
//-----------------------------------------------
#include <DallasTemperature.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
//-----------------------------------------------

//-----------------------------------------------
//блок для define
//-----------------------------------------------
#define BLYNK_PRINT Serial
#define ONE_WIRE_BUS 0 // тут прописать свой GPIO куда подключен сенсор
//-----------------------------------------------

//-----------------------------------------------
//блок для глобальных перменных
//-----------------------------------------------
float temp = NAN; //температура

char auth[] = "***"; 
char ssid[] = "***";
char pass[] = "***";
//-----------------------------------------------

//-----------------------------------------------
//блок определений
//-----------------------------------------------
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
//-----------------------------------------------
// Пин питания датчика
int Vout = 2;       
//ADC_MODE (ADC_VCC);

void setup()
{
  pinMode(Vout, OUTPUT);
  digitalWrite(Vout, HIGH);
  int tryingToConnect = 5; // количество попыток соединиться с blynk сервером если не удается соединиться     
 
  Serial.begin(115200);                   
    
  sensors.requestTemperatures();
  //delay(1000);
  //temp = sensors.getTempCByIndex(0);             
    
  //Настройка блинк
  Blynk.config(auth);

  //Подключаемся к WiFi сети
  Blynk.connectWiFi(ssid, pass);

  while(!Blynk.connect() && tryingToConnect != 0) // пока есть попытки долбимся на сервер
  {
    tryingToConnect--;
  }

  delay(1000); // пауза в 1 секунд, что бы до сна, все успело отправиться                 
  
  //Все отправили или нет, а заснуть нужно. Бай-бай!!!
  ESP.deepSleep(60000000 * 5); //глубокий сон 5 минуты для теста, потом поставить сколько нужно
}

void loop()
{
  //TODO         
}

//Когда произошел коннект с блинк сервером выполняется этот метод (функция)
BLYNK_CONNECTED()
{                           
temp = sensors.getTempCByIndex(0);
  //Отправляем данные на сервер
  Blynk.virtualWrite(V2, temp); // тут прописать свои виртуальные шпильки         
  digitalWrite(Vout, LOW);
   int voltInt = ESP.getVcc();
  // long volt = voltInt*VCC_ADJ;
}
первую после инициализации датчика и перенес опрос датчика в функцию BLYNK_CONNECTED()
После такой переделки потребление в 70 мА увеличивается до 10 сек. и температура не передается.
 

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
161
3
@enemy_krs,
Собрал по Вашему коду из поста #44 термометр на ESP-01s. Ошибок нет, при первом включении потребление 70мА и уходит в сон.
Просыпается через заданное время, но потребление 30мА и модуль висит. В чём может проблема? Датчик подключен к тем же пинам, что и у Вас в коде.
 

p-a-h-a

★✩✩✩✩✩✩
18 Фев 2019
35
27
@S_Sergey_G,
Возможно отсутствует резистор между gpio16 и RST номиналом 100-500 Ом. Иногда перемычка не работает, нужен резистор. На NodeMCU такое встречал.
 

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
161
3
@p-a-h-a,
Был не исправен сам модуль. На любых прошивках, после просыпания зависал, хотя до некоторого времени без сопротивления работал.
Сейчас на другом модуле всё работает с Вашим кодом, но время работы меньше 4 сек. не падает. Не знаю как уменьшить хотя бы до 1-2 сек. на ds18b20.

C++:
// https://community.alexgyver.ru/threads/meteostancija-narodnogo-monitoringa.3529/
// p-a-h-a пост 11
#include <ESP8266WiFi.h>
#define debug false // вывод отладочных сообщений
#define postingInterval  330e6 // интервал между отправками данных в секундах (330 сек=5,5 минут)
#define ONE_WIRE_BUS 2 // GPIO к которому подключен DS18B20
#define TEMPERATURE_PRECISION 12 // точность бит.DS18B20 Если глючит или врет, уменьшить до 9
#define TEMPERATURE_MEASURE_TIME 750 // время на преобразование температуры. 9бит-94мс, 10-188,11-375,12-750
#define DS18b20_VCC 0 //Нога питания датчика температуры

#define ssid  "*****"
#define password  "******"

#define DHCP true
IPAddress local_IP(192, 168, 8, 80); // меняем при переносе на другой роутер
IPAddress gateway(192, 168, 8, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(192, 168, 8, 1);
IPAddress secondaryDNS(8, 8, 4, 4);
#define chanal 1 //канал wifi
byte macAP[6] = {0x94, 0x37, 0xF7, 0x03, 0x48, 0x7E}; при переносе меняем mac на другой

unsigned long mill[2], startmillisDS18B20;// переменные для установки времени на измерение 18B20

#include <DallasTemperature.h>
#include <Wire.h>
ADC_MODE(ADC_VCC);// Будем измерять напряжение на VCC внутри МК
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
byte NumberOfDevices; //сколько датчиков найдем.
int VCC; //Напряжение батареи
String Hostname; //имя железки - выглядит как ESPAABBCCDDEEFF т.е. ESP+mac адрес.

void wificonect() { // процедура подключения к Wifi.
  if (DHCP)  WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
  WiFi.begin(ssid, password, chanal, macAP, true);

  while (WiFi.status() != WL_CONNECTED) {
    int i;
    if (debug) if (!(i % 100))Serial.print(".");
    delay(1);
    i++; if (i > 15000)  ESP.deepSleep(60e6);//СПИМ 1 минуту
  }
  if (debug) Serial.println("connected...");
  Hostname = "ESP" + WiFi.macAddress();
  Hostname.replace(":", "");// удаляем из названия двоеточия
  // WiFi.hostname(Hostname); // Название станции внутри локальной вайфай сети

  if (debug){ Serial.println(); Serial.print (millis()); Serial.println (" Подключено к wifi");}
}

void setup() {
  WiFi.setAutoConnect(true);
  WiFi.setAutoReconnect(true);
  pinMode(DS18b20_VCC, OUTPUT);
  digitalWrite(DS18b20_VCC, HIGH);
  Measure();// Запуск измерения

  Serial.begin(115200);
}

void loop() {
  SendToNarodmon();
  if (debug) Serial.print (millis());
  digitalWrite(DS18b20_VCC, LOW);// отключаем питание датчиков

  if (VCC > 4600) {
    delay((postingInterval));
    digitalWrite(DS18b20_VCC, HIGH);// включаем питание
    Measure();
  } else {
    ESP.deepSleep(postingInterval);
  }
}

void Measure() { // Запуск измерения датчиков
  VCC = ESP.getVcc();
  if (VCC < 2700) {
    ESP.deepSleep(86400e6); // спим сутки при низком питании
  }

  //DS18B20
  DeviceAddress tempDeviceAddress;
  sensors.begin(); //ds18b20
  NumberOfDevices = sensors.getDeviceCount(); //поищем.
  for (int i = 0; i < NumberOfDevices; i++) {
    if (sensors.getAddress(tempDeviceAddress, i)) sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);  //настроим.
  }
  startmillisDS18B20=millis();
  sensors.requestTemperatures(); //Начали измерение ds18b20
}

bool SendToNarodmon() { // Собственно формирование пакета и отправка.

  DeviceAddress tempDeviceAddress;

  wificonect();// подключаемся к сети
  if (debug) {
    Serial.println(WiFi.localIP()); Serial.println(WiFi.macAddress()); Serial.print("Narodmon ID: "); Serial.println(Hostname);
  }
  WiFiClient client;

  String buf;
buf = "#" + Hostname + "\n"; //mac адрес для авторизации датчика
// }

  client.connect("narodmon.ru", 8283);   // подключение

  if (debug) Serial.print(buf);


  //Данные от ESP ( Напряжение питания, уровень wifi
  buf = buf + "#VCC#" + String(VCC) + "#Напряжение батареи\n"; //показания температуры
  buf = buf + "#WIFI#"  + String(WiFi.RSSI()) + "#Уровень WI-FI " + String(WiFi.SSID()) + "\n"; // уровень WIFI сигнала
  if (debug) Serial.print(buf);

  //DS18B20 в самом конце чтоб было время на измерения

  if ((millis() < TEMPERATURE_MEASURE_TIME + startmillisDS18B20) && NumberOfDevices){// если 18b20 подключен(ы) и время на измерение менее 750мс то
    delay (TEMPERATURE_MEASURE_TIME + startmillisDS18B20 - millis()); // ждем до 750 мс для преобразования данных
  }
  for (int i = 0; i < NumberOfDevices; i++)  { //перечисляем датчики 18b20 и их показания
    mill[i] = millis();
    sensors.getAddress(tempDeviceAddress, i);
    buf = buf + "#";
    for (uint8_t i = 0; i < 8; i++) {
      if (tempDeviceAddress[i] < 16) buf = buf + "0";  // адрес датчика
      buf = buf  + String(tempDeviceAddress[i], HEX);
    }
    buf = buf + "#" + String(sensors.getTempCByIndex(i)) + "#DS18B20 №" + String(i + 1) + "\n"; //и температура
  }

  String worcktime = String(millis());
  float WTime = worcktime.toInt(); WTime /= 1000;
  buf = buf + "#WORKTIME#"  + String(WTime) + "#Время передачи данных" + "\n"; // уровень WIFI сигнала
  buf = buf + "##\n"; //окончание передачи

  client.print(buf); // и отправляем данные
  if (debug) {
    Serial.print(buf);
    for (int i = 0; i < NumberOfDevices; i++)  { //время отведенное на измерение 18b20 18b20 и их показания
      Serial.print  ("Время на измерения DS18B20№" + String(i) + " " + String(mill[i] - startmillisDS18B20) + "мс");
    }
  }

  delay(10);// сделать 100 если нужен ответ или 10 если не нужен . Время активности увеличивается в 2 раза
  while (client.available()) {
    String line = client.readStringUntil('\r'); // если что-то в ответ будет - все в Serial
    if (debug) {
      Serial.println(line);
    }
  }
  return true; //ушло
}
 

p-a-h-a

★✩✩✩✩✩✩
18 Фев 2019
35
27
@S_Sergey_G, Встретился с этой бедой. Похоже что дело в современных роутерах.
Попробуйте это и напишите сколько времени оно исполняется:
C++:
// Тестовый скеч для народмона. Шлет время выполнения себя на народмон
#include <ESP8266WiFi.h>
#define ssid  "*****"
#define password  "******"

void setup() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {delay(10);}
  WiFiClient client;
  String buf = "#ESP" + WiFi.macAddress() + "\n";
  buf.replace(":", "");// удаляем из мак двоеточия
  client.connect("narodmon.ru", 8283);   // можно и на narodmon.com
  String worcktime = String(millis());
  float WTime = worcktime.toInt(); WTime /= 1000;
  buf = buf + "#WORKTIME#"  + String(WTime) + "#Время передачи данных\n##\n";
  client.print(buf); // и отправляем данные
  delay(10);
  while (client.available()) {
    String line = client.readStringUntil('\r');// Возможна эту строку можно просто закоментировать
  }
  ESP.deepSleep(330e6, RF_NO_CAL); // Обратите внимание на , RF_NO_CAL это обязательно для быстродействия
}

void loop() {}
@S_Sergey_G, Задумайтесь о смене DS18B20 датчика еще. Этот датчик довольно медлителен. 0,75 сек думает.
Вариант еще такой: Просыпаемся, даем команду чтения температуры. Запоминаем в RTC память что нужно опросить датчик. Засыпаем на 0,75 сек. Просыпаемся, читаем RTC память и забираем температуру.
Из опытов ESP-Now выяснил, что милис() начинают работать примерно с 200й мс после подачи питания.
 

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
161
3
#WORKTIME#10.22#Время передачи данных
#WORKTIME#6.21#Время передачи данных
#WORKTIME#3.21#Время передачи данных
 
Изменено:

p-a-h-a

★✩✩✩✩✩✩
18 Фев 2019
35
27
@S_Sergey_G, Я не знаю простых способов победить вашу проблему.
Варианты такие:
№1. найти старый роутер
№2. Взять еще одну ESP подключенную к розетке и по протоколу ESP-Now принимать инфу с метеостанции а потом ее тихо и спокойно передавать куда следует. Помимо метеостанции еще можно каких-либо батарейных датчиков прикрутить отдельных.
Время работы ESP-Now 260 мс а millis покажет вообще 60 мс. тестировал недавно на старых ni-mhi AA аккумуляторах которым больше 10 лет, их на 120 000 соединений хватило в режиме 4 сообщения в секунду.
Пример ESP-Now прикладываю. Controller это датчик(метеостанция) а SLAVE приемник. Из подводных камней: при подключении SLAVE к WIFI канал роутера и ESP-Now должны быть одинаковы.
 

Вложения

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
161
3
@p-a-h-a, архив повреждён, не открывается.
Надо менять старенький архиватор, всё распаковалось.
 
Изменено:

p-a-h-a

★✩✩✩✩✩✩
18 Фев 2019
35
27
Прикладываю как заметку для себя.
В архиве скеч опроса BMP/BME280 без библиотеки со скоростью работы до 20мс на опрос температуры, давления и влажности. Это чуть быстрее Adafruit_BME280.h примерно на 0,5 секунды.
Позже внедрю в метеостанцию.
 

Вложения

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
161
3
@p-a-h-a,
Осилил Ваш проект из поста #32. Оставил из датчиков только DS18B20. Всё работает, время передачи на 12 bit датчика DS в среднем 1,5 сек. Но вот уменьшить битность датчика не получается. При изменении этих строк температура не передаётся, 25.00 постоянно показывает, номер датчика передаётся.
C++:
#define DS18B20Resolution 12
#define DS18B20Resolution 9
int DelayResolutionTime = 750 / (1 << (12 - DS18B20Resolution));
int DelayResolutionTime = 94 / (1 << (9 - DS18B20Resolution));
Вот полностью код, если можно посмотрите может ошибки где то есть?
C++:
#include <ESP8266WiFi.h>
//Настройки скетча:
#define debug false // Вывод отладочных сообщений в TCP сервер. Замедляет работу. false по умолчанию
#define Host "narodmon.ru"//"185.245.187.136"//"192.168.0.32"// можно запустить свой сервер с портом 8283 и смотреть во время отладки. Например https://swiddler.com/ (не отображает кодировку кириллицы)
#define SendData true // Отправлять данные на сервер (для отладки). true по умолчанию
#define postingInterval 330e6 // интервал между отправками данных в секундах (330 сек=5,5 минут)
#define MinVccSleep 0e9 // Время спячки при севших батарейках. 0 - до передергивания питания.
#define Recall 60e6 //время переподключения если нет сети или соединения с хостом
#define minVCC 2900 // Минимальное реальное напряжение питания.
#define OneWireGpio 2 // GPIO к которому подключен DS18B20
#define PIN_POWER_DS 0 // Шина питания датчика температуры
#define DS18B20Resolution 12 // точность бит.DS18B20 от 9 до 12. Чем выше разрядность тем медленее работает. 9=0,5`С 10=0,25`С
                              // 9бит-94мс, 10-188,11-375,12-750
#define ssid  "***"
#define password  "***"
#define local_IP {192, 168, 8, 95}
#define gateway {192, 168, 8, 1}
#define subnet {255, 255, 255, 0}
#define primaryDNS {192, 168, 8, 1}
#define secondaryDNS {8, 8, 4, 4}
#include <Wire.h>
#include <DallasTemperature.h>
OneWire oneWire(OneWireGpio);
DallasTemperature DS18B20(&oneWire);
uint32_t WaitDS18B20;// время ожидания измерения DS18B20
String DebugBuf;//строка Debug info
void ICACHE_RAM_ATTR InterruptMeasureLightPin();//ставим функцию прерываний InterruptMeasureLightPin() в RAM память для стабильной работы
uint32_t RCtime1;// тут хранится начальное время RC цепи
volatile uint32_t RCtime2;// тут хранится конечное время RC цепи
ADC_MODE(ADC_VCC);// Будем измерять напряжение на VCC внутри МК
int VCC; //Напряжение батареи
uint32_t calculateCRC32(const uint8_t *data, size_t length);
struct { //Структура, хранящаяся в RTC памяти
  uint32_t crc32;
  uint32_t NumberOfTransmitted; // Номер переданніх данніх после последней подачи питания
  uint32_t SendDataTime; // Время работы последней отправки
  bool DS18B20_not_found;
  DeviceAddress DS18B20Address;
  byte DS18B20Count;
} rtcData;
//[I]Расчет CRC32 RTC памяти[/I]/
uint32_t calculateCRC32(const uint8_t *data, size_t length) {// Расчет CRC RTC памяти чтоб понять битые там данные или нет
  uint32_t crc = 0xffffffff;
  while (length--) {
    uint8_t c = *data++;
    for (uint32_t i = 0x80; i > 0; i >>= 1) {
      bool bit = crc & 0x80000000;
      if (c & i) {
        bit = !bit;
      }
      crc <<= 1;
      if (bit) {
        crc ^= 0x04c11db7;
      }
    }
  }
  return crc;
}

//[I]Читаем данные из RTC памяти[/I]/
void RTCread() {
  if (ESP.rtcUserMemoryRead(0, (uint32_t*) &rtcData, sizeof(rtcData))) {
    uint32_t crcOfData = calculateCRC32((uint8_t*) &rtcData.NumberOfTransmitted, sizeof(rtcData) - sizeof(rtcData.crc32)); // Вычисляем crc32 начиная с адреса хранения переменной rtcData.NumberOfTransmitted до адресса размера в байтах структуры rtcData за исключением первой переменной, хранящей crc32
    if (crcOfData != rtcData.crc32) {// При первом включении и при битых данных в RTC памяти
      rtcData.NumberOfTransmitted = 1; //количество включений Назначаем данные по умолчанию при первом включении
      rtcData.SendDataTime = 0;// время работы
      rtcData.DS18B20Count = 0;
    }
  }
}

//[I]Обновляем данные в RTC памяти[/I]/
void RTCupdate() {
  rtcData.NumberOfTransmitted++;// Увеличиваем количество срабатываний
  rtcData.SendDataTime = millis();// Запоминаем время передачи
  rtcData.crc32 = calculateCRC32((uint8_t*) &rtcData.NumberOfTransmitted, sizeof(rtcData) - sizeof(rtcData.crc32));
  ESP.rtcUserMemoryWrite(0, (uint32_t*) &rtcData, sizeof(rtcData));// Write struct to RTC memory
}

//[I]процедура ожидания подключения к Wifi. длится в идеале 129мс[/I]/
void wificonect() {
  int i = 0;
  if (debug) DebugBuf += String(millis()) + "ms Time not wifi \n"; //64 мс
  while (WiFi.status() != WL_CONNECTED) {
    delay(1);
    i++; if (i > 10000) {
      RTCupdate();
      ESP.deepSleep(600e6, RF_NO_CAL);//СПИМ если не было соединения в течении 10 сек. Если у вас плохой конект с wifi то следует увеличить число до 10000
    }
  }
  if (debug) DebugBuf += String(millis()) + "ms wifi conected!\n";
}

void setup() {
  pinMode     (PIN_POWER_DS, OUTPUT);
  digitalWrite(PIN_POWER_DS, HIGH);
  if (debug) DebugBuf += "\n\nDebug info:\n" + String(millis()) + "ms void setup()\n";
  WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
  RTCread();// Пока конектится wifi читаем переменные из RTC памяти что сохранили перед прошлым сном
  if (rtcData.NumberOfTransmitted == 1) {
    WiFi.begin(ssid, password); // Если уже было подключение хоть раз то ssid и pass хранятся во флеше и берутся от туда раньше чем скетч начнет исполнятся. К этому моменту соединение с wifi установлено, назначаются ip адреса
  }
 
  Measure();// Запускаем измерения датчиков
  SendToNarodmon();
  RTCupdate();
  ESP.deepSleep(postingInterval - millis() * 1e3, RF_NO_CAL); // спим до следующей передачи данных
}

void loop() {}

void Measure() { // Запуск измерения датчиков
  //[I]-------------VCC-------------------[/I]/
  VCC = ESP.getVcc(); //Корректировка напряжения АКБ
  if (VCC < minVCC) {
    RTCupdate();
    ESP.deepSleep(MinVccSleep); // спим при низком питании
  }
  //[I]---------------DS18B20--------------[/I]/
  DS18B20.begin(); //ds18b20
  DS18B20.setWaitForConversion(false);//Асинхронный режим, т.е. функция requestTemperatures() не ждет 650 мс.

  if (rtcData.NumberOfTransmitted == 1) { // При первом включении находим датчики DS18B20 и запоминаем их.
    rtcData.DS18B20Count = DS18B20.getDeviceCount(); //поищем.
    for (int i = 0; i < rtcData.DS18B20Count; i++) {
      if (DS18B20.getAddress(rtcData.DS18B20Address, i)) DS18B20.setResolution(rtcData.DS18B20Address, DS18B20Resolution);  //настроим.
    }
    if (debug) DebugBuf += String(millis()) + " getAddress\n";
  }
  if (rtcData.DS18B20Count) { //Если DS18B20 подключены то запрашиваем измерения
    DS18B20.requestTemperatures(); //Начали измерение ds18b20
    WaitDS18B20 = millis();
    if (debug) DebugBuf += String(WaitDS18B20) + " DS18B20.requestTemperatures()\n";
  }
    }
void SendToNarodmon() { // Собственно формирование пакета и отправка.
  String buf = "#ESP" + WiFi.macAddress() + "\n"; //mac адрес для авторизации датчика
  buf.replace(":", "");// удаляем двоеточия из мак адреса
  String worcktime;
  float WTime;
  if (rtcData.NumberOfTransmitted == 1) { // При первом соединении передаем тип, показания и имена датчиков, при последующих только тип и показания
 }
    //Данные от ESP ( Напряжение питания,уровень wifi
    buf += "#VCC#" + String(VCC) + "#Напряжение батареи\n"; //показания температуры
    worcktime = String(rtcData.SendDataTime); // Время работы при предыдущей отправке
    WTime = worcktime.toInt(); WTime /= 1000;
    buf += "#WORKTIME#"  + String(WTime) + "#Время передачи данных\n";
      if (rtcData.DS18B20Count) {
      WaitDS18B20 = millis() - WaitDS18B20;
      //if (debug) DebugBuf += "timeDS " + String(WaitDS18B20) + "\n" + "millis=" + String(millis()) + "\n"; //64 мс
      int DelayResolutionTime = 750 / (1 << (12 - DS18B20Resolution));
      if (DelayResolutionTime > WaitDS18B20)
        delay(DelayResolutionTime - WaitDS18B20);
      if (debug) DebugBuf += "millis=" + String(millis()) + "\n" + "DelayResolutionTime " + String(DelayResolutionTime) + "\n" + "DelayResolutionTime-WaitDS18B20=" + String(DelayResolutionTime - WaitDS18B20) + "\n";

      for (int i = 0; i < rtcData.DS18B20Count; i++)  { //перечисляем датчики 18b20 и их показания
        DS18B20.getAddress(rtcData.DS18B20Address, i);
        buf = buf + "#";
        for (uint8_t i = 0; i < 8; i++) {
          if (rtcData.DS18B20Address[i] < 16) buf = buf + "0";  // адрес датчика
          buf = buf  + String(rtcData.DS18B20Address[i], HEX);
        }
        buf = buf + "#" + String(DS18B20.getTempCByIndex(i)) + "#DS18B20 №" + String(i + 1) + "\n"; //и температура
      }
    }
  wificonect();// ожидание установки соединения с сетью
  WiFiClient client;
  buf += "#WIFI#"  + String(WiFi.RSSI()) + "\n"; // уровень WIFI сигнала
  if (SendData) {
    if (!client.connect(Host, 8283)) {  // подключение
      RTCupdate();
      ESP.deepSleep(50e65, RF_NO_CAL);// Если не вышло подключится - засыпаем
    }
  }
  buf = buf + "##\n"; //окончание передачи
  client.print(buf); // и отправляем данные
  if (debug) {
  }

  delay(10);// сделать 100 если нужен ответ или 10 если не нужен . Время активности увеличивается в 2 раза
  if (SendData) {
    while (client.available()) {
      String line = client.readStringUntil('\r'); //
    }
  }
}
 

p-a-h-a

★✩✩✩✩✩✩
18 Фев 2019
35
27
В 151 строке int DelayResolutionTime = 750 / (1 << (12 - DS18B20Resolution));
Замените на:
DelayResolutionTime = 750;
Задержку в мс 750 измените на необходимую, в зависимости от битности.

Перед этим убедитесь что в примере от dallas датчик работает корректно на разной битности.
Подозреваю что вашему датчику не хватает времени на преобразование. Время прописано в даташите. Возможно неоригинальный датчик.
 

p-a-h-a

★✩✩✩✩✩✩
18 Фев 2019
35
27
Я в новых устройствах поменял концепцию.
Сейчас одна esp постоянно сидит на розетке и ждет пакета ESP-NOW. А датчик работает от 2х батареек ААА
К концу передачи millis() составляет 38мс. По факту вместе с загрузкой магия длится 0,25с. Ну и для таких таймингов 18b20 конечно не годиться, хотя и передаватт инфу можно через раз. Запросил измерение, поспал, проснулся - передал результат. Но в таком случае 0,5 с будет на измерение что составит больше года работы от ААА.
 

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
161
3
@p-a-h-a,
Проверил на примере от dallas , датчик работает корректно на всех битностях. Но в коде только на 12 bit работает. Строчку int DelayResolutionTime = 750 / (1 << (12 - DS18B20Resolution)); заменил на
int DelayResolutionTime = 94;
 

knopaleo

✩✩✩✩✩✩✩
12 Авг 2019
19
2

@p-a-h-a,
В вашей новой концепции как я понимаю можно передать результат на любой ресурс, а не только на народный монитор?
И еще хотелось бы узнать о вашем опыте установки внешней антенны.
 

xlin

✩✩✩✩✩✩✩
20 Фев 2021
1
0
приветствую. собрал метеостанцию, она через какое то время перестает просыпаться,то через день,то через два. вытаскиваешь питание-запускается,и снова не просыпается через какое то время,если архив прикреплю с кодом кто нибудь ткнет на ошибку? спасибо
 

Dimka_STUDENT

✩✩✩✩✩✩✩
28 Ноя 2022
3
1
Здравствуйте! Я в ардуино ещё новичок, и вот такой вопрос. Можно ли данный код как то преобразить для отправки данных на локальный сервер? Задумывается использовать esp8266 с распаянный на платке программатором и датчик температуры DS18B20
 

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
161
3
@Dimka_STUDENT,
Вроде Narodmon нельзя поднять на локальном сервере. А вот Blynk можно. Или MQTT используйте.
 

Dimka_STUDENT

✩✩✩✩✩✩✩
28 Ноя 2022
3
1
@S_Sergey_G, я не про копию народной карты. На локальном сервере php скрипт будет получать данные и заносить в таблицу sql, а другой уже выводить на планшет данные погоды и температуры. Автономность датчиков при этом не нужна
 
  • Лойс +1
Реакции: Burai

knopaleo

✩✩✩✩✩✩✩
12 Авг 2019
19
2
@Dimka_STUDENT,
Както заумно у вас. Зарегистрируйтесь на Thingspeak. Отправляйте свои данные туда.
Установите программу мониторинга на планшет и смотрите что вам надо с разбивкой от одного дня до месяца.
 

Вложения