Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ошибка при компиляции в ESPHome #13

Open
Igor-kr opened this issue Oct 10, 2020 · 17 comments
Open

Ошибка при компиляции в ESPHome #13

Igor-kr opened this issue Oct 10, 2020 · 17 comments

Comments

@Igor-kr
Copy link

Igor-kr commented Oct 10, 2020

Спасибо за библиотеку.
На Ардуино работает, хочу отправлять данные в HomeAssistant используя ESPHome но на первом этапе

при компиляции для ESP32 выдает ошибку:

/igor/Library/Arduino15/packages/esp32/hardware/esp32/1.0.4/variants/nodemcu-32s -I/Users/igor/Documents/Arduino/libraries/Oregon_NR /var/folders/ft/ghv3fbyd6_xbwrbg8k4pm2_r0000gn/T/arduino_build_527710/sketch/Receiver.ino.cpp -o /var/folders/ft/ghv3fbyd6_xbwrbg8k4pm2_r0000gn/T/arduino_build_527710/preproc/ctags_target_for_gcc_minus_e.cpp -DARDUINO_LIB_DISCOVERY_PHASE
Receiver:3:36: error: missing expression between '(' and ')'
#if defined ( ESP8266 ) || ( ESP32 )// Для Wemos
^
Используем библиотеку Oregon_NR версии 20.10.10 из папки: /Users/igor/Documents/Arduino/libraries/Oregon_NR
exit status 1
missing expression between '(' and ')'

@invandy
Copy link
Owner

invandy commented Oct 10, 2020

Скорее всего у вас не определено ESP8266 или ESP32
Попробуйте заменить на
#if defined ( ESP32 )
Если не поможет, можно попробовать убрать все предпроцессорные директивы и оставить только нужный конструктор.

@invandy
Copy link
Owner

invandy commented Oct 10, 2020

Заодно скачайте библиотеку заново, там как раз для ESP только что подправил скетч.

@Igor-kr
Copy link
Author

Igor-kr commented Oct 11, 2020

Здравствуйте,

#include <Oregon_NR.h>
#define ESP32
#if defined ( ESP8266 ) || ( ESP32 )// Для Wemos

выдает ошибку

#include <Oregon_NR.h>
#define ESP32
#if defined ( ESP32 ) || ( ESP8266 )// Для Wemos

компилируется в IDE Arduino и работает нормально

При попытке скомпилировать для ESPHOME

файл my_oregon.h

#include "esphome.h"
#include "Oregon_NR.h"
//Oregon_NR oregon(13, 13, 2, true);
class MyOregonSensor : public PollingComponent {
public:
Oregon_NR oregon(13,13,2,true);

// Oregon_NR oregon(13, 13, // приёмник на выводе D7 (GPIO13)
// 2, true, // Светодиод на D2 подтянут к +пит(true). Если светодиод не нужен, то номер вывода - 255
// 50, true); // Буфер на приём посылки из 50 ниблов, включена сборка пакетов для v2

Sensor *temperature_sensor = new Sensor();
Sensor *humidity_sensor = new Sensor();

MyOregonSensor() : PollingComponent(15000) { }

void setup() override {

oregon.start(); 

// oregon.receiver_dump = 0; //true - Включает "осциллограф" - отображение данных, полученных с приёмника
}

void update() override {
// This is the actual sensor reading logic.
float temperature = oregon.sens_tmp;
temperature_sensor->publish_state(temperature);

float humidity = oregon.sens_hmdty;
humidity_sensor->publish_state(humidity);

}
};

Компилятор ругается на конструктор класса

