Jump to content
iT4iT.CLUB

Recommended Posts

В 09.04.2018 в 17:46, Dark FeniX сказал:

После передачи 3-х параметров идёт непонятный Socket error on client ESP_FEDA21, disconnecting.

Подскажите пожалуйста, куда копать?

А у меня пока норм мажор принимает данные (у меня по-моему 5 параметров), правда я до самой последней версии ещё не обновился. 

Share this post


Link to post
Share on other sites

Вчера пытался разобраться, почему передаются только 3 параметра. Особого результата не добился. Понял только все 5 параметров передаются - добавил вывод в монитор порта после передачи каждого параметра. Но соединение с брокером рвётся после передачи 3-го. От того, какой именно параметр - не зависит, менял порядок местами.

Гугление результата не дало, наткнулся только на мысль, что, возможно, параллельно передаче данных на брокер, начинает идти передача ещё каких-то данных, что и вызывает обрыв сеанса передачи.

Share this post


Link to post
Share on other sites
В 09.04.2018 в 17:46, Dark FeniX сказал:

Доброго времени суток! Сперва, хочу поблагодарить автора за столь замечательный проект. На его основе я сейчас создаю свою домашнюю метеостанцию. Пока только собрана на макетке, но работоспособна уже на 80%. Распечатана будка Стивенсона, жду, как приедет OLED-дисплей, который намереваюсь прикрутить к основному блоку. Немного подправил код программы, для работы с двумя датчиками - BME280 (внутренний) и Si7021 (внешний).

users_bme280_x2.h

  Показать содержимое


#ifndef USERS_H
#define USERS_H

#include <BME280I2C.h> // https://github.com/finitespace/BME280
#include <HTU21D.h>
  HTU21D myHTU21D(HTU21D_RES_RH12_TEMP14);


  BME280I2C::Settings
  settings_in(
    BME280::OSR_X1,
    BME280::OSR_X1,
    BME280::OSR_X1,
    BME280::Mode_Forced,
    BME280::StandbyTime_1000ms,
    BME280::Filter_Off,
    BME280::SpiEnable_False,
    BME280I2C::I2CAddr_0x76
  );

  BME280I2C BME_IN(settings_in);

  /* Параметры индикаторов web интерфейса для плагина Knob
    Мин Макс Шаг Заголовок Ед. измер.
    |---------------------|----|------|------|--------------|---------| */
  knob_t *T = new knob_t( -40, 125, ".1", "Температура", "°C");
  knob_t *P = new knob_t(-500, 9000, ".01", "Давление", "mm");
  knob_t *H = new knob_t( 0, 100, ".01", "Влажность", "%");

  /* Функции, описывающие инициализацию датчиков */
  void out_init() {
    myHTU21D.begin();
  }
  void in_init() {
    BME_IN.begin();
  }

  /* Функции, описывающие как получить от внешнего датчика те или иные данные */
  float out_temp() {
    return myHTU21D.readTemperature(SI70xx_TEMP_READ_AFTER_RH_MEASURMENT);
  } 
  float out_hum() {
    return myHTU21D.readHumidity();
  }

  /* Функции, описывающие как получить от внутреннего датчика те или иные данные */
  float in_temp() {
    return BME_IN.temp(BME280::TempUnit_Celsius);
  }
  float in_hum() {
    return BME_IN.hum();
  }
  float in_pres() {
    return BME_IN.pres(BME280::PresUnit_torr);
  }

  /* Добавление датчиков в систему */
  void sensors_config() {
    Wire.begin(4, 5);

    /* Внешний датчик */
    sensors.add(H, device::out, 0x40, "out_humidity", out_hum, true);  
    sensors.add(T, device::out, 0x40, "out_temperature", out_init, out_temp, true);

    /* Внутренний датчик */
    sensors.add(P, device::in, 0x76, "in_pressure", in_pres, true);
    sensors.add(H, device::in, 0x76, "in_humidity", in_hum, true);
    sensors.add(T, device::in, 0x76, "in_temperature", in_init, in_temp, true);
  }

#endif

 

SERVICES.H (подправлена секция MQTT)

  Показать содержимое


#ifndef SERVICES_H
#define SERVICES_H

