10 changed files with 298 additions and 0 deletions
@ -0,0 +1,4 @@ |
|||||
|
build/ |
||||
|
sdkconfig |
||||
|
sdkconfig.old |
||||
|
|
||||
@ -0,0 +1,6 @@ |
|||||
|
[submodule "components/esp32-owb"] |
||||
|
path = components/esp32-owb |
||||
|
url = https://github.com/DavidAntliff/esp32-owb |
||||
|
[submodule "components/esp32-ds18b20"] |
||||
|
path = components/esp32-ds18b20 |
||||
|
url = https://github.com/DavidAntliff/esp32-ds18b20 |
||||
@ -0,0 +1,21 @@ |
|||||
|
MIT License |
||||
|
|
||||
|
Copyright (c) 2017 David Antliff |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in all |
||||
|
copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
|
SOFTWARE. |
||||
@ -0,0 +1,9 @@ |
|||||
|
#
|
||||
|
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
|
# project subdirectory.
|
||||
|
#
|
||||
|
|
||||
|
PROJECT_NAME := esp32-ds18b20-example |
||||
|
|
||||
|
include $(IDF_PATH)/make/project.mk |
||||
|
|
||||
@ -0,0 +1,58 @@ |
|||||
|
# ESP32-DS18B20 |
||||
|
|
||||
|
## Introduction |
||||
|
|
||||
|
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 the [ESP-IDF](https://github.com/espressif/esp-idf) environment, using the xtensa-esp32-elf toolchain (gcc version 5.2.0). |
||||
|
|
||||
|
Ensure that submodules are cloned: |
||||
|
|
||||
|
$ git clone --recursive https://github.com/DavidAntliff/esp32-ds18b20-example.git |
||||
|
|
||||
|
Build the application with: |
||||
|
|
||||
|
$ cd esp32-ds18b20-example.git |
||||
|
$ make menuconfig # set your serial configuration and the 1-Wire GPIO - see below |
||||
|
$ make flash monitor |
||||
|
|
||||
|
The program should detect your connected devices and periodically obtain temperature readings from them, displaying them on the console. |
||||
|
|
||||
|
## 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.k kOhms, connected to the 3.3V supply. |
||||
|
|
||||
|
`make menuconfig` can be used to set the 1-Wire GPIO. |
||||
|
|
||||
|
## Features |
||||
|
|
||||
|
This example provides: |
||||
|
|
||||
|
* External power supply mode. |
||||
|
* Static (stack-based) or dynamic (malloc-based) memory model examples. |
||||
|
* No global variables. |
||||
|
* Device search. |
||||
|
* Addressing optimisation for a single (solo) device on a bus. |
||||
|
* CRC checks on ROM code and temperature data. |
||||
|
* Programmable temperature measurement resolution (9, 10, 11 or 12-bit resolution). |
||||
|
* Temperature conversion and retrieval. |
||||
|
* Simultaneous conversion across multiple devices. |
||||
|
|
||||
|
## Source Code |
||||
|
|
||||
|
The source is available from [GitHub](https://www.github.com/DavidAntliff/esp32-ds18b20-example). |
||||
|
|
||||
|
## License |
||||
|
|
||||
|
The code in this project is licensed under the MIT license - see LICENSE for details. |
||||
|
|
||||
|
## Links |
||||
|
|
||||
|
* [DS18B20 Datasheet](http://datasheets.maximintegrated.com/en/ds/DS18B20.pdf) |
||||
|
* [Espressif IoT Development Framework for ESP32](https://github.com/espressif/esp-idf) |
||||
|
|
||||
|
## Acknowledgements |
||||
|
|
||||
|
"1-Wire" is a registered trademark of Maxim Integrated. |
||||
@ -0,0 +1,14 @@ |
|||||
|
menu "esp32-ds18b20-example Configuration" |
||||
|
|
||||
|
config ONE_WIRE_GPIO |
||||
|
int "OneWire GPIO number" |
||||
|
range 0 34 |
||||
|
default 5 |
||||
|
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. |
||||
|
|
||||
|
endmenu |
||||
@ -0,0 +1,179 @@ |
|||||
|
/*
|
||||
|
* MIT License |
||||
|
* |
||||
|
* Copyright (c) 2017 David Antliff |
||||
|
* |
||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||
|
* in the Software without restriction, including without limitation the rights |
||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||
|
* furnished to do so, subject to the following conditions: |
||||
|
* |
||||
|
* The above copyright notice and this permission notice shall be included in all |
||||
|
* copies or substantial portions of the Software. |
||||
|
* |
||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
|
* SOFTWARE. |
||||
|
*/ |
||||
|
|
||||
|
#include <inttypes.h> |
||||
|
|
||||
|
#include "freertos/FreeRTOS.h" |
||||
|
#include "freertos/task.h" |
||||
|
#include "esp_system.h" |
||||
|
#include "esp_log.h" |
||||
|
|
||||
|
// Uncomment to enable static (stack-based) allocation of instances and avoid malloc/free.
|
||||
|
//#define USE_STATIC 1
|
||||
|
|
||||
|
#include "owb.h" |
||||
|
#include "ds18b20.h" |
||||
|
|
||||
|
|
||||
|
#define GPIO_DS18B20_0 (GPIO_NUM_5) |
||||
|
#define MAX_DEVICES (8) |
||||
|
#define DS18B20_RESOLUTION (DS18B20_RESOLUTION_11_BIT) |
||||
|
|
||||
|
void app_main() |
||||
|
{ |
||||
|
esp_log_level_set("*", ESP_LOG_INFO); |
||||
|
|
||||
|
// Create a 1-Wire bus
|
||||
|
#ifdef USE_STATIC |
||||
|
OneWireBus owb_static; // static allocation
|
||||
|
OneWireBus * owb = &owb_static; |
||||
|
#else |
||||
|
OneWireBus * owb = owb_malloc(); // heap allocation
|
||||
|
#endif |
||||
|
|
||||
|
owb_init(owb, GPIO_DS18B20_0); |
||||
|
owb_use_crc(owb, true); // enable CRC check for ROM code
|
||||
|
|
||||
|
// find all connected devices
|
||||
|
printf("Find devices:\n"); |
||||
|
OneWireBus_ROMCode device_rom_codes[MAX_DEVICES] = {0}; |
||||
|
int num_devices = 0; |
||||
|
OneWireBus_SearchState search_state = {0}; |
||||
|
bool found = owb_search_first(owb, &search_state); |
||||
|
while (found) |
||||
|
{ |
||||
|
char rom_code_s[17]; |
||||
|
owb_string_from_rom_code(search_state.rom_code, rom_code_s, sizeof(rom_code_s)); |
||||
|
printf(" %d : %s\n", num_devices, rom_code_s); |
||||
|
device_rom_codes[num_devices] = search_state.rom_code; |
||||
|
++num_devices; |
||||
|
found = owb_search_next(owb, &search_state); |
||||
|
} |
||||
|
|
||||
|
//uint64_t rom_code = 0x0001162e87ccee28; // pink
|
||||
|
//uint64_t rom_code = 0xf402162c6149ee28; // green
|
||||
|
//uint64_t rom_code = 0x1502162ca5b2ee28; // orange
|
||||
|
//uint64_t rom_code = owb_read_rom(owb);
|
||||
|
|
||||
|
// known ROM codes (LSB first):
|
||||
|
OneWireBus_ROMCode known_device = { |
||||
|
.fields.family = { 0x28 }, |
||||
|
.fields.serial_number = { 0xee, 0xcc, 0x87, 0x2e, 0x16, 0x01 }, |
||||
|
.fields.crc = { 0x00 }, |
||||
|
}; |
||||
|
char rom_code_s[17]; |
||||
|
owb_string_from_rom_code(known_device, rom_code_s, sizeof(rom_code_s)); |
||||
|
printf("Device %s is %s\n", rom_code_s, owb_verify_rom(owb, known_device) ? "present" : "not present"); |
||||
|
|
||||
|
// Create a DS18B20 device on the 1-Wire bus
|
||||
|
#ifdef USE_STATIC |
||||
|
DS18B20_Info devices_static[MAX_DEVICES] = {0}; |
||||
|
DS18B20_Info * devices[MAX_DEVICES] = {0}; |
||||
|
for (int i = 0; i < MAX_DEVICES; ++i) |
||||
|
{ |
||||
|
devices[i] = &(devices_static[i]); |
||||
|
} |
||||
|
#else |
||||
|
DS18B20_Info * devices[MAX_DEVICES] = {0}; |
||||
|
#endif |
||||
|
|
||||
|
for (int i = 0; i < num_devices; ++i) |
||||
|
{ |
||||
|
#ifdef USE_STATIC |
||||
|
DS18B20_Info * ds18b20_info = devices[i]; |
||||
|
#else |
||||
|
DS18B20_Info * ds18b20_info = ds18b20_malloc(); // heap allocation
|
||||
|
devices[i] = ds18b20_info; |
||||
|
#endif |
||||
|
if (num_devices == 1) |
||||
|
{ |
||||
|
printf("Single device optimisations enabled\n"); |
||||
|
ds18b20_init_solo(ds18b20_info, owb); // only one device on bus
|
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
ds18b20_init(ds18b20_info, owb, device_rom_codes[i]); // associate with bus and device
|
||||
|
} |
||||
|
ds18b20_use_crc(ds18b20_info, true); // enable CRC check for temperature readings
|
||||
|
ds18b20_set_resolution(ds18b20_info, DS18B20_RESOLUTION); |
||||
|
} |
||||
|
|
||||
|
// // read temperatures from all sensors sequentially
|
||||
|
// while (1)
|
||||
|
// {
|
||||
|
// printf("\nTemperature readings (degrees C):\n");
|
||||
|
// for (int i = 0; i < num_devices; ++i)
|
||||
|
// {
|
||||
|
// float temp = ds18b20_get_temp(devices[i]);
|
||||
|
// printf(" %d: %.3f\n", i, temp);
|
||||
|
// }
|
||||
|
// vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
|
// }
|
||||
|
|
||||
|
// read temperatures more efficiently by starting conversions on all devices at the same time
|
||||
|
if (num_devices > 0) |
||||
|
{ |
||||
|
while (1) |
||||
|
{ |
||||
|
TickType_t start_ticks = 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]); |
||||
|
|
||||
|
// read the results immediately after conversion otherwise it may fail
|
||||
|
// (using printf before reading may take too long)
|
||||
|
float temps[MAX_DEVICES] = { 0 }; |
||||
|
for (int i = 0; i < num_devices; ++i) |
||||
|
{ |
||||
|
temps[i] = ds18b20_read_temp(devices[i]); |
||||
|
} |
||||
|
|
||||
|
// print results in a separate loop, after all have been read
|
||||
|
printf("\nTemperature readings (degrees C):\n"); |
||||
|
for (int i = 0; i < num_devices; ++i) |
||||
|
{ |
||||
|
printf(" %d: %.1f\n", i, temps[i]); |
||||
|
} |
||||
|
|
||||
|
// make up delay to approximately 1 second per measurement
|
||||
|
vTaskDelay(1000 / portTICK_PERIOD_MS - (xTaskGetTickCount() - start_ticks)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#ifndef USE_STATIC |
||||
|
// clean up dynamically allocated data
|
||||
|
for (int i = 0; i < num_devices; ++i) |
||||
|
{ |
||||
|
ds18b20_free(&devices[i]); |
||||
|
} |
||||
|
owb_free(&owb); |
||||
|
#endif |
||||
|
|
||||
|
printf("Restarting now.\n"); |
||||
|
fflush(stdout); |
||||
|
esp_restart(); |
||||
|
} |
||||
@ -0,0 +1,5 @@ |
|||||
|
#
|
||||
|
# "main" pseudo-component makefile.
|
||||
|
#
|
||||
|
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
|
||||
Loading…
Reference in new issue