Dependency Graph
|-- 1.1.1
|-- 1.0
| |-- 1.0
|-- <Oregon_NR> 20.10.7
|-- 1.0
|-- 1.2.7
| |-- 1.1.1
| |-- 1.0
| |-- 1.0
|-- 1.1.0
| |-- 1.0
|-- 1.0
|-- 1.0
Compiling .pioenvs/oregon_rx/src/main.cpp.o
In file included from src/main.cpp:15:0:
src/my_oregon.h:6:20: error: expected identifier before numeric constant
Oregon_NR oregon(13, 13, 2, true);
^
src/my_oregon.h:6:20: error: expected ',' or '...' before numeric constant
In file included from src/main.cpp:15:0:
src/my_oregon.h: In member function 'virtual void MyOregonSensor::setup()':
src/my_oregon.h:19:5: error: '((MyOregonSensor*)this)->MyOregonSensor::oregon' does not have class type
oregon.start();
^
src/my_oregon.h: In member function 'virtual void MyOregonSensor::update()':
src/my_oregon.h:25:25: error: '((MyOregonSensor*)this)->MyOregonSensor::oregon' does not have class type
float temperature = oregon.sens_tmp;
^
src/my_oregon.h:28:22: error: '((MyOregonSensor*)this)->MyOregonSensor::oregon' does not have class type
float humidity = oregon.sens_hmdty;
^
src/main.cpp: In lambda function:
src/main.cpp:126:28: error: expected type-specifier before 'MyCustomSensor'
auto my_sensor = new MyCustomSensor();
^
src/main.cpp:128:72: error: could not convert '{, }' from '' to 'std::vectoresphome::sensor::Sensor*'
return {my_sensor->temperature_sensor, my_sensor->humidity_sensor};
^
Compiling .pioenvs/oregon_rx/FrameworkArduino/FunctionalInterrupt.cpp.o
Compiling .pioenvs/oregon_rx/FrameworkArduino/HardwareSerial.cpp.o
*** [.pioenvs/oregon_rx/src/main.cpp.o] Error 1
Compiling .pioenvs/oregon_rx/FrameworkArduino/IPAddress.cpp.o
========================= [FAILED] Took 150.17 seconds =========================

@invandy
Copy link
Owner

invandy commented Oct 11, 2020

Так я не понял? В Arduino IDE пример с приёмником под ESP32 тоже не компилируется?

@Igor-kr
Copy link
Author

Igor-kr commented Oct 11, 2020

В Arduino IDE компилируется без ошибок и принимает данные (вижу в мониторе порта).

Когда пытаюсь использовать вашу библиотеку,
создаю Custom Sensor для EspHome и объявляю класс
Как здесь описано

https://esphome.io/components/sensor/custom.html

public:
Oregon_NR oregon(13,13,2,true);

Компилятор , они используют PlatformIO ругается на это (13,13,2,true);

Compiling .pioenvs/oregon_rx/src/main.cpp.o
In file included from src/main.cpp:15:0:
src/my_oregon.h:6:20: error: expected identifier before numeric constant
Oregon_NR oregon(13, 13, 2, true);
^
src/my_oregon.h:6:20: error: expected ',' or '...' before numeric constant


In file included from src/main.cpp:15:0:
src/my_oregon.h: In member function 'virtual void MyOregonSensor::setup()':
src/my_oregon.h:19:5: error: '((MyOregonSensor*)this)->MyOregonSensor::oregon' does not have class type
oregon.start();
^

Вот мой заголовочный файл для ESPHOME

#include "esphome.h"
#include "Oregon_NR.h"

class MyOregonSensor : public PollingComponent {
 public:
 
  Oregon_NR oregon(13,13,2,true);

  Sensor *temperature_sensor = new Sensor();
  Sensor *humidity_sensor = new Sensor();

  MyOregonSensor() : PollingComponent(15000) { }

  void setup() override {
    
    oregon.start(); 
//    oregon.receiver_dump = 0;       //true - Включает "осциллограф" - отображение данных, полученных с приёмника
  }

  void update() override {
    // This is the actual sensor reading logic.
    float temperature = oregon.sens_tmp;
    temperature_sensor->publish_state(temperature);

    float humidity = oregon.sens_hmdty;
    humidity_sensor->publish_state(humidity);
  }
};

esphome:
  name: oregon_rx
  platform: ESP32
  board: nodemcu-32s
  includes:
    - "my_oregon.h"
  libraries:
    - "https://github.com/invandy/Oregon_NR.git"  
  

wifi:
  ssid: secret
  password: secret

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: secret
    password: secret

captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

# Example configuration entry
sensor:
- platform: custom
  lambda: |-
    auto my_sensor = new MyOregonSensor();
    App.register_component(my_sensor);
    return {my_sensor->temperature_sensor, my_sensor->humidity_sensor};

  sensors:
  - name: "My Custom Temperature Sensor"
    unit_of_measurement: °C
    accuracy_decimals: 1
  - name: "My Custom Humidity Sensor"
    unit_of_measurement: "%"
    accuracy_decimals: 1

Может быть как то по другому можно инициализировать класс?
Извиняюсь за глупые вопросы но не програмист я :)

@invandy
Copy link
Owner

invandy commented Oct 11, 2020

Так вот сходу не скажу, как решить ваш вопрос, надо же тщательно разобраться в вашей инструкции по подключению

