adcsensor: make BridgeGpio setup time configurable
On some voltage-monitoring lines there may be enough capacitance that
the hard-coded 20ms enable time is insufficient to allow the signal to
fully stabilize (a case in point being the battery voltage line on the
ASRock Rack E3C246D4I), leading to inaccurate readings. It would be
unfortunate to penalize all systems and make them unconditionally wait
longer by simply upping the global enable time, however, so instead we
allow it to be configured as an additional BridgeGpio parameter
"SetupTime", the (float) number of seconds to wait after enabling the
bridge GPIO before sampling the sensor. (The default setup time if
unspecified remains 20ms.)
Tested: with a corresponding entity-manager configuration adjustment to
add a longer SetupTime setting, achieved much more accurate battery
voltage readings on E3C246D4I.
Signed-off-by: Zev Weiss <zweiss@equinix.com>
Change-Id: I17f0ffa603fbbaa3bf929502bbdf02394719b3a4
diff --git a/include/ADCSensor.hpp b/include/ADCSensor.hpp
index 9ba0060..9e58139 100644
--- a/include/ADCSensor.hpp
+++ b/include/ADCSensor.hpp
@@ -15,7 +15,9 @@
class BridgeGpio
{
public:
- BridgeGpio(const std::string& name, const int polarity)
+ BridgeGpio(const std::string& name, const int polarity,
+ const float setupTime) :
+ setupTimeMs(static_cast<unsigned int>(setupTime * 1000))
{
line = gpiod::find_line(name);
if (!line)
@@ -54,6 +56,8 @@
}
}
+ unsigned int setupTimeMs;
+
private:
gpiod::line line;
};
diff --git a/src/ADCSensor.cpp b/src/ADCSensor.cpp
index e77261a..5abee29 100644
--- a/src/ADCSensor.cpp
+++ b/src/ADCSensor.cpp
@@ -35,7 +35,6 @@
#include <vector>
static constexpr size_t warnAfterErrorCount = 10;
-static constexpr unsigned int gpioBridgeEnableMs = 20;
// scaling factor from hwmon
static constexpr unsigned int sensorScaleFactor = 1000;
@@ -110,7 +109,7 @@
// value. Guarantee that the HW signal can be stable, the HW signal
// could be instability.
waitTimer.expires_from_now(
- boost::posix_time::milliseconds(gpioBridgeEnableMs));
+ boost::posix_time::milliseconds(bridgeGpio->setupTimeMs));
waitTimer.async_wait(
[weakRef, buffer](const boost::system::error_code& ec) {
std::shared_ptr<ADCSensor> self = weakRef.lock();
diff --git a/src/ADCSensorMain.cpp b/src/ADCSensorMain.cpp
index 9d29895..4f35a7f 100644
--- a/src/ADCSensorMain.cpp
+++ b/src/ADCSensorMain.cpp
@@ -37,6 +37,7 @@
static constexpr bool debug = false;
static constexpr float pollRateDefault = 0.5;
+static constexpr float gpioBridgeSetupTimeDefault = 0.02;
namespace fs = std::filesystem;
@@ -281,7 +282,18 @@
polarity = gpiod::line::ACTIVE_LOW;
}
}
- bridgeGpio = BridgeGpio(gpioName, polarity);
+
+ float setupTime = gpioBridgeSetupTimeDefault;
+ auto findSetupTime =
+ suppConfig.second.find("SetupTime");
+ if (findSetupTime != suppConfig.second.end())
+ {
+ setupTime = std::visit(VariantToFloatVisitor(),
+ findSetupTime->second);
+ }
+
+ bridgeGpio =
+ BridgeGpio(gpioName, polarity, setupTime);
}
break;