#include <PubSubClient.h>
#include <ESP8266HTTPClient.h>
#include "webserver.h"

  WiFiClient wifiClient;
  PubSubClient mqttAPI(wifiClient);
  HTTPClient restAPI;

  String httpCodeStr(int code) {
    switch (code) {
      case -1: return "CONNECTION REFUSED";
      case -2: return "SEND HEADER FAILED";
      case -3: return "SEND PAYLOAD FAILED";
      case -4: return "NOT CONNECTED";
      case -5: return "CONNECTION LOST";
      case -6: return "NO STREAM";
      case -7: return "NO HTTP SERVER";
      case -8: return "TOO LESS RAM";
      case -9: return "ENCODING";
      case -10: return "STREAM WRITE";
      case -11: return "READ TIMEOUT";
      default: return http.codeTranslate(code);
    }
  }

  String mqttCodeStr(int code) {
    switch (code) {
      case -4: return "CONNECTION TIMEOUT";
      case -3: return "CONNECTION LOST";
      case -2: return "CONNECT FAILED";
      case -1: return "MQTT DISCONNECTED";
      case 0: return "CONNECTED";
      case 1: return "CONNECT BAD PROTOCOL";
      case 2: return "CONNECT BAD CLIENT ID";
      case 3: return "CONNECT UNAVAILABLE";
      case 4: return "CONNECT BAD CREDENTIALS";
      case 5: return "CONNECT UNAUTHORIZED";
      default: return String(code);
    }
  }

  bool mqttPublish(String topic, float data) {
    if (conf.param("mqtt_path").length()) topic = conf.param("mqtt_path") + "/" + topic;
    return mqttAPI.publish(topic.c_str(), String(data).c_str(), true);
  }

  void restAPIsend(String host, uint16_t port, String query) {
    restAPI.setUserAgent("weather station (www.it4it.club) " + WiFi.hostname());
    restAPI.setTimeout(5000);
    restAPI.begin(host, port, query);
    int code = restAPI.GET();
#ifdef console
    console.printf("answer: %s\n", httpCodeStr(code).c_str());
#endif
    restAPI.end();
  }

  /* mqtt.it4it.club */
  void sendDataToMQTT() {
    if (wifi.transferDataPossible() and conf.param("mqtt_server").length()) {
#ifdef console
      console.println(F("services: send data to MQTT server"));
#endif
      // баг при прямой передаче значения (c_str) из конфига в setServer (не забыть поправить!)
      String server = conf.param("mqtt_server");
      mqttAPI.setServer(server.c_str(), 1883);
      mqttAPI.connect(WiFi.hostname().c_str(),
                      (conf.param("mqtt_login").length() ? conf.param("mqtt_login").c_str() : 0),
                      (conf.param("mqtt_pass").length() ? conf.param("mqtt_pass").c_str() : 0)
                     );
      if (mqttAPI.connected()) {
        //mqttPublish("light", sensors.get("out_light"));
        mqttPublish("out_temperature", sensors.get("out_temperature"));
        mqttPublish("out_humidity", sensors.get("out_humidity"));
        mqttPublish("in_pressure", sensors.get("in_pressure"));
        mqttPublish("in_temperature", sensors.get("in_temperature"));
        mqttPublish("in_humidity", sensors.get("in_humidity"));  

#ifdef console
        console.printf("answer: %s\n", mqttCodeStr(mqttAPI.state()).c_str());
#endif
        mqttAPI.disconnect();
      } else {
#ifdef console
        console.printf("answer: %s\n", mqttCodeStr(mqttAPI.state()).c_str());
#endif
      }
    }
  }

  /* https://thingspeak.com/ */
  void sendDataToThingSpeak() {
    if (wifi.transferDataPossible() and conf.param("thingspeak_key").length()) {
#ifdef console
      console.println(F("services: send data to ThingSpeak"));
#endif

      String query;
      query += "&field1=" + String(sensors.get("out_light"));
      query += "&field2=" + String(sensors.get("out_temperature"));
      query += "&field3=" + String(sensors.get("out_humidity"));
      query += "&field4=" + String(sensors.get("out_pressure"));

      restAPIsend("api.thingspeak.com", 80, "/update?api_key=" + conf.param("thingspeak_key") + query);
    }
  }

  /* https://narodmon.ru/ */
  void sendDataToNarodmon() {
    if (wifi.transferDataPossible() and conf.param("narodmon_id").length()) {
#ifdef console
      console.println(F("services: send data to Narodmon"));
#endif

      String query;
      query += "&L1=" + String(sensors.get("out_light"));
      query += "&T1=" + String(sensors.get("out_temperature"));
      query += "&H1=" + String(sensors.get("out_humidity"));
      query += "&P1=" + String(sensors.get("out_pressure"));

      restAPIsend("narodmon.ru", 80, "/get?id=" + conf.param("narodmon_id") + query);
    }
  }

#endif

 

Вот только есть небольшая проблема, в решении которой прошу помощи. А именно: передача информации по MQTT. Для меня это важно, так как хочу добиться передачи в Мажордомо. Суть проблемы в том, что передаются только первые 3 данных. Причем эта проблема у меня была ещё даже с одним датчиком ВМЕ280, передавалось пустое значение с отсутствующего люксометра. После того, как закомментировал строку


 //mqttPublish("light", sensors.get("out_light"));

в SERVICES.H, передаваться стали следующие 3 параметра, температура, влажность и давление. Сейчас же, когда должны передаваться 5 параметров с 2-х датчиков, передаются только температура и влажность с Si7021 и давление с BME280, всё в порядке, указанном в SERVICES.H. 

В Mosquitto отображается следующее:

5acb7c3fec9aa_2.PNG.cbd5563e8f69d2c0ef967519cc243d9f.PNG

После передачи 3-х параметров идёт непонятный Socket error on client ESP_FEDA21, disconnecting.

Подскажите пожалуйста, куда копать?

У меня была подобная проблема с Mosquitto неполной передачи.

Решение 

 if (tMQTT != 0) {
      if (millis() - tMQTT > 1000 or tMQTT > millis()){       
      mqttAPI.disconnect();
      tMQTT = 0;
    }
  }

Вызов функции mqttAPI.disconnect(); после окончания передачи через 1с. Все заработало. У меня передача на Mosquitto идет каждые 5s. 

Далее полученная информация архивируется в СКАДА системе. (с периодичностью 5с)

У меня к ESP (Nodemcu) подключено 2хBME + 10x ds18b20 и все передается в Mosquitto реализованное на виртуальной машине как и web скада

Edited by Vladimir
  • Thanks 2

Share this post


Link to post
Share on other sites
В 20.04.2018 в 12:46, Vladimir сказал:

У меня была подобная проблема с Mosquitto неполной передачи.