@invandy
Copy link
Owner

invandy commented Oct 11, 2020

#include "esphome.h"
#include "Oregon_NR.h"

class MyOregonSensor  : public Component, public Sensor 
{
  public:
   Oregon_NR oregon{13,13,2,true};
   Sensor *temperature_sensor = new Sensor();
   Sensor *humidity_sensor = new Sensor();

   void setup() override {oregon.start();}

   void loop() override 
   {
     oregon.capture(0);
     if (oregon.captured) 
     {
      temperature_sensor -> publish_state(oregon.sens_tmp);
      humidity_sensor -> publish_state(oregon.sens_hmdty);
     }
   }
};

@Igor-kr
Copy link
Author

Igor-kr commented Oct 12, 2020

Спасибо ! Все с компилировалось, вечером проверю с реальными датчиками.

@invandy
Copy link
Owner

invandy commented Oct 12, 2020

Тут вот ещё что хотелось отметить.

  1. Концептуально вы немого неверно пытаетесь зарегистрировать датчик в системе. Дело в том, что вы регистрируете канал данных, по которому можно получать информацию от целого комплекса датчиков., поэтому, для регистрации одного датчика надо делать вот так:

if (oregon.captured && oregon.sens_type == THGN132) { temperature_sensor -> publish_state(oregon.sens_tmp); humidity_sensor -> publish_state(oregon.sens_hmdty); }

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

@invandy invandy changed the title Ошибка при колпиляции ESP 32 Ошибка при колпиляции в ESPHome Oct 12, 2020
@Igor-kr
Copy link
Author

Igor-kr commented Oct 13, 2020

Добрый день,

Вобщем этот код почти заработал

#include "esphome.h"
#include "Oregon_NR.h"

class MyOregonSensor : public Component, public Sensor 
{
public:
Oregon_NR oregon{13,13,2,true};
Sensor *temperature_sensor = new Sensor();
Sensor *humidity_sensor = new Sensor();
Sensor *battery_sensor = new Sensor();

void setup() override 
{
//вкючение прослушивания радиоканала  
  oregon.start(); 
}
void loop() override
{
  oregon.capture(0); // 1 - выводить в Serial сервисную информацию
 
  if (oregon.captured && oregon.sens_type == THGN132)  {
  temperature_sensor -> publish_state(oregon.sens_tmp); 
  humidity_sensor -> publish_state(oregon.sens_hmdty);
  battery_sensor -> publish_state(oregon.sens_battery);
  };
yield();  
}
};

Компилируется, в мониторе USB вижу


[redacted]▂▄▆█
[10:41:21][W][wifi:394]: No matching network found!
[10:41:21][D][sensor:092]: 'My Custom Temperature Sensor': Sending state 23.30000 °C with 1 decimals of accuracy
[10:41:21][D][sensor:092]: 'My Custom Humidity Sensor': Sending state 13.00000 % with 1 decimals of accuracy
[10:41:21][D][sensor:092]: 'Battery': Sending state 1.00000  with 0 decimals of accuracy
[10:41:26][D][wifi:324]: Starting scan...
[10:41:28][D][wifi:339]: Found networks:


даже выводит результаты на OLED дисплей, но ровно до того момента пока нет подключения к WiFi сети.
Как только соединение установлено, прием прекращается,
Видимо какая то не совместимость с WiFi билиотекой от EspHome.

Кстати когда создаешь новый проект при первой компиляции ругается на ошибки:

.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp:1622:25: warning: extra tokens at end of #ifdef directive
 #ifdef ADD_SENS_SUPPORT == 1
                         ^
In file included from .piolibdeps/oregon_rx/Oregon_NR/Oregon_TM.cpp:1:0:
.piolibdeps/oregon_rx/Oregon_NR/Oregon_TM.h:49:11: warning: ISO C++11 requires whitespace after the macro name
 #define THТ800    0xС844
           ^
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp: In member function 'void Oregon_NR::get_tacts(byte*, int)':
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp:710:10: warning: value computed is not used [-Wunused-value]
    *cdp++;
          ^
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp:730:12: warning: value computed is not used [-Wunused-value]
      *cdp++;
            ^
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp:813:10: warning: value computed is not used [-Wunused-value]
    *cdp++;
          ^
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp:826:10: warning: value computed is not used [-Wunused-value]
    *cdp++;
          ^
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp:867:12: warning: value computed is not used [-Wunused-value]
      *cdp++;
            ^
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp: In member function 'int Oregon_NR::get_info_data(byte*, byte*, byte*)':
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp:1255:11: warning: suggest parentheses around comparison in operand of '&' [-Wparentheses]
   if (ver == 2 & csm > 22) return 0; 
           ^
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp:1257:11: warning: suggest parentheses around comparison in operand of '&' [-Wparentheses]
   if (ver == 3 & csm > 30) return 0; 
           ^
