Перейти к публикации
iT4iT.CLUB

Dark FeniX

Пользователи
  • Публикации

    12
  • Зарегистрирован

  • Посещение

  • Дней в лидерах

    1

Сообщения, опубликованные пользователем Dark FeniX


  1. @Kitsum, огромное спасибо за помощь! Получилось, заработал экран, сделал всё согласно инструкции, расписано подробнее некуда.

    Конечно, мелковат экран у 1306, надо было брать больший, типа TFT 2.4". На этом помещаются всего 2 параметра, так, чтоб было заметно. Вывел показания температуру улицы и комнаты. Возможно, добавлю кнопку, переключать экраны с дополнительными показаниями. Но уже сейчас проект, по сути, готов, будка Стивенсона есть, осталось распечатать корпус и метеостанция готова!

    • Like 1

  2. Пытаюсь разобраться с подключением дисплея. Тут в теме уже описывалось такое тут вот только напрямую воспользоваться теми наработками не получается, несмотря на кажущуюся простоту. Сейчас программа разбита на части, даже представить не могу, в какую из них вставлять код. Понимаю, что это из-за банальной нехватки знаний, но всё же прошу помощи.

    В 16.01.2018 в 03:31, RusD сказал:

     

    
    #include "SSD1306.h" // добавил библиотеку
      
    // инициализация OLED-дисплея с помощью библиотеки Wire:
     SSD1306  display(0x3c, D2, D1);
    
    В void setup добавил
      
      display.init();
      display.flipScreenVertically();
      display.setFont(ArialMT_Plain_16);
      display.setTextAlignment(TEXT_ALIGN_LEFT);
    
    В void readSensors() изменил и добавил строки:
    
    /* BME280 */
    #ifdef TG_BME_280_I2C_H
        if (temperature.status) BME.read(pressure.data, temperature.data, humidity.data, BME280::TempUnit_Celsius, BME280::PresUnit_torr);
        display.clear();
        display.drawString(0, 0, "Temperature: " + String(temperature.data) + "C");
        display.drawString(0, 16, "Humidity: " + String(humidity.data) + "%\t");
        display.drawString(0, 32, "Pressure: " + String(pressure.data) + "mmHg");
      #endif
    
    И добавил в
      
    void loop() {
      
      display.display();

     

     

    Уточню, что не понял, куда можно вставить эту часть кода

    display.clear();
    display.drawString(0, 0, "Temperature: " + String(temperature.data) + "C");

     


  3. В 19.05.2018 в 22:51, Kitsum сказал:

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

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


  4. В 19.05.2018 в 22:51, Kitsum сказал:

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

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

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


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

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


  6. В 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

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


  7. В 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


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

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


  9. 15 минут назад, doc_bravn сказал:

    Кнопка это хорошо, но я говорил об одновременно отображении внешних и внутренних показаний. Допустим разделить экран на 2 части и подписать одну часть "Улица" и там отображать показания внешнего датчика, а вторую подписать "Квартира" и там отображать показания датчика в квартире. Так можно сделать?

    Думаю, да. Правкой html-кода. В теме были примеры, как добавляли самые разные датчики. Правда, без группировки, только датчики один за другим.


  10. 2 часа назад, doc_bravn сказал:

    Добавить разделение на внешний и внутренний датчики чтобы отображать как-то информацию с датчиков на улице и в квартире?

    Это есть и так, при использовании users_bme280_x2.h в интерфейсе появляется кнопка для переключения между показаниями датчиков.


  11. Доброго времени суток! Сперва, хочу поблагодарить автора за столь замечательный проект. На его основе я сейчас создаю свою домашнюю метеостанцию. Пока только собрана на макетке, но работоспособна уже на 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.

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

×
×
  • Создать...