Решение 

 if (tMQTT != 0) {
      if (millis() - tMQTT > 1000 or tMQTT > millis()){       
      mqttAPI.disconnect();
      tMQTT = 0;
    }
  }

Вызов функции mqttAPI.disconnect(); после окончания передачи через 1с. Все заработало. У меня передача на Mosquitto идет каждые 5s. 

Далее полученная информация архивируется в СКАДА системе. (с периодичностью 5с)

У меня к ESP (Nodemcu) подключено 2хBME + 10x ds18b20 и все передается в Mosquitto реализованное на виртуальной машине как и web скада

Спасибо за помощь! Если я всё правильно понял, то предлагается ввести задержку после отправки данных через MQTT, перед отключением от брокера. Возможно, действительно, разрыв связи происходит быстрее, чем происходит передача.

Я попробовал ввести этот код в свой скетч, но, увы, из-за малых познаний Ардуино, пришлось действовать методом проб и ошибок. Хотя, как я понял, это банальная задержка с помощью millis. Просьба взглянуть на мой код и подправить, где я ошибся. :)

Скрытый текст

#ifndef SERVICES_H
#define SERVICES_H

#include <PubSubClient.h>
#include <ESP8266HTTPClient.h>
#include "webserver.h"

WiFiClient wifiClient;
PubSubClient mqttAPI(wifiClient);
HTTPClient restAPI;
unsigned long tMQTT = millis();

String httpCodeStr(int code) {
switch (code) {
case -1: return "CONNECTION REFUSED";
case -2: return "SEND HEADER FAILED";
case -3: return "SEND PAYLOAD FAILED";
case -4: return "NOT CONNECTED";
case -5: return "CONNECTION LOST";
case -6: return "NO STREAM";
case -7: return "NO HTTP SERVER";
case -8: return "TOO LESS RAM";
case -9: return "ENCODING";
case -10: return "STREAM WRITE";
case -11: return "READ TIMEOUT";
default: return http.codeTranslate(code);
}
}

String mqttCodeStr(int code) {
switch (code) {
case -4: return "CONNECTION TIMEOUT";
case -3: return "CONNECTION LOST";
case -2: return "CONNECT FAILED";
case -1: return "MQTT DISCONNECTED";
case 0: return "CONNECTED";
case 1: return "CONNECT BAD PROTOCOL";
case 2: return "CONNECT BAD CLIENT ID";
case 3: return "CONNECT UNAVAILABLE";
case 4: return "CONNECT BAD CREDENTIALS";
case 5: return "CONNECT UNAUTHORIZED";
default: return String(code);
}
}

bool mqttPublish(String topic, String data) {
if (conf.param("mqtt_path").length()) topic = conf.param("mqtt_path") + "/" + topic;
// return mqttAPI.publish(topic.c_str(), data.c_str(), true);
}
bool mqttPublish(String topic, float data) {
return mqttPublish(topic, String(data));
}

void restAPIsend(String host, uint16_t port, String query) {
restAPI.setUserAgent("weather station (www.it4it.club) " + WiFi.hostname());
restAPI.setTimeout(5000);
restAPI.begin(host, port, query);
int code = restAPI.GET();
#ifdef console
console.printf("answer: %s\n", httpCodeStr(code).c_str());
#endif
restAPI.end();
}

/* mqtt.it4it.club */
void sendDataToMQTT() {
if (wifi.transferDataPossible() and conf.param("mqtt_server").length()) {
#ifdef console
console.println(F("services: send data to MQTT server"));
#endif
// баг при прямой передаче значения (c_str) из конфига в setServer (не забыть поправить!)
String server = conf.param("mqtt_server");
mqttAPI.setServer(server.c_str(), 1883);
mqttAPI.connect(WiFi.hostname().c_str(),
(conf.param("mqtt_login").length() ? conf.param("mqtt_login").c_str() : 0),
(conf.param("mqtt_pass").length() ? conf.param("mqtt_pass").c_str() : 0)
);
if (mqttAPI.connected()) {
//mqttPublish("light", sensors.get("out_light"));
mqttPublish("out_temperature", sensors.get("out_temperature"));
console.println(F("send data out_temperature"));
mqttPublish("out_humidity", sensors.get("out_humidity"));
console.println(F("send data out_humidity"));
mqttPublish("in_pressure", sensors.get("in_pressure"));
console.println(F("send data in_pressure"));
mqttPublish("in_temperature", sensors.get("in_temperature"));
console.println(F("send data in_temperature"));
mqttPublish("in_humidity", sensors.get("in_humidity"));
console.println(F("send data in_humidity"));

#ifdef console
console.printf("answer: %s\n", mqttCodeStr(mqttAPI.state()).c_str());
#endif
if (tMQTT != 0) {
if (millis() - tMQTT > 1000 or tMQTT > millis()) {
mqttAPI.disconnect();
tMQTT = 0;
}
} else {
#ifdef console
console.printf("answer: %s\n", mqttCodeStr(mqttAPI.state()).c_str());
#endif
}
}
}
}
/* https://thingspeak.com/ */
void sendDataToThingSpeak() {
if (wifi.transferDataPossible() and conf.param("thingspeak_key").length()) {
#ifdef console
console.println(F("services: send data to ThingSpeak"));
#endif

String query;
query += "&field1=" + String(sensors.get("out_light"));
query += "&field2=" + String(sensors.get("out_temperature"));
query += "&field3=" + String(sensors.get("out_humidity"));
query += "&field4=" + String(sensors.get("out_pressure"));

restAPIsend("api.thingspeak.com", 80, "/update?api_key=" + conf.param("thingspeak_key") + query);
}
}