Archiving .pioenvs/oregon_rx/libd94/libWiFi.a
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp: In member function 'int Oregon_NR::get_data(int, byte, byte*)':
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp:1001:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp: In member function 'float Oregon_NR::get_temperature(byte*)':
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp:1323:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
Indexing .pioenvs/oregon_rx/libd94/libWiFi.a
.piolibdeps/oregon_rx/Oregon_NR/Oregon_TM.cpp: In member function 'void Oregon_TM::setChannel(byte)':
.piolibdeps/oregon_rx/Oregon_NR/Oregon_TM.cpp:527:43: warning: 'channel_code' may be used uninitialized in this function [-Wmaybe-uninitialized]
       SendBuffer[2] += channel_code & 0xF0;
                                           ^
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp: In member function 'int Oregon_NR::get_info_data(byte*, byte*, byte*)':
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp:1278:37: warning: 'multipl' may be used uninitialized in this function [-Wmaybe-uninitialized]
     if (*code < 128 ) *vd += multipl;
                                     ^
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp: In member function 'float Oregon_NR::get_temperature(byte*)':
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp:1317:34: warning: 'tmprt' may be used uninitialized in this function [-Wmaybe-uninitialized]
     tmprt += *(oregon_data) * 0.1;
                                  ^
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp: In member function 'float Oregon_NR::get_rain_rate()':
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp:1547:34: warning: 'tmprt' may be used uninitialized in this function [-Wmaybe-uninitialized]
     tmprt += *(packet + 8) * 1000;
                                  ^
Compiling .pioenvs/oregon_rx/lib1e0/FS/FS.cpp.o
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp: In member function 'void Oregon_NR::capture(bool)':
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp:480:46: warning: 'secresingV' may be used uninitialized in this function [-Wmaybe-uninitialized]
       for (int www = 0; www < (packet_length - secresingV + 2); www++)
                                              ^
.piolibdeps/oregon_rx/Oregon_NR/Oregon_NR.cpp:471:22: warning: 'result_data' may be used uninitialized in this function [-Wmaybe-uninitialized]
     if (get_info_data(result_data, packet, valid_p))
                      ^

Не знаю имеет это значение или нет.

@invandy
Copy link
Owner

invandy commented Oct 13, 2020

Предупреждения компилятора по возможности подправлю в следующей версии. Не критично, но аккуратность прежде всего :)
Потерю связи можно объяснить двумя причинами:

  1. Помехи. ESP и без того шумный проц, а с включённым вайфаем может давать много шума в широком диапазоне частот. Я бы отнёс приёмник с антенной от ESP подальше.
  2. Как я и говорил, ESP может быть в вашем случае сильно нагружен и у него просто нет времени, чтобы вовремя отслеживать сигнал с приёмника. Решение тут одно - ставить отдельный микроконтроллер для радиоприёмника, чтобы он занимался ловлей пакетов и их буферизацией.

@Igor-kr
Copy link
Author

Igor-kr commented Oct 14, 2020

Добрый день, спасибо за помощь!
Вчера проверил - приемник на проводах отодвинул метра на 2 результат тот же. Видимо ЕСП шке не хватает времени обработать все правильно когда WiFi включен. Отрицательный результат - тоже результат!
Решил принимать на Ардуину и по serial закину в HomeAssistant

   StaticJsonDocument<100> jsonBuffer;

  jsonBuffer["temperature"] = oregon.sens_tmp;
  jsonBuffer["humidity"] = oregon.sens_hmdty;
  jsonBuffer["battery"] = oregon.sens_battery;

  serializeJson(jsonBuffer, Serial);
  Serial.println();   

Должно сработать.

Попутно возник вопрос можно ли при помощи вашей библиотеки принять и декодировать синалы от этого устройства:

https://github.com/JackKelly/rfm_edf_ecomanager/wiki/Technical-details-of-Current-Cost-RF-protocol

Было бы здорово!

@invandy
Copy link
Owner

invandy commented Oct 14, 2020

Попутно возник вопрос можно ли при помощи вашей библиотеки принять и декодировать синалы от этого устройства:

