[1Wire] Fix not always showing 1-wire sensor & correct saving sensor

Fixes: #5309
This commit is contained in:
TD-er committed 2026-09-16 13:47:48 +02:00
1 parent 8ccd7d13e8
commit e329922abd
7 files changed
+199 -102

No files matched your search

+22 -2
View File
@@ -41,6 +41,20 @@ ValueStruct ValueStruct::makeHexFormatted(uint64_t val, uint8_t minNrDigits)
return res;
}
ValueStruct ValueStruct::makeHexDecimalFormatted(uint64_t val,
uint8_t minNrDigits)
{
ValueStruct res(val);
// TODO TD-er: Add factor option for decimal formatted, like in String formatToHex_decimal(uint32_t value, uint32_t factor)
// Or maybe just a flag to make it 'human readable' and maybe whether the factor should be 1000 or 1024.
res.setPreferredFormat(PreferredFormat::Hex_Dec);
res.setMinNrDigits(minNrDigits);
res.setCaseFormat(CaseFormat::ToUpper);
return res;
}
ValueStruct ValueStruct::makeBinFormatted(uint64_t val, uint8_t minNrDigits)
{
ValueStruct res(val);
@@ -685,8 +699,14 @@ size_t ValueStruct::print(Print& out, ValueType& valueType, bool unformatted) co
return out.print(concat(F("0b"), ull2String(u64_val, BIN, _minNrDigits)));
}
if (format == PreferredFormat::Hex) {
return out.print(concat(F("0x"), ull2String(u64_val, HEX, _minNrDigits, '\0', getCaseFormat(unformatted) == CaseFormat::ToUpper)));
if ((format == PreferredFormat::Hex) || (format == PreferredFormat::Hex_Dec)) {
String str = concat(F("0x"), ull2String(u64_val, HEX, _minNrDigits, '\0', getCaseFormat(unformatted) == CaseFormat::ToUpper));
if (format == PreferredFormat::Hex_Dec) {
// Old implementation: formatToHex_decimal
str += strformat(F(" (%s)"), ull2String(u64_val, DEC /*, _minNrDigits*/).c_str());
}
return out.print(std::move(str));
}
if ((_size > 32) || _minNrDigits) {
+6 -2
View File
@@ -46,7 +46,8 @@ public:
enum class PreferredFormat : uint8_t {
Default = 0,
Bin,
Hex
Hex,
Hex_Dec // for example: "0x1234 (4660)"
};
@@ -103,6 +104,8 @@ public:
static ValueStruct makeHexFormatted(uint64_t val,
uint8_t minNrDigits);
static ValueStruct makeHexDecimalFormatted(uint64_t val,
uint8_t minNrDigits);
static ValueStruct makeBinFormatted(uint64_t val,
uint8_t minNrDigits);
@@ -118,7 +121,8 @@ public:
void setInt(size_t val);
#endif
void setIPAddress(const IPAddress& ip, bool includeZone = false);
void setIPAddress(const IPAddress& ip,
bool includeZone = false);
ValueStruct::ValueType getValueType() const
{
+104 -89
View File
@@ -34,6 +34,12 @@
# endif // ifdef ESP32
# ifndef DALLAS_RESET_RETRIES
// Reset may fail if a
# define DALLAS_RESET_RETRIES 3
# endif // ifndef DALLAS_RESET_RETRIES
# include <vector>
unsigned char ROM_NO[8]{ 0 };
@@ -45,7 +51,6 @@ int32_t usec_release{};
int32_t presence_start{};
int32_t presence_end{};
void DALLAS_IRAM_ATTR Dallas_pinModeInput(uint32_t gpio_pin_rx, uint32_t gpio_pin_tx)
{
if (gpio_pin_rx == gpio_pin_tx) {
@@ -132,7 +137,8 @@ int Dallas_measure_rise_time(int8_t gpio_pin_rx, int8_t gpio_pin_tx)
// http://owfs.sourceforge.net/simple_family.html
// https://github.com/owfs/owfs-doc/wiki/1Wire-Device-List
const __FlashStringHelper* Dallas_getModel(uint8_t family, const bool hasFixedResolution) {
switch (family) {
switch (family)
{
case 0x28: return F("DS18B20");
case 0x3b: return hasFixedResolution ? F("MAX31826") : F("DS1825");
case 0x22: return F("DS1822");
@@ -271,13 +277,14 @@ void Dallas_addr_selector_webform_load(taskIndex_t TaskIndex, int8_t gpio_pin_rx
}
const bool selected = (memcmp(tmpAddress, savedAddress, 8) == 0);
addSelector_Item(option, index, selected);
addSelector_Item_index64(option, scan_res[index], selected);
}
addSelector_Foot();
}
}
# ifndef LIMIT_BUILD_SIZE
void Dallas_show_sensor_stats_webform_load(const Dallas_SensorData& sensor_data)
{
if (sensor_data.addr == 0) {
@@ -338,10 +345,10 @@ void Dallas_addr_selector_webform_save(taskIndex_t TaskIndex, int8_t gpio_pin_rx
uint8_t addr[8]{};
for (uint8_t var_index = 0; var_index < nrVariables; ++var_index) {
const int selection = getFormItemInt(concat(F("dallas_addr"), static_cast<int>(var_index)), -1);
const uint64_t selection = getFormItemUInt64(concat(F("dallas_addr"), static_cast<int>(var_index)), 0);
if (selection != -1) {
Dallas_scan(selection, addr, gpio_pin_rx, gpio_pin_tx);
if (selection != 0) {
Dallas_uint64_to_addr(selection, addr);
Dallas_plugin_set_addr(addr, TaskIndex, var_index);
}
}
@@ -411,6 +418,7 @@ uint8_t Dallas_scan(uint8_t getDeviceROM, uint8_t *ROM, int8_t gpio_pin_rx, int8
// read power supply
# ifndef LIMIT_BUILD_SIZE
bool Dallas_is_parasite(const uint8_t ROM[8], int8_t gpio_pin_rx, int8_t gpio_pin_tx, bool& isParasitePowered)
{
if (!Dallas_address_ROM(ROM, gpio_pin_rx, gpio_pin_tx)) {
@@ -435,6 +443,7 @@ bool Dallas_is_parasite(const uint8_t ROM[8], int8_t gpio_pin_rx, int8_t gpio_pi
Dallas_write(0x44, gpio_pin_rx, gpio_pin_tx);
}
*/
/*********************************************************************************************\
* Dallas Read temperature from scratchpad
\*********************************************************************************************/
@@ -535,6 +544,7 @@ Dallas_read_result Dallas_readTemp(const uint8_t ROM[8], float *value, int8_t gp
}
# ifdef USES_P080
bool Dallas_readiButton(const uint8_t addr[8], int8_t gpio_pin_rx, int8_t gpio_pin_tx, int8_t lastState)
{
// maybe this is needed to trigger the reading
@@ -783,113 +793,117 @@ bool Dallas_setResolution(const uint8_t ROM[8], uint8_t res, int8_t gpio_pin_rx,
\*********************************************************************************************/
uint8_t Dallas_reset(int8_t gpio_pin_rx, int8_t gpio_pin_tx)
{
presence_start = 0;
presence_end = 0;
for (uint8_t attempt = 0; attempt < DALLAS_RESET_RETRIES; ++attempt) {
presence_start = 0;
presence_end = 0;
// Keep track of usec_release as it is an indicator for the recovery time
usec_release = Dallas_measure_rise_time(gpio_pin_rx, gpio_pin_tx);
delayMicroseconds(10);
// Keep track of usec_release as it is an indicator for the recovery time
// Only call ISR_noInterrupts(); after this Dallas_measure_rise_time as it also disables interrupts.
usec_release = Dallas_measure_rise_time(gpio_pin_rx, gpio_pin_tx);
delayMicroseconds(10);
ISR_noInterrupts();
ISR_noInterrupts();
# ifdef DEBUG_LOGIC_ANALYZER_PIN
// DEBUG code using logic analyzer for timings
DIRECT_pinWrite(DEBUG_LOGIC_ANALYZER_PIN, 1);
# endif // ifdef DEBUG_LOGIC_ANALYZER_PIN
Dallas_pinInput;
# ifdef DEBUG_LOGIC_ANALYZER_PIN
// DEBUG code using logic analyzer for timings
DIRECT_pinWrite(DEBUG_LOGIC_ANALYZER_PIN, 0);
# endif // ifdef DEBUG_LOGIC_ANALYZER_PIN
// wait until the wire is high... just in case
if (Dallas_waitForPinHigh(gpio_pin_rx, micros(), 250)) {
# ifdef DEBUG_LOGIC_ANALYZER_PIN
// DEBUG code using logic analyzer for timings
DIRECT_pinWrite(DEBUG_LOGIC_ANALYZER_PIN, 1);
# endif // ifdef DEBUG_LOGIC_ANALYZER_PIN
// The master starts a transmission with a reset pulse,
// which pulls the wire to 0 volts for at least 480 µs.
// This resets communication of every slave device on the bus.
Dallas_pinLow;
delayMicroseconds(480); // t_RSTL 480 ... 960 usec
// puling pin high will be very fast, so start measurement before pulling high
const uint32_t start = micros();
Dallas_pinHigh;
// digitalWrite(gpio_pin_tx, 1);
delayMicroseconds(1);
// Set to 'input', state will be pulled high by pull-up resistor
// Or will be kept pulled low by sensor
Dallas_pinInput;
{
Dallas_pinInput;
# ifdef DEBUG_LOGIC_ANALYZER_PIN
// DEBUG code using logic analyzer for timings
DIRECT_pinWrite(DEBUG_LOGIC_ANALYZER_PIN, 0);
// DEBUG code using logic analyzer for timings
DIRECT_pinWrite(DEBUG_LOGIC_ANALYZER_PIN, 0);
# endif // ifdef DEBUG_LOGIC_ANALYZER_PIN
// wait until the wire is high... just in case
if (Dallas_waitForPinHigh(gpio_pin_rx, micros(), 250)) {
# ifdef DEBUG_LOGIC_ANALYZER_PIN
// DEBUG code using logic analyzer for timings
DIRECT_pinWrite(DEBUG_LOGIC_ANALYZER_PIN, 1);
# endif // ifdef DEBUG_LOGIC_ANALYZER_PIN
// The master starts a transmission with a reset pulse,
// which pulls the wire to 0 volts for at least 480 µs.
// This resets communication of every slave device on the bus.
Dallas_pinLow;
delayMicroseconds(480); // t_RSTL 480 ... 960 usec
// puling pin high will be very fast, so start measurement before pulling high
const uint32_t start = micros();
Dallas_pinHigh;
// digitalWrite(gpio_pin_tx, 1);
delayMicroseconds(1);
// Set to 'input', state will be pulled high by pull-up resistor
// Or will be kept pulled low by sensor
Dallas_pinInput;
# ifdef DEBUG_LOGIC_ANALYZER_PIN
// DEBUG code using logic analyzer for timings
DIRECT_pinWrite(DEBUG_LOGIC_ANALYZER_PIN, 0);
# endif // ifdef DEBUG_LOGIC_ANALYZER_PIN
// After that, any slave device, if present, shows that it exists with a "presence" pulse:
// it holds the bus low for at least 60 µs after the master releases the bus.
// This may take about 25 usec after release for present sensors to pull the line low.
// Sequence:
// - Release => pin high (typ: 1 usec as it was actively pulled high by GPIO)
// - Presence condition start (typ: 25 usec after release)
// - Presence condition end (minimal duration 60 usec, typ: 110 usec)
// - Wait till 480 usec after release.
// After that, any slave device, if present, shows that it exists with a "presence" pulse:
// it holds the bus low for at least 60 µs after the master releases the bus.
// This may take about 25 usec after release for present sensors to pull the line low.
// Sequence:
// - Release => pin high (typ: 1 usec as it was actively pulled high by GPIO)
// - Presence condition start (typ: 25 usec after release)
// - Presence condition end (minimal duration 60 usec, typ: 110 usec)
// - Wait till 480 usec after release.
// First check will only be to make sure the pin isn't pulled down for whatever reason
// Since we set the pin to high, this should return immediately
if (Dallas_waitForPinHigh(gpio_pin_rx, start, 15)) {
// Signal fall time will be quite fast, so no correction needed
presence_start = Dallas_measureWaitForPinLow(gpio_pin_rx, start, 60);
// First check will only be to make sure the pin isn't pulled down for whatever reason
// Since we set the pin to high, this should return immediately
if (Dallas_waitForPinHigh(gpio_pin_rx, start, 15)) {
// Signal fall time will be quite fast, so no correction needed
presence_start = Dallas_measureWaitForPinLow(gpio_pin_rx, start, 60);
if (presence_start > 15) {
// t_PDH 15 ... 60 usec
// t_PDL 60 ... 240 usec
if (presence_start > 15) {
// t_PDH 15 ... 60 usec
// t_PDL 60 ... 240 usec
// Signal will rise only due to pull-up resistor
// Meaning measured duration may be off by usec_release (too int32_t)
presence_end = Dallas_measureWaitForPinHigh(gpio_pin_rx, start, 60 + 240);
// Signal will rise only due to pull-up resistor
// Meaning measured duration may be off by usec_release (too int32_t)
presence_end = Dallas_measureWaitForPinHigh(gpio_pin_rx, start, 60 + 240);
// Set the pin high, just in case we have a (single) parasitic powered sensor
Dallas_pinHigh;
// Set the pin high, just in case we have a (single) parasitic powered sensor
Dallas_pinHigh;
// Enable interrupts again as soon as timing-critical section is done
ISR_interrupts();
// Enable interrupts again as soon as timing-critical section is done
ISR_interrupts();
const int32_t presence_duration = presence_end - presence_start;
const int32_t presence_duration = presence_end - presence_start;
if ((presence_duration >= 60) && (presence_duration < (240 /* + usec_release*/))) {
// t_RSTH = 480 usec
const int32_t timeLeft = 480 - usecPassedSince_fast(start);
if ((presence_duration >= 60) && (presence_duration < (240 /* + usec_release*/))) {
// t_RSTH = 480 usec
const int32_t timeLeft = 480 - usecPassedSince_fast(start);
if (timeLeft > 0) {
delayMicroseconds(timeLeft);
if (timeLeft > 0) {
delayMicroseconds(timeLeft);
}
return 1;
}
}
return 1;
}
return 0;
}
// Set the pin high, just in case we have a (single) parasitic powered sensor
Dallas_pinHigh;
ISR_interrupts();
}
}
// Set the pin high, just in case we have a (single) parasitic powered sensor
Dallas_pinHigh;
ISR_interrupts();
return 0;
}
@@ -1176,7 +1190,7 @@ void Dallas_write_bit(uint8_t v, int8_t gpio_pin_rx, int8_t gpio_pin_tx)
// High time is based on the recovery time, which is detected during reset
const int32_t low_time = (v & 1) ? 7 : 60;
const int32_t high_time = (v & 1) ? (40 + usec_release) : (2 * usec_release + 20); // Recovery time
uint32_t start = 0;
uint32_t start = 0;
Dallas_write_bit_ISR(v, gpio_pin_rx, gpio_pin_tx, low_time, high_time, start);
@@ -1191,8 +1205,8 @@ void Dallas_write_bit(uint8_t v, int8_t gpio_pin_rx, int8_t gpio_pin_tx)
void DALLAS_IRAM_ATTR Dallas_write_bit_ISR(uint8_t v,
int8_t gpio_pin_rx,
int8_t gpio_pin_tx,
int32_t low_time,
int32_t high_time,
int32_t low_time,
int32_t high_time,
uint32_t& start)
{
ISR_noInterrupts();
@@ -1345,7 +1359,8 @@ bool Dallas_SensorData::collect_value(int8_t gpio_rx, int8_t gpio_tx) {
--nrRetries;
Dallas_read_result res = Dallas_readTemp(tmpaddr, &value, gpio_rx, gpio_tx);
switch (res) {
switch (res)
{
case Dallas_read_result::OK:
++read_success;
lastReadError = false;
+18
View File
@@ -276,6 +276,24 @@ void addSelector_Item(const __FlashStringHelper *option, int index, bool sele
}
void addSelector_Item(const String& option, int index, bool selected, bool disabled, const String& attr)
{
addSelector_Item(option, String(index), selected, disabled, attr);
}
void addSelector_Item_index64(const String& option,
uint64_t index,
bool selected,
bool disabled,
const String& attr)
{
addSelector_Item(option, ull2String(index), selected, disabled, attr);
}
void addSelector_Item(const String& option,
const String& index,
bool selected,
bool disabled,
const String& attr)
{
addHtml(F("<option "));
addHtmlAttribute(F("value"), index);
+12
View File
@@ -101,6 +101,18 @@ void addSelector_Item(const String& option,
bool disabled = false,
const String& attr = EMPTY_STRING);
void addSelector_Item(const String& option,
const String& index,
bool selected,
bool disabled = false,
const String& attr = EMPTY_STRING);
void addSelector_Item_index64(const String& option,
uint64_t index,
bool selected,
bool disabled = false,
const String& attr = EMPTY_STRING);
void addSelector_Foot(bool reloadonchange = false);
void addSelector_OptGroup(const String& label);
+30 -9
View File
@@ -685,23 +685,44 @@ int getFormItemInt(const String& key, int defaultValue) {
return value;
}
uint64_t getFormItemUInt64(const String& key, uint64_t defaultValue)
{
uint64_t value = defaultValue;
getCheckWebserverArg_int(key, value);
return value;
}
bool getCheckWebserverArg_int(const String& key, int& value) {
const String valueStr = webArg(key);
if (valueStr.isEmpty()) return false;
// FIXME TD-er: Since ESP_IDF 5.1 int32_t != int
int32_t tmp{};
const bool res = validIntFromString(valueStr, tmp);
int64_t tmp{};
if (!getCheckWebserverArg_int(key, tmp)) return false;
value = tmp;
return res;
return true;
}
bool getCheckWebserverArg_int(const String& key,
uint32_t & value) {
uint64_t tmp{};
if (!getCheckWebserverArg_int(key, tmp)) return false;
value = tmp;
return true;
}
bool getCheckWebserverArg_int(const String& key,
uint64_t & value)
{
const String valueStr = webArg(key);
if (valueStr.isEmpty()) return false;
uint32_t tmp{};
const bool res = validUIntFromString(valueStr, tmp);
value = tmp;
const bool res = validUInt64FromString(valueStr, value);
return res;
}
bool getCheckWebserverArg_int(const String& key,
int64_t & value)
{
const String valueStr = webArg(key);
if (valueStr.isEmpty()) return false;
const bool res = validInt64FromString(valueStr, value);
return res;
}
+7
View File
@@ -322,6 +322,7 @@ void addFormPinStateSelect(int gpio,
int getFormItemInt(const __FlashStringHelper * key, int defaultValue);
int getFormItemInt(const String& key, int defaultValue);
uint64_t getFormItemUInt64(const String& key, uint64_t defaultValue);
bool getCheckWebserverArg_int(const String& key,
int & value);
@@ -329,6 +330,12 @@ bool getCheckWebserverArg_int(const String& key,
bool getCheckWebserverArg_int(const String& key,
uint32_t & value);
bool getCheckWebserverArg_int(const String& key,
uint64_t & value);
bool getCheckWebserverArg_int(const String& key,
int64_t & value);
bool update_whenset_FormItemInt(const __FlashStringHelper * key,
int & value,
bool* changed = nullptr);