mirror of https://github.com/meshcore-dev/MeshCore
committed by
GitHub
5 changed files with 168 additions and 0 deletions
@ -0,0 +1,68 @@ |
|||
#include "OneWireSensor.h" |
|||
|
|||
#if ENV_INCLUDE_ONEWIRE |
|||
|
|||
// 1-Wire ROM family codes for the temperature devices the
|
|||
// DallasTemperature library knows how to decode. Centralised here so
|
|||
// the family filter in begin() reads as a list of supported parts.
|
|||
static inline bool is_temperature_family(uint8_t family) { |
|||
switch (family) { |
|||
case 0x10: // DS18S20 / DS1820
|
|||
case 0x22: // DS1822
|
|||
case 0x28: // DS18B20
|
|||
case 0x3B: // DS1825 / MAX31850
|
|||
case 0x42: // DS28EA00
|
|||
return true; |
|||
default: |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
OneWireSensor::OneWireSensor(uint8_t pin) |
|||
: _bus(pin), _dallas(&_bus) {} |
|||
|
|||
uint8_t OneWireSensor::begin() { |
|||
// Presence-pulse gate. OneWire::reset() returns 1 only when at
|
|||
// least one device on the bus pulls the line low in response to
|
|||
// the reset pulse. Without it, we skip DallasTemperature entirely.
|
|||
if (_bus.reset() != 1) return 0; |
|||
|
|||
_dallas.begin(); |
|||
|
|||
const uint8_t bus_total = _dallas.getDeviceCount(); |
|||
_count = 0; |
|||
for (uint8_t i = 0; i < bus_total && _count < MAX_DEVICES; i++) { |
|||
DeviceAddress addr; |
|||
if (!_dallas.getAddress(addr, i)) continue; |
|||
|
|||
// Extension point: a future non-temperature family (e.g. DS2438
|
|||
// battery monitor, family 0x26) would dispatch on this family
|
|||
// byte to its own driver and register a different query_* free
|
|||
// function from the manager. The presence-pulse gate above and
|
|||
// the per-device address storage below are family-agnostic and
|
|||
// can be reused as-is.
|
|||
if (!is_temperature_family(addr[0])) continue; |
|||
|
|||
memcpy(_addresses[_count], addr, sizeof(DeviceAddress)); |
|||
_count++; |
|||
} |
|||
|
|||
return _count; |
|||
} |
|||
|
|||
void OneWireSensor::query(uint8_t channel, uint8_t index, CayenneLPP& lpp) { |
|||
if (index >= _count) return; |
|||
|
|||
// Per-device blocking conversion keeps query() stateless and
|
|||
// independent of call order — the cost is one conversion window
|
|||
// (~750 ms at default 12-bit resolution) per device per cycle,
|
|||
// which matches the synchronous read pattern used by the other
|
|||
// sensors in EnvironmentSensorManager.
|
|||
_dallas.requestTemperaturesByAddress(_addresses[index]); |
|||
const float t = _dallas.getTempC(_addresses[index]); |
|||
if (t == DEVICE_DISCONNECTED_C) return; |
|||
|
|||
lpp.addTemperature(channel, t); |
|||
} |
|||
|
|||
#endif // ENV_INCLUDE_ONEWIRE
|
|||
@ -0,0 +1,50 @@ |
|||
#pragma once |
|||
|
|||
// Standalone 1-Wire bus driver for EnvironmentSensorManager.
|
|||
//
|
|||
// Covers every DallasTemperature-supported temperature family on one
|
|||
// bus pin: DS18B20 (0x28), DS18S20 (0x10), DS1822 (0x22), DS1825 /
|
|||
// MAX31850 (0x3B), DS28EA00 (0x42). Each detected device is exposed
|
|||
// as its own telemetry sub-channel, so an air-and-water deployment
|
|||
// with two probes on the same pin "just works".
|
|||
//
|
|||
// Portability contract: this file contains no board-specific pins or
|
|||
// #ifdefs. The bus pin comes from the per-board build flag
|
|||
// TELEM_ONEWIRE_PIN, and the whole module is compiled out when
|
|||
// ENV_INCLUDE_ONEWIRE is not set.
|
|||
|
|||
#if ENV_INCLUDE_ONEWIRE |
|||
|
|||
#include <Arduino.h> |
|||
#include <CayenneLPP.h> |
|||
#include <OneWire.h> |
|||
#include <DallasTemperature.h> |
|||
|
|||
class OneWireSensor { |
|||
public: |
|||
// Upper bound on devices enumerated from a single bus. Kept under
|
|||
// EnvironmentSensorManager::MAX_ACTIVE_SENSORS so a fully populated
|
|||
// bus cannot overflow the active-sensor table on its own.
|
|||
static const uint8_t MAX_DEVICES = 8; |
|||
|
|||
explicit OneWireSensor(uint8_t pin); |
|||
|
|||
// Probes the bus for a 1-Wire presence pulse — the direct analog of
|
|||
// the I2C ACK check the manager's address scan relies on. With no
|
|||
// pulse, returns 0 and DallasTemperature is never engaged; this
|
|||
// preserves the manager's "never touch absent hardware" invariant.
|
|||
// Otherwise enumerates the bus and returns the number of detected
|
|||
// temperature-family devices (clamped to MAX_DEVICES).
|
|||
uint8_t begin(); |
|||
|
|||
// Reads device `index` and writes one temperature channel.
|
|||
void query(uint8_t channel, uint8_t index, CayenneLPP& lpp); |
|||
|
|||
private: |
|||
OneWire _bus; |
|||
DallasTemperature _dallas; |
|||
uint8_t _count = 0; |
|||
DeviceAddress _addresses[MAX_DEVICES]; |
|||
}; |
|||
|
|||
#endif // ENV_INCLUDE_ONEWIRE
|
|||
Loading…
Reference in new issue