https://github.com/JackKelly/rfm_edf_ecomanager/wiki/Technical-details-of-Current-Cost-RF-protocol

Ну, если вы найдёте подходящий приёмник с FSK модуляцией, то теоретически можно. Но надо будет с нуля писать декодировщик

@invandy invandy changed the title Ошибка при колпиляции в ESPHome Ошибка при компиляции в ESPHome Oct 14, 2020
@macros0
Copy link

macros0 commented Dec 1, 2020

Вчера проверил - приемник на проводах отодвинул метра на 2 результат тот же. Видимо ЕСП шке не хватает времени обработать все правильно когда WiFi включен. Отрицательный результат - тоже результат!

Но ведь на esp8266 у меня работает передача в https://blynk.io/
не ужели на столько проседает производительность из-за интеграции с HA?
Просто метод loop() вызывается 60 раз в секунду, и публиковать значение в нем нельзя!

Мне кажется нужно использовать:

  1. PollingComponent вместо Component
  2. в методе loop() оставить только oregon.capture(0);
  3. в методе update():
    if (oregon.captured && oregon.sens_type == THGN132) {
    temperature_sensor -> publish_state(oregon.sens_tmp);
    humidity_sensor -> publish_state(oregon.sens_hmdty);
    battery_sensor -> publish_state(oregon.sens_battery);
    };

наверное в п.2 лучше сохранять в переменные (обернув проверками (oregon.captured) и (oregon.crc_c)) и в п.3 выводить уже переменные

@eagle23
Copy link

eagle23 commented Feb 3, 2021

Если кому еще интересно данный вопрос. То вот мои изыскания ))
Никак не мог заставить работать связку esp8266 + ESPHome + Oregon_NR
В итоге выяснил, что задержка в методе loop равна 16ms, что для библиотеки Oregon_NS очень высока.
Понизив ее, мы заставим работать обе библиотеки работать как надо.
Тут приходит на помощь два варианта:
Добавить в метод setup своего компонента строчку:
App.set_loop_interval(1);

Либо сделать так, как предлагают в комментарий исходного кода (в документации этого не нашел):

  • Each component can request a high frequency loop execution by using the HighFrequencyLoopRequester
  • helper in helpers.h

https://github.com/esphome/esphome/blob/5c86f332b269fd3e4bffcbdf3359a021419effdd/esphome/core/application.h#L111

Добавляем HighFrequencyLoopRequester и стартуем в его в setup
В итоге мой компонент выглядит так:

#include "esphome.h"
#include "Oregon_NR.h"

static char const *TAG = "custom.oregon";

class MyOregonSensor : public Component, public Sensor
{
public:
    Oregon_NR oregon = Oregon_NR{14, 14, 2, true};
    HighFrequencyLoopRequester high_freq_;

    Sensor *temperature_sensor = new Sensor();
    Sensor *humidity_sensor = new Sensor();
    Sensor *battery_sensor = new Sensor();

    float get_setup_priority() const override { return esphome::setup_priority::LATE; }

    void setup() override
    {
        // App.set_loop_interval(1); // так тоже работает
        this->high_freq_.start();
        ESP_LOGD(TAG, "SETUP OREGON SENSOR");
        oregon.start();
    }

    void loop() override
    {
        oregon.capture(0); // 1 - выводить в Serial сервисную информацию

        if (oregon.captured && oregon.crc_c)
        {
            ESP_LOGD(TAG, "OREGON SENSOR CAPTURED");

            temperature_sensor->publish_state(oregon.sens_tmp);
            humidity_sensor->publish_state(oregon.sens_hmdty);
            battery_sensor->publish_state(oregon.sens_battery);
        }

        yield();
    }
};

После чего у меня все заработало.

@invandy
Copy link
Owner

invandy commented Feb 3, 2021

Это, ИМХО, работоспособное, но не идеальное решение. При наличии большого количества разношёрстных датчиков в системе времени на прослушивание радиоэфира будет оставаться всё меньше и меньше, что приведёт к пропускам пакетов от радиодатчиков. Они же не по запросу данные выдают, а по таймеру. Тут нужно уже либо реализовывать тайм-слоты и слушать радиоэфир в нужные моменты времени, либо решать вопрос аппаратно, как я предлагал раньше.

@eagle23
Copy link

eagle23 commented Feb 3, 2021

К сожалению, мои познания в c++ очень скромны, поэтому довольствуюсь, тем что есть )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants