xoseperez / espurna

Home automation firmware for ESP8266-based devices
http://tinkerman.cat
GNU General Public License v3.0
3k stars 638 forks source link

Linking error (static members) in AnalogSensor.h #2624

Open JavierAder opened 2 days ago

JavierAder commented 2 days ago

Device

Lolin

Version

1.18

Bug description

Hello. I wrote a subclass of NTCSensor and when compiling the linker it throws an error:

Linking .pio\build\nodemcu-lolin-analog-mux\firmware.elf
c:/users/javier/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio/build/nodemcu-lolin-analog-mux/src/sensor.cpp.o:C:\Users\Javier\Documents\PlatformIO\Projects\espurna-1.18.0\code/espurna\sensors/AnalogMux.h:37: undefined reference to `AnalogSensor::SamplesMin'
c:/users/javier/.platformio/packages/toolchain-xtensa/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: .pio/build/nodemcu-lolin-analog-mux/src/sensor.cpp.o:C:\Users\Javier\Documents\PlatformIO\Projects\espurna-1.18.0\code/espurna\sensors/AnalogMux.h:37: undefined reference to `AnalogSensor::SamplesMax'
collect2.exe: error: ld returned 1 exit status

This doesn't happen if you build a project that uses NTCSensor, but it does if you use a subclass of it (I have no idea why). The solution I found was to add these two lines to the end of AnalogSensor.h

constexpr size_t AnalogSensor::SamplesMin; 
constexpr size_t AnalogSensor::SamplesMax;

Best regards

Steps to reproduce

No response

Build tools used

No response

Any relevant log output (when available)

No response

Decoded stack trace (when available)

No response

JavierAder commented 2 days ago

Probably add also constexpr int AnalogSensor::RawBits; is necessary; my actual NTCSensor subclass is reporting SENSOR_ERROR_OVERFLOW, which is set in NTCSensor::pre() and use RawMax const double voltage = static_cast(_rawRead()) / AnalogSensor::RawMax; and RawMax is defined using RawBits in AnalogSensor static constexpr double RawMax { (1 << RawBits) - 1 }; Probably RawMax is getting a random value

JavierAder commented 1 day ago

Probably add also constexpr int AnalogSensor::RawBits; is necessary; my actual NTCSensor subclass is reporting SENSOR_ERROR_OVERFLOW, which is set in NTCSensor::pre() and use RawMax const double voltage = static_cast(_rawRead()) / AnalogSensor::RawMax; and RawMax is defined using RawBits in AnalogSensor static constexpr double RawMax { (1 << RawBits) - 1 }; Probably RawMax is getting a random value

No, surely SENSOR_ERROR_OVERFLOW occurs because readAnalog is returning 65535 instead of 1023. In the debug terminal:

adc 
value 65535
+OK
[319002] [SENSOR] Could not read from NTCMux 0 3.30 - Value Overflow
adc 0
value 65535
+OK

I don't know if it's another bug or my error in the configuration; It seems that my Lolin is starting with the ADC in "Measure the power supply voltage of VDD3P3 (Pin3 and Pin4" mode, although I am not totally sure. In any case, the latter is independent of the linking error. Why analogRead(0) is returning 65535?

mcspr commented 1 day ago

re. static constexpr declaration / definition outside the class - just a language implementation oddity due to older GCC version and -std=c++11. It is a bug that AnalogSensor.h does not have those two, though. edit: -std=c++17 and latter makes these redundant, so building w/ -latest or -git envs would work even without the extra definition lines. per https://en.cppreference.com/w/cpp/language/inline#Notes __cpp_inline_variables is the feature-flag to check for non-compatible environments

re. ADC, I would guess it is due to this not being picked up in the config code/espurna/config/sensors.h https://github.com/xoseperez/espurna/blob/dc9ba63295833d34a29d4b72ef956ee8401f0aab/code/espurna/config/sensors.h#L1529