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