/* https://narodmon.ru/ */
void sendDataToNarodmon() {
if (wifi.transferDataPossible() and conf.param("narodmon_id").length()) {
#ifdef console
console.println(F("services: send data to Narodmon"));
#endif

String query;
query += "&L1=" + String(sensors.get("out_light"));
query += "&T1=" + String(sensors.get("out_temperature"));
query += "&H1=" + String(sensors.get("out_humidity"));
query += "&P1=" + String(sensors.get("out_pressure"));

restAPIsend("narodmon.ru", 80, "/get?id=" + conf.param("narodmon_id") + query);
}
}

#endif

 

По факту, у меня вообще перестала работать передача данных на брокер. Идёт разрыв по тайм-ауту.

Снимок3.PNG

Share this post


Link to post
Share on other sites
12 часов назад, Dark FeniX сказал:

Спасибо за помощь! Если я всё правильно понял, то предлагается ввести задержку после отправки данных через MQTT, перед отключением от брокера. Возможно, действительно, разрыв связи происходит быстрее, чем происходит передача.

Я попробовал ввести этот код в свой скетч, но, увы, из-за малых познаний Ардуино, пришлось действовать методом проб и ошибок. Хотя, как я понял, это банальная задержка с помощью millis. Просьба взглянуть на мой код и подправить, где я ошибся. :)

По факту, у меня вообще перестала работать передача данных на брокер. Идёт разрыв по тайм-ауту.

 

Для введения задержки я использовал:

 

В servces.h Сделать так.

 tMQTT = millis();
    //  mqttAPI.disconnect();

В теле программы (первая закладка с названием прошивки) сделать так.

void loop() {
  /* Обработчики */
  wifi.handleEvents();
  http.handleClient();
  cron.handleEvents();


// Дисконект по связи с MQTT необходима задержка для передачи всех данных
  if (tMQTT != 0) {
      if (millis() - tMQTT > 1000 or tMQTT > millis()){       
      mqttAPI.disconnect();
      tMQTT = 0;
    }
  }
// Активация счета температуры в датчиках DS за 1,5с до чтения датчиков из программы
  if (millis() - TReadT > 3500 or TReadT > millis()){       
      Tsensors.setWaitForConversion(false); //No waiting for measurement
      Tsensors.requestTemperatures(); //Initiate the temperature measurement
    }

  
}

У меня все работает. 

Часть касательно датчиков DS не нужна. К стати сейчас на один шлейф повешено 11 датчиков DS - работают стабильно.

 

  • Thanks 1

Share this post


Link to post
Share on other sites

залил последнюю прошивку с изменениями (отправка на MD), с раскомментированными строками:

 

  sensors.add(new knob_t(-100, 0, "1", "RSSI", "dbm"), device::in, "rssi",[&](){ 
    return wifi.isConnected() ? WiFi.RSSI() : 0; 
  });
  sensors.add(new knob_t(0, 5, ".01", "Питание", "V"), device::in, "vcc", [&](){ 
    return ESP.getVcc() * 0.001; 
  });
  sensors.add(new knob_t(0, 81920, "1", "RAM", "Byte"), device::in, "ram", [&](){
    return 81920 - ESP.getFreeHeap();
  });

вот так выдает:

5ae075b4b8734_Screenshot_2018-04-25-15-30-59-065_com.yandex.browser1.thumb.png.3425141f0099d105d94c3f8c58030b57.png

странно получается..что-то передает что-то нет.

несколько раз прошивал, картина не меняется, прошил другую плату все стало норм показывать (пару раз прошил все ок!).

походу все дело в платах

Edited by pasha413
поправка

Share this post


Link to post
Share on other sites
В 25.04.2018 в 15:35, pasha413 сказал:

залил последнюю прошивку с изменениями (отправка на MD), с раскомментированными строками:

 


  sensors.add(new knob_t(-100, 0, "1", "RSSI", "dbm"), device::in, "rssi",[&](){ 
    return wifi.isConnected() ? WiFi.RSSI() : 0; 
  });
  sensors.add(new knob_t(0, 5, ".01", "Питание", "V"), device::in, "vcc", [&](){ 
    return ESP.getVcc() * 0.001; 
  });
  sensors.add(new knob_t(0, 81920, "1", "RAM", "Byte"), device::in, "ram", [&](){
    return 81920 - ESP.getFreeHeap();
  });

вот так выдает:

5ae075b4b8734_Screenshot_2018-04-25-15-30-59-065_com.yandex.browser1.thumb.png.3425141f0099d105d94c3f8c58030b57.png

странно получается..что-то передает что-то нет.

несколько раз прошивал, картина не меняется, прошил другую плату все стало норм показывать (пару раз прошил все ок!).

походу все дело в платах

Сталкивался с подобной ситуацией при заливке прошивки через WEB интерфейс.

Причины до конца не выяснил НО!:

Если сначала сделать без подключенного контроллера:

1) Надавить кнопку "Проверить"

2) Кнопка "Загрузка" при этом происходит компиляция но выдается ошибка т.к. ESP не подключено

3) "Скетч"далее "Экспорт бинарного файла" и загрузится через WEB то если загрузка пройдет (у меня не всегда проходит) то русский язык появляется.

Конечно это странно. У меня NODEMCU стоит далеко и поэтому загрузка только через WEB возможна.

Но сейчас уже не актуально т.к. все данные у меня передаются через MQTT на домашнюю СКАДА.

 

Share this post


Link to post
Share on other sites

