Browse Source

Add support for Parasitic Power mode, including secondary GPIO control of external "strong pull-up" circuit.

main
David Antliff 6 years ago
parent
commit
cacfc57e9f
  1. 25
      README.md
  2. 2
      components/esp32-ds18b20
  3. 2
      components/esp32-owb
  4. 38
      main/Kconfig.projbuild
  5. 34
      main/app_main.c
  6. 4
      sdkconfig.defaults

25
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.

2
components/esp32-ds18b20

@ -1 +1 @@
Subproject commit ae81f86e0ee1cd65b6d6a2ad59deb7ba295ab3c4
Subproject commit e763961d445263cdfc93d0fe516f917ba95a43e1

2
components/esp32-owb

@ -1 +1 @@
Subproject commit af25dd31dbb1e80364b99fad29815badfab0ceda
Subproject commit c678bad2af657359ebdab90473df2f65ff5ac83d

38
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

34
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, &parasitic_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)

4
sdkconfig.defaults

@ -0,0 +1,4 @@
#
# Log output
#
CONFIG_LOG_DEFAULT_LEVEL=4
Loading…
Cancel
Save