From 19d8b0e625e9e088800b02d56f0f6c198cce8a81 Mon Sep 17 00:00:00 2001 From: David Antliff Date: Thu, 23 Apr 2020 15:36:45 +1200 Subject: [PATCH 1/4] Support for parasitic power - WIP. --- CMakeLists.txt | 2 +- components/esp32-ds18b20 | 2 +- main/app_main.c | 25 +++++++++++++++++++------ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 31da009..f0e3c48 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.5) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(esp32-ds18b20-example) +project(esp32-ds18b20-example LANGUAGES C) if (NOT IDF_VERSION_MAJOR) set(IDF_VERSION_MAJOR 3) diff --git a/components/esp32-ds18b20 b/components/esp32-ds18b20 index d76b70c..ae81f86 160000 --- a/components/esp32-ds18b20 +++ b/components/esp32-ds18b20 @@ -1 +1 @@ -Subproject commit d76b70c0a795adbbd1b9d1b3e2789b455cfd945d +Subproject commit ae81f86e0ee1cd65b6d6a2ad59deb7ba295ab3c4 diff --git a/main/app_main.c b/main/app_main.c index d0705ec..14c99b9 100644 --- a/main/app_main.c +++ b/main/app_main.c @@ -22,8 +22,6 @@ * SOFTWARE. */ -#include - #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" @@ -38,10 +36,11 @@ #define DS18B20_RESOLUTION (DS18B20_RESOLUTION_12_BIT) #define SAMPLE_PERIOD (1000) // milliseconds -void app_main() +_Noreturn void app_main() { // Override global log level esp_log_level_set("*", ESP_LOG_INFO); + esp_log_level_set("*", ESP_LOG_DEBUG); // To debug, use 'make menuconfig' to set default Log level to DEBUG, then uncomment: //esp_log_level_set("owb", ESP_LOG_DEBUG); @@ -150,6 +149,14 @@ void app_main() // vTaskDelay(1000 / portTICK_PERIOD_MS); // } + // Check for parasitic-powered devices that require a strong-pullup + bool require_strong_pullup = false; + ds18b20_check_for_parasite_power(owb, &require_strong_pullup); + printf("Strong pullup (parasitic power) %srequired\n", require_strong_pullup ? "" : "not "); + if (require_strong_pullup) + { + } + // Read temperatures more efficiently by starting conversions on all devices at the same time int errors_count[MAX_DEVICES] = {0}; int sample_count = 0; @@ -157,15 +164,21 @@ void app_main() { TickType_t last_wake_time = xTaskGetTickCount(); - while (1) - { + while (1) { last_wake_time = xTaskGetTickCount(); ds18b20_convert_all(owb); // In this application all devices use the same resolution, // so use the first device to determine the delay - ds18b20_wait_for_conversion(devices[0]); + if (require_strong_pullup) { + ets_delay_us(750000); + gpio_set_level(5, 0); + } + else + { + ds18b20_wait_for_conversion(devices[0]); + } // Read the results immediately after conversion otherwise it may fail // (using printf before reading may take too long) From cacfc57e9fac9a86e18cefabfbbadd0f6c34f453 Mon Sep 17 00:00:00 2001 From: David Antliff Date: Thu, 23 Apr 2020 18:08:39 +1200 Subject: [PATCH 2/4] Add support for Parasitic Power mode, including secondary GPIO control of external "strong pull-up" circuit. --- README.md | 25 +++++++++++++++++++------ components/esp32-ds18b20 | 2 +- components/esp32-owb | 2 +- main/Kconfig.projbuild | 38 +++++++++++++++++++++++++++++++++++--- main/app_main.c | 34 ++++++++++++++++++---------------- sdkconfig.defaults | 4 ++++ 6 files changed, 78 insertions(+), 27 deletions(-) create mode 100644 sdkconfig.defaults diff --git a/README.md b/README.md index c4ed2f6..0fba9e5 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,13 @@ ## Introduction -This is an example application for the Maxim Integrated DS18B20 Programmable Resolution 1-Wire Digital Thermometer device. +This is an example application for the Maxim Integrated DS18B20 Programmable Resolution 1-Wire Digital Thermometer +device. It supports a single or multiple devices on the same 1-Wire bus. -It is written and tested for v3.3 of the [ESP-IDF](https://github.com/espressif/esp-idf) environment, using the xtensa-esp32-elf toolchain (gcc version 5.2.0, crosstool-ng-1.22.0-80-g6c4433a). +It is written and tested for v3.3 and v4.1-beta1 of the [ESP-IDF](https://github.com/espressif/esp-idf) environment, +using the xtensa-esp32-elf toolchain (gcc version 5.2.0, crosstool-ng-1.22.0-80-g6c4433a). Ensure that submodules are cloned: @@ -23,7 +25,8 @@ Build the application with: $ idf.py build $ idf.py -p (PORT) flash monitor -The program should detect your connected devices and periodically obtain temperature readings from them, displaying them on the console. +The program should detect your connected devices and periodically obtain temperature readings from them, displaying them +on the console. ## Dependencies @@ -34,17 +37,27 @@ This application makes use of the following components (included as submodules): ## Hardware -To run this example, connect one or more DS18B20 devices to a single GPIO on the ESP32. Use the recommended pull-up resistor of 4.7 KOhms, connected to the 3.3V supply. +To run this example, connect one or more DS18B20 devices to a single GPIO on the ESP32. Use the recommended pull-up +resistor of 4.7 KOhms, connected to the 3.3V supply. `idf.py menuconfig` can be used to set the 1-Wire GPIO. -If you have several devices and see occasional CRC errors, consider using a 2.2 kOhm pull-up resistor instead. Also consider adding decoupling capacitors between the sensor supply voltage and ground, as close to each sensor as possible. +If you have several devices and see occasional CRC errors, consider using a 2.2 kOhm pull-up resistor instead. Also +consider adding decoupling capacitors between the sensor supply voltage and ground, as close to each sensor as possible. + +If you wish to enable a second GPIO to control an external strong pull-up circuit for parasitic power mode, ensure +`CONFIG_ENABLE_STRONG_PULLUP=y` and `CONFIG_STRONG_PULLUP_GPIO` is set appropriately. + +See documentation for [esp32-ds18b20](https://www.github.com/DavidAntliff/esp32-ds18b20-example#parasitic-power-mode) +for further information about parasitic power mode, including strong pull-up configuration. + ## Features This example provides: - * External power supply mode. + * External power supply detection. + * Parasitic power supply detection. * Static (stack-based) or dynamic (malloc-based) memory model examples. * No global variables. * Device search. diff --git a/components/esp32-ds18b20 b/components/esp32-ds18b20 index ae81f86..e763961 160000 --- a/components/esp32-ds18b20 +++ b/components/esp32-ds18b20 @@ -1 +1 @@ -Subproject commit ae81f86e0ee1cd65b6d6a2ad59deb7ba295ab3c4 +Subproject commit e763961d445263cdfc93d0fe516f917ba95a43e1 diff --git a/components/esp32-owb b/components/esp32-owb index af25dd3..c678bad 160000 --- a/components/esp32-owb +++ b/components/esp32-owb @@ -1 +1 @@ -Subproject commit af25dd31dbb1e80364b99fad29815badfab0ceda +Subproject commit c678bad2af657359ebdab90473df2f65ff5ac83d diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild index 27da83c..189c66b 100644 --- a/main/Kconfig.projbuild +++ b/main/Kconfig.projbuild @@ -2,13 +2,45 @@ menu "esp32-ds18b20-example Configuration" config ONE_WIRE_GPIO int "OneWire GPIO number" - range 0 34 - default 5 + range 0 33 + default 4 help GPIO number (IOxx) to access One Wire Bus. Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used. - GPIOs 35-39 are input-only so cannot be used to drive the One Wire Bus. + GPIOs 34-39 are input-only so cannot be used to drive the One Wire Bus. + +config ENABLE_STRONG_PULLUP_GPIO + bool "Enable strong pull-up controlled by GPIO (MOSFET)" + default n + help + An external circuit can be used to provide a strong pull-up to the One Wire Bus. + This is useful when the bus has parasitic-powered devices and extra current is + required to power them, such as during temperature ADC conversions. + + An example of such a circuit for the ESP32 is a P-channel MOSFET (such as the BS250) + connected Source-to-Drain between a current-limiting resistor (e.g. 270ohm for 12mA + max at 3.3V), itself connected to VCC, and the One Wire Bus data line. The Gate is + connected to the GPIO specified here. + +config STRONG_PULLUP_GPIO + int "Strong pull-up GPIO number" + range 0 33 + default 5 + help + GPIO number (IOxx) to control the strong pull-up on the One Wire Bus, perhaps + via a P-channel MOSFET between VCC and the One Wire Bus data line. + + This GPIO will be set as an output and driven high during temperature conversion. + This would enable the MOSFET providing current to the devices. + + At all other times it will be driven low, switching off the MOSFET and allowing + the One Wire Bus to operate normally. + + Some GPIOs are used for other purposes (flash connections, etc.) and cannot be used. + + GPIOs 34-39 are input-only so cannot be used to drive the One Wire Bus. + depends on ENABLE_STRONG_PULLUP_GPIO endmenu diff --git a/main/app_main.c b/main/app_main.c index 14c99b9..e8bfafd 100644 --- a/main/app_main.c +++ b/main/app_main.c @@ -40,7 +40,6 @@ _Noreturn void app_main() { // Override global log level esp_log_level_set("*", ESP_LOG_INFO); - esp_log_level_set("*", ESP_LOG_DEBUG); // To debug, use 'make menuconfig' to set default Log level to DEBUG, then uncomment: //esp_log_level_set("owb", ESP_LOG_DEBUG); @@ -149,14 +148,23 @@ _Noreturn void app_main() // vTaskDelay(1000 / portTICK_PERIOD_MS); // } - // Check for parasitic-powered devices that require a strong-pullup - bool require_strong_pullup = false; - ds18b20_check_for_parasite_power(owb, &require_strong_pullup); - printf("Strong pullup (parasitic power) %srequired\n", require_strong_pullup ? "" : "not "); - if (require_strong_pullup) - { + // Check for parasitic-powered devices + bool parasitic_power = false; + ds18b20_check_for_parasite_power(owb, ¶sitic_power); + if (parasitic_power) { + printf("Parasitic-powered devices detected"); } + // In parasitic-power mode, devices cannot indicate when conversions are complete, + // so waiting for a temperature conversion must be done by waiting a prescribed duration + owb_use_parasitic_power(owb, parasitic_power); + +#ifdef CONFIG_ENABLE_STRONG_PULLUP_GPIO + // An external pull-up circuit is used to supply extra current to OneWireBus devices + // during temperature conversions. + owb_use_strong_pullup_gpio(owb, CONFIG_STRONG_PULLUP_GPIO); +#endif + // Read temperatures more efficiently by starting conversions on all devices at the same time int errors_count[MAX_DEVICES] = {0}; int sample_count = 0; @@ -164,21 +172,15 @@ _Noreturn void app_main() { TickType_t last_wake_time = xTaskGetTickCount(); - while (1) { + while (1) + { last_wake_time = xTaskGetTickCount(); ds18b20_convert_all(owb); // In this application all devices use the same resolution, // so use the first device to determine the delay - if (require_strong_pullup) { - ets_delay_us(750000); - gpio_set_level(5, 0); - } - else - { - ds18b20_wait_for_conversion(devices[0]); - } + ds18b20_wait_for_conversion(devices[0]); // Read the results immediately after conversion otherwise it may fail // (using printf before reading may take too long) diff --git a/sdkconfig.defaults b/sdkconfig.defaults new file mode 100644 index 0000000..4a89088 --- /dev/null +++ b/sdkconfig.defaults @@ -0,0 +1,4 @@ +# +# Log output +# +CONFIG_LOG_DEFAULT_LEVEL=4 From 4d397f97d2892c3592217ae8ad95aaa710fd989a Mon Sep 17 00:00:00 2001 From: David Antliff Date: Thu, 23 Apr 2020 19:24:21 +1200 Subject: [PATCH 3/4] Use relative URLs for submodules. --- .gitmodules | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.gitmodules b/.gitmodules index b6b1986..01573de 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,7 +1,6 @@ [submodule "components/esp32-owb"] - path = components/esp32-owb - url = https://github.com/DavidAntliff/esp32-owb + path = components/esp32-owb + url = ../esp32-owb [submodule "components/esp32-ds18b20"] path = components/esp32-ds18b20 - url = https://github.com/DavidAntliff/esp32-ds18b20 - + url = ../esp32-ds18b20 From 30c9bfeefb587f30151d2ffb2935c888c0b8950e Mon Sep 17 00:00:00 2001 From: David Antliff Date: Thu, 23 Apr 2020 19:46:06 +1200 Subject: [PATCH 4/4] Update esp32-owb component. --- components/esp32-owb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/esp32-owb b/components/esp32-owb index c678bad..316296a 160000 --- a/components/esp32-owb +++ b/components/esp32-owb @@ -1 +1 @@ -Subproject commit c678bad2af657359ebdab90473df2f65ff5ac83d +Subproject commit 316296a398e44976a5abdd7d70f8c21ad2cec09d