Друзья, всем доброго времени суток. Моя домашняя метеостанция восстановлена, но в ходе поиска и исправления ошибок на которые Вы указали и дальнейших тестов (приходится проводить длительные эксперименты, примерно 1-2 суток на каждый т.к некоторые проблемы сразу не проявляются) была выявлена серьезная утечка памяти. Убил много времени на поиск проблемы в проекте метеостанции, но к сожалению, она оказалась в самой платформе ESP8266 v2.4.1. Пришлось откатиться на v2.4.0 и начать тесты с нуля. Проблема проявляется при работе с объектом WiFiClient, а значит при работе со всеми удаленными серверами (MQTT, RestAPI,  ...). Отслеживать состояние решения проблемы можно на GitHub. Это важный момент и его стоит отслеживать.

Share this post


Link to post
Share on other sites

Не уверен насколько это актуально для новой версии (не проверял), но похожие глюки со шрифтами у меня были с предыдущей прошивкой...

Найдите пять отличий... ))

Скрытый текст

I  1377053588_2018-04-2822-40-11_ESP8266_WS_iT4iT.CLUB-PPS-oled_v14.5_.inoArduino1.8.5(2).jpg.8de5c1c5253ce3c422a44158d1145650.jpg20112017105.jpg.4a5511739de4b2d4bfa08b829df0e267.jpg.cf130fd6a83613e4ec0a64c9863be72e.jpg

 

 

II 2102484117_2018-04-2822-40-34_ESP8266_WS_iT4iT.CLUB-PPS-oled_v14.5_.inoArduino1.8.5(2).jpg.87c7bcceb86130fff7bdb9a0a4af0585.jpg28042018128.jpg.a0a0f85e83ab8a622339956cc430e0d7.jpg

На самом деле принципиальных и существенных отличий тут два. 1) В первом случае знак градуса (°) не отображается на экране монитора не смотря на то, что часть кода с этим самым знаком неизменна... 2) Уверен вы уже заметили сами... (§ - ɐʞεɐʞɔɓоu 'vиɯǝwɐε ǝн оɯʞ)

Предполагаю это ошибка Arduino IDE, т.к. в настройках хоть и стоит галочка "Сохранять скетч при проверке или компиляции" на функцию "Экспорт бинарного файла" это почем-то не распространяется... @pasha413 @Vladimir и дело тут вероятно не в платах, и не в "Проверить". После внесения изменений, перед "Экспорт бинарного файла", попробуйте нажимать Ctrl+S "Сохранить", мне это помогло... Другой вопрос почему так происходит, но это уже думаю не сюда, а к разработчикам IDE или библиотек для IDE...

Удачи! ))

Edited by EndWar
орфография и пунктуация...
  • Thanks 1

Share this post


Link to post
Share on other sites
В 25.04.2018 в 07:20, Vladimir сказал:

Для введения задержки я использовал:

 

В servces.h Сделать так.

 tMQTT = millis();
    //  mqttAPI.disconnect();

В теле программы (первая закладка с названием прошивки) сделать так.

void loop() {
  /* Обработчики */
  wifi.handleEvents();
  http.handleClient();
  cron.handleEvents();


// Дисконект по связи с MQTT необходима задержка для передачи всех данных
  if (tMQTT != 0) {
      if (millis() - tMQTT > 1000 or tMQTT > millis()){       
      mqttAPI.disconnect();
      tMQTT = 0;
    }
  }
// Активация счета температуры в датчиках DS за 1,5с до чтения датчиков из программы
  if (millis() - TReadT > 3500 or TReadT > millis()){       
      Tsensors.setWaitForConversion(false); //No waiting for measurement
      Tsensors.requestTemperatures(); //Initiate the temperature measurement
    }

  
}

У меня все работает. 

Часть касательно датчиков DS не нужна. К стати сейчас на один шлейф повешено 11 датчиков DS - работают стабильно.

 

Спасибо огромное, заработало! Единственное, пришлось объявить переменную tMQTT, потому что компилятор ругался. В servces.h в начале ввёл

unsigned long tMQTT;

WiFiClient wifiClient;
PubSubClient mqttAPI(wifiClient);

Еще одно нашел, пока гуглил о проблемах с передачами по MQTT. 

 Есть два проекта PubSubClient:
для Arduino - https://github.com/knolleary/pubsubclient
для ESP8266 - https://github.com/Imroy/pubsubclient

У нас используется первый, возможно, второй будет более подходящим?

Share this post


Link to post
Share on other sites
В 25.03.2018 в 18:12, Вадим сказал:

Температура, влажность, давление - BME280. Ветер, направление, облачность - с openweathermap.org. Взял часть кода с " Умные часы на ESP8266 и SSD1306". В services.h  (там видно где) прописываем свой ключ  полученный при регистрации. После запуска сразу будут нули, значения подтянутся на шестой минуте, в логе видно. Может кого  заинтересует... P. S.  Ни как не получается направление ветра с градусов перевести в быстрее понятное  "С", "СВ", и так далее... Может кто поможет. P. S.2 Я только учусь.

скрин.JPG

Wether.7z

Два датчика BME280, изменения в файле index (направление ветра словом). Если кому надо... P. S. ветер, направление, облачность- подтягиваются сразу.

Погода.JPG

Wether with wind direction .7z

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites
7 часов назад, pasha413 сказал:

... очень удобны ...

тоже так считаю... и что там действительно +32МБ память..?!

Edited by EndWar

Share this post


Link to post
Share on other sites

