Add DS18x20 support on up to four GPIOs

Add DS18x20 support on up to four GPIOs by md5sum-as (#16833)
This commit is contained in:
Theo Arends 2022-10-18 16:36:45 +02:00
parent df24aef75c
commit 2104256b74
7 changed files with 109 additions and 167 deletions

View File

@ -5,10 +5,12 @@ All notable changes to this project will be documented in this file.
## [12.2.0.1] ## [12.2.0.1]
### Added ### Added
- DS18x20 support on up to four GPIOs by md5sum-as (#16833)
### Breaking Changed ### Breaking Changed
### Changed ### Changed
- DS18x20 ``DS18Alias`` to ``DS18Sens`` (#16833)
### Fixed ### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 (#16850) - BP5758D red channel corruption regression from v12.1.1.6 (#16850)

View File

@ -109,10 +109,12 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
## Changelog v12.2.0.1 ## Changelog v12.2.0.1
### Added ### Added
- DS18x20 support on up to four GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
### Breaking Changed ### Breaking Changed
### Changed ### Changed
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
### Fixed ### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850) - BP5758D red channel corruption regression from v12.1.1.6 [#16850](https://github.com/arendst/Tasmota/issues/16850)

View File

@ -304,8 +304,6 @@ const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to
#define XPT2046_MINY 346 #define XPT2046_MINY 346
#define XPT2046_MAXY 3870 #define XPT2046_MAXY 3870
// Max number GPIO for DS18x20_MULTI_GPIOs
#define MAX_DSB 4
/*********************************************************************************************\ /*********************************************************************************************\
* Enumeration * Enumeration
\*********************************************************************************************/ \*********************************************************************************************/

View File

@ -446,6 +446,7 @@ const char kSensorNames[] PROGMEM =
const char kSensorNamesFixed[] PROGMEM = const char kSensorNamesFixed[] PROGMEM =
D_SENSOR_USER; D_SENSOR_USER;
// Max number of GPIOs
#define MAX_MAX31865S 6 #define MAX_MAX31865S 6
#define MAX_FLOWRATEMETER 2 #define MAX_FLOWRATEMETER 2
#define MAX_A4988_MSS 3 #define MAX_A4988_MSS 3
@ -453,6 +454,7 @@ const char kSensorNamesFixed[] PROGMEM =
#define MAX_WEBCAM_HSD 3 #define MAX_WEBCAM_HSD 3
#define MAX_SM2135_DAT 10 #define MAX_SM2135_DAT 10
#define MAX_SM2335_DAT 16 #define MAX_SM2335_DAT 16
#define MAX_DSB 4
const uint16_t kGpioNiceList[] PROGMEM = { const uint16_t kGpioNiceList[] PROGMEM = {
GPIO_NONE, // Not used GPIO_NONE, // Not used
@ -661,18 +663,11 @@ const uint16_t kGpioNiceList[] PROGMEM = {
AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321
#endif #endif
#ifdef USE_DS18x20 #ifdef USE_DS18x20
#ifdef DS18x20_MULTI_GPIOs AGPIO(GPIO_DSB) + MAX_DSB, // Single wire DS18B20 or DS18S20
AGPIO(GPIO_DSB) + MAX_DSB, // Single wire DS18B20 or DS18S20 #ifdef ESP8266
#ifdef ESP8266 // ESP32 don't support dual pin mode AGPIO(GPIO_DSB_OUT) + MAX_DSB, // Pseudo Single wire DS18B20 or DS18S20
AGPIO(GPIO_DSB_OUT) + MAX_DSB, // Pseudo Single wire DS18B20 or DS18S20 #endif // ESP8266
#endif #endif // USE_DS18x20
#else
AGPIO(GPIO_DSB), // Single wire DS18B20 or DS18S20
#ifdef ESP8266 // ESP32 don't support dual pin mode
AGPIO(GPIO_DSB_OUT), // Pseudo Single wire DS18B20 or DS18S20
#endif
#endif //DS18x20_MULTI_GPIOs
#endif
#ifdef USE_LMT01 #ifdef USE_LMT01
AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO
#endif #endif

View File

@ -580,7 +580,6 @@
#define USE_DS18x20 // Add support for DS18x20 sensors with id sort, single scan and read retry (+2k6 code) #define USE_DS18x20 // Add support for DS18x20 sensors with id sort, single scan and read retry (+2k6 code)
// #define W1_PARASITE_POWER // Optimize for parasite powered sensors // #define W1_PARASITE_POWER // Optimize for parasite powered sensors
// #define DS18x20_USE_ID_ALIAS // Add support aliasing for DS18x20 sensors. See comments in xsns_05 files (+0k5 code) // #define DS18x20_USE_ID_ALIAS // Add support aliasing for DS18x20 sensors. See comments in xsns_05 files (+0k5 code)
// #define DS18x20_MULTI_GPIOs // Add support multiple GPIOs for DS18x20 sensors (+0k2 code)
// -- I2C sensors --------------------------------- // -- I2C sensors ---------------------------------
#define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram) #define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram)

View File

@ -1,8 +1,8 @@
/* /*
xsns_05_ds18x20.ino - DS18x20 temperature sensor support for Tasmota xsns_05_ds18x20.ino - DS18x20 temperature sensor support for Tasmota
Copyright (C) 2021 Theo Arends Copyright (C) 2021 Theo Arends and md5sum-as (https://github.com/md5sum-as)
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
@ -15,8 +15,6 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
Updated by md5sum-as (https://github.com/md5sum-as)
*/ */
#ifdef ESP8266 #ifdef ESP8266
@ -28,8 +26,8 @@
#define XSNS_05 5 #define XSNS_05 5
//#define USE_DS18x20_RECONFIGURE // When sensor is lost keep retrying or re-configure //#define USE_DS18x20_RECONFIGURE // When sensor is lost keep retrying or re-configure
//#define DS18x20_USE_ID_AS_NAME // Use last 3 bytes for naming of sensors //#define DS18x20_USE_ID_AS_NAME // Use last 3 bytes for naming of sensors
/* #define DS18x20_USE_ID_ALIAS in my_user_config.h or user_config_override.h /* #define DS18x20_USE_ID_ALIAS in my_user_config.h or user_config_override.h
* Use alias for fixed sensor name in scripts by autoexec. Command: DS18Alias XXXXXXXXXXXXXXXX,N where XXXXXXXXXXXXXXXX full serial and N number 1-255 * Use alias for fixed sensor name in scripts by autoexec. Command: DS18Alias XXXXXXXXXXXXXXXX,N where XXXXXXXXXXXXXXXX full serial and N number 1-255
* Result in JSON: "DS18Sens_2":{"Id":"000003287CD8","Temperature":26.3} (example with N=2) * Result in JSON: "DS18Sens_2":{"Id":"000003287CD8","Temperature":26.3} (example with N=2)
@ -47,7 +45,7 @@
#define W1_WRITE_SCRATCHPAD 0x4E #define W1_WRITE_SCRATCHPAD 0x4E
#define W1_READ_SCRATCHPAD 0xBE #define W1_READ_SCRATCHPAD 0xBE
#ifndef DS18X20_MAX_SENSORS // DS18X20_MAX_SENSORS fallback to 8 if not defined in user_config_override.h #ifndef DS18X20_MAX_SENSORS // DS18X20_MAX_SENSORS fallback to 8 if not defined in user_config_override.h
#define DS18X20_MAX_SENSORS 8 #define DS18X20_MAX_SENSORS 8
#endif #endif
@ -62,22 +60,17 @@ struct {
uint8_t address[8]; uint8_t address[8];
uint8_t index; uint8_t index;
uint8_t valid; uint8_t valid;
int8_t pins_id;
#ifdef DS18x20_USE_ID_ALIAS #ifdef DS18x20_USE_ID_ALIAS
uint8_t alias; uint8_t alias;
#endif //DS18x20_USE_ID_ALIAS #endif // DS18x20_USE_ID_ALIAS
#ifdef DS18x20_MULTI_GPIOs
int8_t pins_id = 0;
#endif //DS18x20_MULTI_GPIOs
} ds18x20_sensor[DS18X20_MAX_SENSORS]; } ds18x20_sensor[DS18X20_MAX_SENSORS];
#ifdef DS18x20_MULTI_GPIOs
struct { struct {
int8_t pin = 0; // Shelly GPIO3 input only int8_t pin = 0; // Shelly GPIO3 input only
int8_t pin_out = 0; // Shelly GPIO00 output only int8_t pin_out = 0; // Shelly GPIO00 output only
bool dual_mode = false; // Single pin mode bool dual_mode = false; // Single pin mode
} ds18x20_gpios[MAX_DSB]; } ds18x20_gpios[MAX_DSB];
uint8_t ds18x20_ngpio = 0; // Count of GPIO found
#endif
struct { struct {
#ifdef W1_PARASITE_POWER #ifdef W1_PARASITE_POWER
@ -85,7 +78,8 @@ struct {
uint8_t current_sensor = 0; uint8_t current_sensor = 0;
#endif #endif
char name[17]; char name[17];
uint8_t sensors = 0; uint8_t sensors;
uint8_t gpios; // Count of GPIO found
uint8_t input_mode = 0; // INPUT or INPUT_PULLUP (=2) uint8_t input_mode = 0; // INPUT or INPUT_PULLUP (=2)
int8_t pin = 0; // Shelly GPIO3 input only int8_t pin = 0; // Shelly GPIO3 input only
int8_t pin_out = 0; // Shelly GPIO00 output only int8_t pin_out = 0; // Shelly GPIO00 output only
@ -315,27 +309,24 @@ bool OneWireCrc8(uint8_t *addr) {
/********************************************************************************************/ /********************************************************************************************/
void Ds18x20Init(void) { void Ds18x20Init(void) {
DS18X20Data.input_mode = Settings->flag3.ds18x20_internal_pullup ? INPUT_PULLUP : INPUT; // SetOption74 - Enable internal pullup for single DS18x20 sensor DS18X20Data.gpios = 0;
for (uint32_t pins = 0; pins < MAX_DSB; pins++) {
uint64_t ids[DS18X20_MAX_SENSORS];
DS18X20Data.sensors = 0;
#ifdef DS18x20_MULTI_GPIOs
ds18x20_ngpio=0;
uint8_t pins;
for (pins = 0; pins < MAX_DSB; pins++) {
if (PinUsed(GPIO_DSB, pins)) { if (PinUsed(GPIO_DSB, pins)) {
ds18x20_gpios[pins].pin = Pin(GPIO_DSB, pins); ds18x20_gpios[pins].pin = Pin(GPIO_DSB, pins);
if (PinUsed(GPIO_DSB_OUT, pins)) { if (PinUsed(GPIO_DSB_OUT, pins)) {
ds18x20_gpios[pins].dual_mode = true; ds18x20_gpios[pins].dual_mode = true;
ds18x20_gpios[pins].pin_out = Pin(GPIO_DSB_OUT, pins); ds18x20_gpios[pins].pin_out = Pin(GPIO_DSB_OUT, pins);
} }
ds18x20_ngpio++; DS18X20Data.gpios++;
} }
} }
for (pins = 0; pins < ds18x20_ngpio; pins++) { uint64_t ids[DS18X20_MAX_SENSORS];
DS18X20Data.sensors = 0;
DS18X20Data.input_mode = Settings->flag3.ds18x20_internal_pullup ? INPUT_PULLUP : INPUT; // SetOption74 - Enable internal pullup for single DS18x20 sensor
for (uint32_t pins = 0; pins < DS18X20Data.gpios; pins++) {
DS18X20Data.pin = ds18x20_gpios[pins].pin; DS18X20Data.pin = ds18x20_gpios[pins].pin;
DS18X20Data.dual_mode = ds18x20_gpios[pins].dual_mode; DS18X20Data.dual_mode = ds18x20_gpios[pins].dual_mode;
if (ds18x20_gpios[pins].dual_mode) { if (ds18x20_gpios[pins].dual_mode) {
@ -343,52 +334,37 @@ uint8_t pins;
pinMode(DS18X20Data.pin_out, OUTPUT); pinMode(DS18X20Data.pin_out, OUTPUT);
pinMode(DS18X20Data.pin, DS18X20Data.input_mode); pinMode(DS18X20Data.pin, DS18X20Data.input_mode);
} }
#else
DS18X20Data.pin = Pin(GPIO_DSB);
if (PinUsed(GPIO_DSB_OUT)) { onewire_last_discrepancy = 0;
DS18X20Data.pin_out = Pin(GPIO_DSB_OUT); onewire_last_device_flag = false;
DS18X20Data.dual_mode = true; // Dual pins mode as used by Shelly onewire_last_family_discrepancy = 0;
pinMode(DS18X20Data.pin_out, OUTPUT); for (uint32_t i = 0; i < 8; i++) {
pinMode(DS18X20Data.pin, DS18X20Data.input_mode); onewire_rom_id[i] = 0;
}
#endif //DS18x20_MULTI_GPIOs
onewire_last_discrepancy = 0;
onewire_last_device_flag = false;
onewire_last_family_discrepancy = 0;
for (uint32_t i = 0; i < 8; i++) {
onewire_rom_id[i] = 0;
}
while (DS18X20Data.sensors < DS18X20_MAX_SENSORS) {
if (!OneWireSearch(ds18x20_sensor[DS18X20Data.sensors].address)) {
break;
} }
if (OneWireCrc8(ds18x20_sensor[DS18X20Data.sensors].address) &&
((ds18x20_sensor[DS18X20Data.sensors].address[0] == DS18S20_CHIPID) || while (DS18X20Data.sensors < DS18X20_MAX_SENSORS) {
(ds18x20_sensor[DS18X20Data.sensors].address[0] == DS1822_CHIPID) || if (!OneWireSearch(ds18x20_sensor[DS18X20Data.sensors].address)) {
(ds18x20_sensor[DS18X20Data.sensors].address[0] == DS18B20_CHIPID) || break;
(ds18x20_sensor[DS18X20Data.sensors].address[0] == MAX31850_CHIPID))) {
ds18x20_sensor[DS18X20Data.sensors].index = DS18X20Data.sensors;
ids[DS18X20Data.sensors] = ds18x20_sensor[DS18X20Data.sensors].address[0]; // Chip id
for (uint32_t j = 6; j > 0; j--) {
ids[DS18X20Data.sensors] = ids[DS18X20Data.sensors] << 8 | ds18x20_sensor[DS18X20Data.sensors].address[j];
} }
#ifdef DS18x20_USE_ID_ALIAS if (OneWireCrc8(ds18x20_sensor[DS18X20Data.sensors].address) &&
ds18x20_sensor[DS18X20Data.sensors].alias=0; ((ds18x20_sensor[DS18X20Data.sensors].address[0] == DS18S20_CHIPID) ||
(ds18x20_sensor[DS18X20Data.sensors].address[0] == DS1822_CHIPID) ||
(ds18x20_sensor[DS18X20Data.sensors].address[0] == DS18B20_CHIPID) ||
(ds18x20_sensor[DS18X20Data.sensors].address[0] == MAX31850_CHIPID))) {
ds18x20_sensor[DS18X20Data.sensors].index = DS18X20Data.sensors;
ids[DS18X20Data.sensors] = ds18x20_sensor[DS18X20Data.sensors].address[0]; // Chip id
for (uint32_t j = 6; j > 0; j--) {
ids[DS18X20Data.sensors] = ids[DS18X20Data.sensors] << 8 | ds18x20_sensor[DS18X20Data.sensors].address[j];
}
#ifdef DS18x20_USE_ID_ALIAS
ds18x20_sensor[DS18X20Data.sensors].alias=0;
#endif #endif
#ifdef DS18x20_MULTI_GPIOs ds18x20_sensor[DS18X20Data.sensors].pins_id = pins;
ds18x20_sensor[DS18X20Data.sensors].pins_id = pins; DS18X20Data.sensors++;
#endif //DS18x20_MULTI_GPIOs }
DS18X20Data.sensors++;
} }
} }
#ifdef DS18x20_MULTI_GPIOs
}
#endif //DS18x20_MULTI_GPIOs
//#ifndef DS18x20_MULTI_GPIOs
for (uint32_t i = 0; i < DS18X20Data.sensors; i++) { for (uint32_t i = 0; i < DS18X20Data.sensors; i++) {
for (uint32_t j = i + 1; j < DS18X20Data.sensors; j++) { for (uint32_t j = i + 1; j < DS18X20Data.sensors; j++) {
if (ids[ds18x20_sensor[i].index] > ids[ds18x20_sensor[j].index]) { // Sort ascending if (ids[ds18x20_sensor[i].index] > ids[ds18x20_sensor[j].index]) { // Sort ascending
@ -396,31 +372,27 @@ uint8_t pins;
} }
} }
} }
//#endif
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DSB D_SENSORS_FOUND " %d"), DS18X20Data.sensors); AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DSB D_SENSORS_FOUND " %d"), DS18X20Data.sensors);
} }
void Ds18x20Convert(void) { void Ds18x20Convert(void) {
#ifdef DS18x20_MULTI_GPIOs for (uint8_t i = 0; i < DS18X20Data.gpios; i++) {
for (uint8_t i = 0; i < ds18x20_ngpio; i++) {
DS18X20Data.pin = ds18x20_gpios[i].pin; DS18X20Data.pin = ds18x20_gpios[i].pin;
DS18X20Data.dual_mode = ds18x20_gpios[i].dual_mode; DS18X20Data.dual_mode = ds18x20_gpios[i].dual_mode;
DS18X20Data.pin_out = ds18x20_gpios[i].pin_out; DS18X20Data.pin_out = ds18x20_gpios[i].pin_out;
#endif OneWireReset();
OneWireReset();
#ifdef W1_PARASITE_POWER #ifdef W1_PARASITE_POWER
// With parasite power address one sensor at a time // With parasite power address one sensor at a time
if (++DS18X20Data.current_sensor >= DS18X20Data.sensors) if (++DS18X20Data.current_sensor >= DS18X20Data.sensors)
DS18X20Data.current_sensor = 0; DS18X20Data.current_sensor = 0;
OneWireSelect(ds18x20_sensor[DS18X20Data.current_sensor].address); OneWireSelect(ds18x20_sensor[DS18X20Data.current_sensor].address);
#else #else
OneWireWrite(W1_SKIP_ROM); // Address all Sensors on Bus OneWireWrite(W1_SKIP_ROM); // Address all Sensors on Bus
#endif #endif
OneWireWrite(W1_CONVERT_TEMP); // start conversion, no parasite power on at the end OneWireWrite(W1_CONVERT_TEMP); // start conversion, no parasite power on at the end
// delay(750); // 750ms should be enough for 12bit conv // delay(750); // 750ms should be enough for 12bit conv
#ifdef DS18x20_MULTI_GPIOs
} }
#endif
} }
bool Ds18x20Read(uint8_t sensor) { bool Ds18x20Read(uint8_t sensor) {
@ -429,11 +401,9 @@ bool Ds18x20Read(uint8_t sensor) {
int8_t sign = 1; int8_t sign = 1;
uint8_t index = ds18x20_sensor[sensor].index; uint8_t index = ds18x20_sensor[sensor].index;
#ifdef DS18x20_MULTI_GPIOs
DS18X20Data.pin = ds18x20_gpios[ds18x20_sensor[index].pins_id].pin; DS18X20Data.pin = ds18x20_gpios[ds18x20_sensor[index].pins_id].pin;
DS18X20Data.pin_out = ds18x20_gpios[ds18x20_sensor[index].pins_id].pin_out; DS18X20Data.pin_out = ds18x20_gpios[ds18x20_sensor[index].pins_id].pin_out;
DS18X20Data.dual_mode = ds18x20_gpios[ds18x20_sensor[index].pins_id].dual_mode; DS18X20Data.dual_mode = ds18x20_gpios[ds18x20_sensor[index].pins_id].dual_mode;
#endif
if (ds18x20_sensor[index].valid) { ds18x20_sensor[index].valid--; } if (ds18x20_sensor[index].valid) { ds18x20_sensor[index].valid--; }
for (uint32_t retry = 0; retry < 3; retry++) { for (uint32_t retry = 0; retry < 3; retry++) {
OneWireReset(); OneWireReset();
@ -608,7 +578,7 @@ void CmndDSAlias(void) {
uint8_t sensor=255; uint8_t sensor=255;
char argument[XdrvMailbox.data_len]; char argument[XdrvMailbox.data_len];
char address[17]; char address[17];
if (ArgC()==2) { if (ArgC()==2) {
tmp=atoi(ArgV(argument, 2)); tmp=atoi(ArgV(argument, 2));
ArgV(argument,1); ArgV(argument,1);
@ -643,8 +613,8 @@ void CmndDSAlias(void) {
bool Xsns05(uint8_t function) { bool Xsns05(uint8_t function) {
bool result = false; bool result = false;
if (PinUsed(GPIO_DSB,GPIO_ANY)) { if (PinUsed(GPIO_DSB, GPIO_ANY)) {
switch (function) { switch (function) {
case FUNC_INIT: case FUNC_INIT:
Ds18x20Init(); Ds18x20Init();

View File

@ -1,8 +1,8 @@
/* /*
xsns_05_esp32_ds18x20.ino - DS18x20 temperature sensor support for ESP32 Tasmota xsns_05_esp32_ds18x20.ino - DS18x20 temperature sensor support for ESP32 Tasmota
Copyright (C) 2021 Heiko Krupp and Theo Arends Copyright (C) 2021 Heiko Krupp, Theo Arends and md5sum-as (https://github.com/md5sum-as)
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
@ -15,8 +15,6 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
Updated by md5sum-as (https://github.com/md5sum-as)
*/ */
#ifdef ESP32 #ifdef ESP32
@ -27,7 +25,7 @@
#define XSNS_05 5 #define XSNS_05 5
//#define DS18x20_USE_ID_AS_NAME // Use last 3 bytes for naming of sensors //#define DS18x20_USE_ID_AS_NAME // Use last 3 bytes for naming of sensors
/* #define DS18x20_USE_ID_ALIAS in my_user_config.h or user_config_override.h /* #define DS18x20_USE_ID_ALIAS in my_user_config.h or user_config_override.h
* Use alias for fixed sensor name in scripts by autoexec. Command: DS18Alias XXXXXXXXXXXXXXXX,N where XXXXXXXXXXXXXXXX full serial and N number 1-255 * Use alias for fixed sensor name in scripts by autoexec. Command: DS18Alias XXXXXXXXXXXXXXXX,N where XXXXXXXXXXXXXXXX full serial and N number 1-255
@ -44,7 +42,7 @@
#define W1_CONVERT_TEMP 0x44 #define W1_CONVERT_TEMP 0x44
#define W1_READ_SCRATCHPAD 0xBE #define W1_READ_SCRATCHPAD 0xBE
#ifndef DS18X20_MAX_SENSORS // DS18X20_MAX_SENSORS fallback to 8 if not defined in user_config_override.h #ifndef DS18X20_MAX_SENSORS // DS18X20_MAX_SENSORS fallback to 8 if not defined in user_config_override.h
#define DS18X20_MAX_SENSORS 8 #define DS18X20_MAX_SENSORS 8
#endif #endif
@ -58,78 +56,62 @@ struct {
uint8_t address[8]; uint8_t address[8];
uint8_t index; uint8_t index;
uint8_t valid; uint8_t valid;
int8_t pins_id;
#ifdef DS18x20_USE_ID_ALIAS #ifdef DS18x20_USE_ID_ALIAS
uint8_t alias; uint8_t alias;
#endif //DS18x20_USE_ID_ALIAS #endif //DS18x20_USE_ID_ALIAS
#ifdef DS18x20_MULTI_GPIOs
int8_t pins_id = 0;
#endif //DS18x20_MULTI_GPIOs
} ds18x20_sensor[DS18X20_MAX_SENSORS]; } ds18x20_sensor[DS18X20_MAX_SENSORS];
#include <OneWire.h> #include <OneWire.h>
OneWire *ds = nullptr;
#ifdef DS18x20_MULTI_GPIOs
OneWire *ds18x20_gpios[MAX_DSB]; OneWire *ds18x20_gpios[MAX_DSB];
uint8_t ds18x20_ngpio = 0; // Count of GPIO found
#endif
struct { struct {
char name[17]; char name[17];
uint8_t sensors = 0; uint8_t sensors;
uint8_t gpios; // Count of GPIO found
} DS18X20Data; } DS18X20Data;
/********************************************************************************************/ /********************************************************************************************/
OneWire *ds = nullptr;
void Ds18x20Init(void) { void Ds18x20Init(void) {
DS18X20Data.gpios = 0;
#ifdef DS18x20_MULTI_GPIOs for (uint32_t pins = 0; pins < MAX_DSB; pins++) {
for (uint8_t pins = 0; pins < MAX_DSB; pins++) { if (PinUsed(GPIO_DSB, pins)) {
if (PinUsed(GPIO_DSB, pins)) { ds18x20_gpios[pins] = new OneWire(Pin(GPIO_DSB, pins));
ds18x20_gpios[pins] = new OneWire(Pin(GPIO_DSB,pins)); DS18X20Data.gpios++;
ds18x20_ngpio++;
} }
} }
#else
ds = new OneWire(Pin(GPIO_DSB));
#endif
Ds18x20Search(); Ds18x20Search();
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DSB D_SENSORS_FOUND " %d"), DS18X20Data.sensors); AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_DSB D_SENSORS_FOUND " %d"), DS18X20Data.sensors);
} }
void Ds18x20Search(void) { void Ds18x20Search(void) {
uint8_t num_sensors=0; uint8_t num_sensors = 0;
uint8_t sensor = 0; uint8_t sensor = 0;
#ifdef DS18x20_MULTI_GPIOs for (uint8_t pins = 0; pins < DS18X20Data.gpios; pins++) {
for (uint8_t pins=0; pins < ds18x20_ngpio; pins++) { ds = ds18x20_gpios[pins];
ds=ds18x20_gpios[pins]; ds->reset_search();
for (num_sensors; num_sensors < DS18X20_MAX_SENSORS; num_sensors) {
if (!ds->search(ds18x20_sensor[num_sensors].address)) {
ds->reset_search();
break;
}
// If CRC Ok and Type DS18S20, DS1822, DS18B20 or MAX31850
if ((OneWire::crc8(ds18x20_sensor[num_sensors].address, 7) == ds18x20_sensor[num_sensors].address[7]) &&
((ds18x20_sensor[num_sensors].address[0] == DS18S20_CHIPID) ||
(ds18x20_sensor[num_sensors].address[0] == DS1822_CHIPID) ||
(ds18x20_sensor[num_sensors].address[0] == DS18B20_CHIPID) ||
(ds18x20_sensor[num_sensors].address[0] == MAX31850_CHIPID))) {
#ifdef DS18x20_USE_ID_ALIAS
ds18x20_sensor[num_sensors].alias=0;
#endif #endif
ds->reset_search(); ds18x20_sensor[num_sensors].pins_id = pins;
for (num_sensors; num_sensors < DS18X20_MAX_SENSORS; num_sensors) { num_sensors++;
if (!ds->search(ds18x20_sensor[num_sensors].address)) { }
ds->reset_search();
break;
}
// If CRC Ok and Type DS18S20, DS1822, DS18B20 or MAX31850
if ((OneWire::crc8(ds18x20_sensor[num_sensors].address, 7) == ds18x20_sensor[num_sensors].address[7]) &&
((ds18x20_sensor[num_sensors].address[0] == DS18S20_CHIPID) ||
(ds18x20_sensor[num_sensors].address[0] == DS1822_CHIPID) ||
(ds18x20_sensor[num_sensors].address[0] == DS18B20_CHIPID) ||
(ds18x20_sensor[num_sensors].address[0] == MAX31850_CHIPID))) {
#ifdef DS18x20_USE_ID_ALIAS
ds18x20_sensor[num_sensors].alias=0;
#endif
#ifdef DS18x20_MULTI_GPIOs
ds18x20_sensor[num_sensors].pins_id = pins;
#endif //DS18x20_MULTI_GPIOs
num_sensors++;
} }
} }
#ifdef DS18x20_MULTI_GPIOs
}
#endif //DS18x20_MULTI_GPIOs
for (uint32_t i = 0; i < num_sensors; i++) { for (uint32_t i = 0; i < num_sensors; i++) {
ds18x20_sensor[i].index = i; ds18x20_sensor[i].index = i;
@ -145,17 +127,13 @@ void Ds18x20Search(void) {
} }
void Ds18x20Convert(void) { void Ds18x20Convert(void) {
#ifdef DS18x20_MULTI_GPIOs for (uint32_t i = 0; i < DS18X20Data.gpios; i++) {
for (uint8_t i = 0; i < ds18x20_ngpio; i++) { ds = ds18x20_gpios[i];
ds=ds18x20_gpios[i]; ds->reset();
#endif ds->write(W1_SKIP_ROM); // Address all Sensors on Bus
ds->reset(); ds->write(W1_CONVERT_TEMP); // start conversion, no parasite power on at the end
ds->write(W1_SKIP_ROM); // Address all Sensors on Bus // delay(750); // 750ms should be enough for 12bit conv
ds->write(W1_CONVERT_TEMP); // start conversion, no parasite power on at the end }
// delay(750); // 750ms should be enough for 12bit conv
#ifdef DS18x20_MULTI_GPIOs
}
#endif
} }
bool Ds18x20Read(uint8_t sensor, float &t) { bool Ds18x20Read(uint8_t sensor, float &t) {
@ -166,9 +144,7 @@ bool Ds18x20Read(uint8_t sensor, float &t) {
uint8_t index = ds18x20_sensor[sensor].index; uint8_t index = ds18x20_sensor[sensor].index;
if (ds18x20_sensor[index].valid) { ds18x20_sensor[index].valid--; } if (ds18x20_sensor[index].valid) { ds18x20_sensor[index].valid--; }
#ifdef DS18x20_MULTI_GPIOs ds = ds18x20_gpios[ds18x20_sensor[index].pins_id];
ds=ds18x20_gpios[ds18x20_sensor[index].pins_id];
#endif
ds->reset(); ds->reset();
ds->select(ds18x20_sensor[index].address); ds->select(ds18x20_sensor[index].address);
ds->write(W1_READ_SCRATCHPAD); // Read Scratchpad ds->write(W1_READ_SCRATCHPAD); // Read Scratchpad
@ -316,7 +292,7 @@ void CmndDSAlias(void) {
uint8_t sensor=255; uint8_t sensor=255;
char argument[XdrvMailbox.data_len]; char argument[XdrvMailbox.data_len];
char address[17]; char address[17];
if (ArgC()==2) { if (ArgC()==2) {
tmp=atoi(ArgV(argument, 2)); tmp=atoi(ArgV(argument, 2));
ArgV(argument,1); ArgV(argument,1);
@ -352,7 +328,7 @@ void CmndDSAlias(void) {
bool Xsns05(uint8_t function) { bool Xsns05(uint8_t function) {
bool result = false; bool result = false;
if (PinUsed(GPIO_DSB,GPIO_ANY)) { if (PinUsed(GPIO_DSB, GPIO_ANY)) {
switch (function) { switch (function) {
case FUNC_INIT: case FUNC_INIT:
Ds18x20Init(); Ds18x20Init();