Категорически всех приветствую.

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

  1. Поправлен порядок отображения сенсоров в web интерфейсе. Введена простая и понятная система нумерации в замен именованного списка. Датчики отображаются в обратном порядке их объявления. Систему можно легко переделать и инвертировать отображение, дайте знать если Вам будет это интересно.
  2. Хоть я и не смог воссоздать некоторые единичные проблемы с отправкой данных на внешние сервера (в частности mqtt) но все же были внесены некоторые правки в services.h. В частности, в функции mqttPublish и restAPIsend добавлена передача контроля системным задачам esp в список которых входит обработка сетевых соединений. Объект HTTPClient был перенесен в функцию restAPIsend, это спорный момент, родившийся в ходе борьбы с утечкой памяти в ESP8266 v2.4.1
  3. Запись в суточный журнал показаний сенсоров убрана из холодного старта планировщика задач. Это необходимо, чтобы датчики, использующие само калибровку, могли её произвести и в журнал пошли более адекватные показания. Также из-за этого при построении графика в web интерфейсе используется сдвиг на одну позицию меньше чем размер всего журнала (143 точки место 144) иначе временная шкала графика не будет соответствовать реальности со сдвигом в 10 минут.
  4. В файле tools.h был добавлен "Медианный фильтр", он нужен для уменьшения уровня шума в показаниях датчиков. По умолчанию фильтр использует 5 измерений и производит фильтрацию каждый раз при обновлении массива показаний. Сам фильтр объявляется как переменная типа medianFilter_t и работать с ней необходимо также как с любой переменной типа float - если необходимо добавить значение в фильтр, то используется оператор = или +=, а при обращении к переменной (при условии наполнения массива данных) на выходе получаем отфильтрованное значение. По сути medianFilter_t "мимикрирует" под тип float, претворяясь не тем, чем он есть на самом деле, для выполнения своих задач. Конечно этот термин не корректен, но это тестовый фильтр и мне хочется использовать именно это понятие в описании принципов его использования. Таким образом, чтобы задействовать фильтр в уже готовом проекте достаточно просто заменить тип у уже описанной переменной с float на medianFilter_t и это позволит избавиться от переписывания всего кода для реализации наполнения массива данных и последующей фильтрации. Просто работайте с ним как с обычной переменной.
  5. Исправлена проблема с обработкой заголовков Access-Control-Allow при отладке web интерфейса без загрузки файла index.htm на микроконтроллер. Теперь необходимо просто раскомментировать соответствующие строки в функции void http::sendServerHeaders() в файле webserver.h, а в index.htm изменить переменную var domain = ""; указав полный http адрес web сервера микроконтроллера (http://espws.local/ или http://192.168.0.15/ смотрите по обстоятельствам).
  6. В web интерфейсе в разделе "Настройка / Система" добавлен вывод внутреннего таймера millis в читаемом человеческом виде (дни и часы). Он понадобился мне для выявления багов в ходе построения графиков показаний, возможно он будет полезен и Вам.

И теперь самое главное, это проблема с кодировкой при обновлении программы микроконтроллера. Проблема проявляется при загрузке программы через web интерфейс. Я заметил, что проблема (лично у меня) проявляется только если после изменений в описании сенсоров, проект не был сохранен (Ctrl + S) и был произведен экспорт бинарного файла, который и был загружен в дальнейшем. Если перед экспортом сохранять проект, то проблема уходит. Понаблюдайте за этим моментом у себя, возможно это решение данной проблемы.

Еще раз напоминаю об утечки памяти в ESP8266 v2.4.1, используйте v2.4.0

Share this post


Link to post
Share on other sites
В 09.05.2018 в 23:44, Kitsum сказал:

Я заметил, что проблема (лично у меня) проявляется только если после изменений в описании сенсоров, проект не был сохранен (Ctrl + S) и был произведен экспорт бинарного файла, который и был загружен в дальнейшем. Если перед экспортом сохранять проект, то проблема уходит. Понаблюдайте за этим моментом у себя, возможно это решение данной проблемы.

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

Edited by EndWar
  • Thanks 1

Share this post


Link to post
Share on other sites

Установил крайнюю версию прошивки. Вроде всё работает, но проблема с передачей данных на MQTT осталась. Пришлось внести такие же изменения, как и в предыдущую версию.

Кстати, никто не прикручивал OLED дисплей 1306 к метеостанции?

Edited by Dark FeniX

Share this post


Link to post
Share on other sites
В 18.05.2018 в 16:07, doc_bravn сказал:

Можно ли его подключить к esp8266 и как его запустить?

Вам придется задействовать один из портов микроконтроллеров и настроить его на вход. На этот порт нужно подать сигнал с логического выхода электронного преобразователя, идущего в комплекте с "сенсором". Далее просто опрашиваете порт и делаете соответствующие выводы. Также можно снимать показания с АЦП выхода, но у ESP8266 только один АЦП, возможно его стоит оставить для чего-то более нужного.

Мое личное мнение, что данный сенсор не подойдет для адекватного детектирования осадков. Хотя бы по тому, что сенсору необходимо просохнуть для явного указания на конец осадков (дождя). В зимнее время года, как мне кажется, сенсор все время будет сигналить о наличии осадков т.к попросту покроется льдом. Возможно я ошибаюсь.

Думаю, что Вам стоит более пристально присмотреть к BME280 (температура + влажность + давление). Из показаний температуры и влажности можно вычислить так называемую "точку росы", по простому, это температура при которой влага в воздухе начинает конденсироваться. Если она совпадает с текущей температурой, то как минимум на улице туман или дождь, и уж точно не жаркий солнечный день. Если температуры приблизительно равны (плюс/минус погрешность), то смотрим на давление, если оно снизилось по сравнению с ранее собранными значениями (помним, что мы ведем суточный график) или опустилось ниже определенного уровня (возможно стоит вести учет среднесуточных значений для сенсоров) то считаем, что идет дождь. Возможно это сработает, в любом случае было бы интересно посмотреть на некоторую статистику.

В 18.05.2018 в 21:37, Dark FeniX сказал:

Вроде всё работает, но проблема с передачей данных на MQTT осталась.

Вы пробовали передавать на стоковой прошивке показания на другой сервер? Например на mqtt.it4it.club

В данный момент моя домашняя метеостанция использует последнюю опубликованную прошивку в стоковом варианте и передает показания на данный брокер, проблем с передачей нет. Также пробовал передавать показания на домашний брокер и на тестовый удаленный, все в норме. К сожалению, повторить вашу проблему не получается. Возможно причина в чем-то еще... пока сложно сказать.

Share this post


Link to post
Share on other sites
В 19.05.2018 в 22:51, Kitsum сказал:

Вы пробовали передавать на стоковой прошивке показания на другой сервер? Например на mqtt.it4it.club

В данный момент моя домашняя метеостанция использует последнюю опубликованную прошивку в стоковом варианте и передает показания на данный брокер, проблем с передачей нет. Также пробовал передавать показания на домашний брокер и на тестовый удаленный, все в норме. К сожалению, повторить вашу проблему не получается. Возможно причина в чем-то еще... пока сложно сказать.

В ближайшее время обязательно попробую передачу на другой брокер. А у вас сколько параметров передаётся? Потому что 3 и у меня передавалось, разрыв шел после третьего.

Share this post


Link to post
Share on other sites
В 19.05.2018 в 22:51, Kitsum сказал:

Вы пробовали передавать на стоковой прошивке показания на другой сервер? Например на mqtt.it4it.club

Попробовал. И ведь работает! Не пойму теперь, почему не работает с локальным москитто?

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

  • Similar Content

    • By Kitsum
      Хотите помочь проекту или спонсировать новый?
      Yandex.Money PayPal.me Тема проекта
      Arduino IDE + Project + Libraries + tools: https://yadi.sk/d/jseefFB50NMhAg
    • By Kitsum
      Просмотреть файл [esp8266] Библиотека CMD, реализует настройку микроконтроллера и управление вашей программой через терминал.
      Основная задача библиотеки, это прием пользовательских команд через UART интерфейс, их обработка и выполнение пользовательского кода, связанного с той или иной командой.
      Данная библиотека позволяет реализовать:
      Управление микроконтроллером Любую настройку, будь то WiFi, другие библиотеки или часть Вашей программы Вызывать Ваши задачи (функции) из терминала по команде и передавать им требуемые параметры Использовать контроллер в качестве шлюза между датчиками и программами на PC Внимание: любая команда, передаваемая в терминал обязана заканчиваться символом перевода строки "\n".
      Подключение библиотеки
      #include <cmd.h> Инициализация объекта, к которому мы будем обращаться для добавления команд. В качестве параметра объекту необходимо передать указатель на объект Serial или любой другой схожий по типу интерфейс.
      cmd command(&Serial); В функции Setup описываем какие команды требуется обрабатывать. Например, по команде "test" вызывать пользовательскую функцию с именем "myFunctionName". Имя пользовательской функции может быть абсолютно любым.
      void Setup() { Serial.begin(115200); command.add("test", myFunctionName); } Пользовательская функция будет вызываться каждый раз, когда по интерфейсу Serial поступит команда "test". Если команда будет передана с параметрами, то эти параметры будут переданы в качестве аргументов пользовательской функции.
      В функции loop должна находится команда вызова обработчика.
      void loop() { command.handleEvents(); } Пользовательская функция обязана соответствовать ряду требований:
      Не возвращать никакого результата (быть объявленной с типом void) Принимать в качестве первого аргумента переменную с типом byte в которой будет храниться число равное количеству переданных параметров Принимать в качестве второго параметра переменную с типом char** в которой будет храниться указатель на массив со всеми указателями (char*) на переданные параметры void myFunctionName(byte argc, char** argv) { /* ... */ } Функция всегда должна иметь такой вид, даже если не подразумевается, что ей будут передаваться какие-либо параметры.
      Чтобы перебрать все переданные параметры и вывести их в консоль, можно воспользоваться следующим примером
      void myFunctionName(byte argc, char** argv) { if (0 < argc) { for (uint8_t i = 0; i < argc; i++) { Serial.printf("%i. %s\n", i, argv[i]); } } } Пример вызова пользовательской функции без параметров и с ними
      # test No parameter was passed # test p1 p2 p3 p4 p5 0. p1 1. p2 2. p3 3. p4 4. p5 Помните, что параметры представлены в виде указателей и работать с ними нужно как с обычными переменными не получится т.к указатель содержит не значение переменной (переданный параметр), а указатель на ту область памяти микроконтроллера в которой это значение находится.
      Чтобы сравнить два значения, например, параметр под индексом 0 (идет первым в списке) с каким-либо значением в программе, воспользуйтесь функцией strcmp, которая возвращает целочисленное значение, указывающее на лексическое расхождение строк. Если строки равны, то возвращаемое значение равно 0.
      if (!strcmp(argv[0], "wifi")) { Serial.println(F("Первый аргумент WiFi")); } else { Serial.println(F("Первый аргумент НЕ WiFi!!!")); } Для копирования значения указателя в другую переменную с типом char можно воспользоваться функцией strcpy
      char myVar[20]; strcpy(myVar, argv[0]); if (myVar == "123456") { Serial.prinln(F("ok")); } Также можно обернуть указатель объектом String и получить весь функционал этого объекта, который будет содержать значение параметра
      String param1(argv[0]); // String param1 = argv[0]; Serial.printf("argv[0] length: %i\n", param1.length()); Serial.printf("argv[0] is integer?: %s\n", param1.toInt() ? "YES" : "NO"); if (param1 == "qwerty") { Serial.println(F("Hello QWERTY!")); } С библиотекой идут несколько примеров, в том числе и пример конфигурации WiFi в режиме STA.
      Автор Kitsum Добавлен 05.12.2018 Категория Библиотеки  
    • By Kitsum
      Просмотреть файл [esp8266] Библиотека smartBlink, реализует умное управление штатным светодиодом, что позволяет добавить индикацию состояния вашей программы или микроконтроллера.
      Основная задача библиотеки, это добавление индикации состояния Вашей программы или микроконтроллера. Отображение состояния производится посредством светодиода. Что самое важное, работа библиотеки через прерывание, это позволяет ей поддерживать индикацию даже в то время, когда выполняется длительный код основной программы. Например, Вы можете использовать её для отображения в каком режиме сейчас работает WiFi микроконтроллера, STA или AP и т.д. Или ход выполнения какой-либо операции, например, передача данных на внешний сервер.
      Подключение библиотеки
      #include <smartBlink.h> Чтобы инициализировать управление светодиодом необходимо создать объект, через который мы буем задавать режимы работы индикации.
      smartBlink::smartBlink(byte gpio, bool on = LOW); Объекту необходимо передать два параметра, первый это номер порта, на котором находится светодиод, а второй это уровень логического сигнала, который заставит светодиод работать. Сигнал может быть низким (LOW) или высоким (HIGH), это зависит от схемотехники подключения светодиода.
      Например, штатный светодиод модуля ESP12, использующий GPIO2 (порт 2) можно объявить следующим образом.
      #define led2_pin 2 #define led2_on_signal LOW smartBlink led2(led2_pin, led2_on_signal); Теперь можно в основной программе использовать метод устанавливающий какой режим индикации использовать.
      smartBlink::setMode(mode_t mode); Например, зададим режим светодиода led2 в котором светодиод будет давать одну короткую вспышку раз в секунду.
      led2.setMode(smartBlink::mode_flash1); Режимов работы может быть несколько.
      led2.setMode(smartBlink::mode_off); led2.setMode(smartBlink::mode_flash1); led2.setMode(smartBlink::mode_flash2); led2.setMode(smartBlink::mode_flash3); led2.setMode(smartBlink::mode_flash4); led2.setMode(smartBlink::mode_burn); led2.setMode(smartBlink::mode_inhalf); Чтобы вернуть предыдущий режим индикации для ранее объявленного светодиода led2 используйте следующий метод
      led2.previous(); Благодаря работе библиотеки через прерывания по таймеру, индикация будет работать даже в тех случаях, когда выполняется долгий код.
      С библиотекой идут несколько примеров.
      Автор Kitsum Добавлен 10.12.2018 Категория Библиотеки  
    • By Kitsum
      Основная задача библиотеки, это добавление индикации состояния Вашей программы или микроконтроллера. Отображение состояния производится посредством светодиода. Что самое важное, работа библиотеки через прерывание, это позволяет ей поддерживать индикацию даже в то время, когда выполняется длительный код основной программы. Например, Вы можете использовать её для отображения в каком режиме сейчас работает WiFi микроконтроллера, STA или AP и т.д. Или ход выполнения какой-либо операции, например, передача данных на внешний сервер.
      Подключение библиотеки
      #include <smartBlink.h> Чтобы инициализировать управление светодиодом необходимо создать объект, через который мы буем задавать режимы работы индикации.
      smartBlink::smartBlink(byte gpio, bool on = LOW); Объекту необходимо передать два параметра, первый это номер порта, на котором находится светодиод, а второй это уровень логического сигнала, который заставит светодиод работать. Сигнал может быть низким (LOW) или высоким (HIGH), это зависит от схемотехники подключения светодиода.
      Например, штатный светодиод модуля ESP12, использующий GPIO2 (порт 2) можно объявить следующим образом.
      #define led2_pin 2 #define led2_on_signal LOW smartBlink led2(led2_pin, led2_on_signal); Теперь можно в основной программе использовать метод устанавливающий какой режим индикации использовать.
      smartBlink::setMode(mode_t mode); Например, зададим режим светодиода led2 в котором светодиод будет давать одну короткую вспышку раз в секунду.
      led2.setMode(smartBlink::mode_flash1); Режимов работы может быть несколько.
      led2.setMode(smartBlink::mode_off); led2.setMode(smartBlink::mode_flash1); led2.setMode(smartBlink::mode_flash2); led2.setMode(smartBlink::mode_flash3); led2.setMode(smartBlink::mode_flash4); led2.setMode(smartBlink::mode_burn); led2.setMode(smartBlink::mode_inhalf); Чтобы вернуть предыдущий режим индикации для ранее объявленного светодиода led2 используйте следующий метод
      led2.previous(); Благодаря работе библиотеки через прерывания по таймеру, индикация будет работать даже в тех случаях, когда выполняется долгий код.
      С библиотекой идут несколько примеров.
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...