From 9f4a609964c47108697a9a43d055a3d3a9951a3d Mon Sep 17 00:00:00 2001 From: Nicolas MASSE Date: Mon, 6 Jun 2022 11:13:52 +0200 Subject: [PATCH] add ledc --- .gitmodules | 6 ++- .travis.yml | 37 --------------- README.md | 55 ++-------------------- main/app_main.c | 122 ++++++++++++++++++++++++++---------------------- 4 files changed, 75 insertions(+), 145 deletions(-) delete mode 100644 .travis.yml diff --git a/.gitmodules b/.gitmodules index 01573de..dc50576 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,8 @@ [submodule "components/esp32-owb"] path = components/esp32-owb - url = ../esp32-owb + url = https://github.com/DavidAntliff/esp32-owb.git + branch = master [submodule "components/esp32-ds18b20"] path = components/esp32-ds18b20 - url = ../esp32-ds18b20 + url = https://github.com/DavidAntliff/esp32-ds18b20.git + branch = master diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 397e57e..0000000 --- a/.travis.yml +++ /dev/null @@ -1,37 +0,0 @@ -os: linux -dist: bionic -language: python -python: "3.8" - -jobs: - include: - - stage: # IDF v3.3 - install: - # Install ESP32 toochain following steps as described - # in http://esp-idf.readthedocs.io/en/latest/linux-setup.html - # - # Download binary toolchain for the ESP32 - - pushd ~ - - wget https://dl.espressif.com/dl/xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz - - tar -xzf xtensa-esp32-elf-linux64-1.22.0-80-g6c4433a-5.2.0.tar.gz - # Make xtensa-esp32-elf available for all terminal sessions - - export PATH=$PATH:$(pwd)/xtensa-esp32-elf/bin - # Get ESP-IDF from github - - git clone --recursive --branch v3.3 --single-branch --shallow-submodules https://github.com/espressif/esp-idf.git esp-idf - # Set the path to ESP-IDF directory - - export IDF_PATH=$(pwd)/esp-idf - # Install python dependencies - - pip install --requirement $IDF_PATH/requirements.txt - - popd - script: - - $IDF_PATH/tools/idf.py build - - - stage: # IDF v4.1-beta1 - install: - - pushd ~ - - git clone --recursive --branch v4.1-beta1 --single-branch --shallow-submodules https://github.com/espressif/esp-idf.git esp-idf - - esp-idf/install.sh - - popd - script: - - source ~/esp-idf/export.sh && idf.py build - diff --git a/README.md b/README.md index 0fba9e5..ebb81af 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,17 @@ -# esp32-ds18b20-example - -[![Platform: ESP-IDF](https://img.shields.io/badge/ESP--IDF-v3.0%2B-blue.svg)](https://docs.espressif.com/projects/esp-idf/en/stable/get-started/) -[![Build Status](https://travis-ci.org/DavidAntliff/esp32-ds18b20-example.svg?branch=master)](https://travis-ci.org/DavidAntliff/esp32-ds18b20-example) -[![license](https://img.shields.io/github/license/mashape/apistatus.svg)]() +# esp32-ds18b20-ledc ## 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 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). +device and LEDs. Ensure that submodules are cloned: - $ git clone --recursive https://github.com/DavidAntliff/esp32-ds18b20-example.git + $ git clone --recursive https://github.com/nmasse-itix/esp32-ds18b20-ledc.git Build the application with: - $ cd esp32-ds18b20-example + $ cd esp32-ds18b20-ledc $ idf.py menuconfig # set your serial configuration and the 1-Wire GPIO - see below $ idf.py build $ idf.py -p (PORT) flash monitor @@ -42,43 +33,7 @@ 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 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 detection. - * Parasitic power supply detection. - * 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) +Connect two leds on GPIO 19 and 21 with a small resistor (69 ohms). ## Acknowledgements diff --git a/main/app_main.c b/main/app_main.c index 68d8024..e65c1a7 100644 --- a/main/app_main.c +++ b/main/app_main.c @@ -27,6 +27,9 @@ #include "esp_system.h" #include "esp_log.h" +#include "driver/gpio.h" +#include "driver/ledc.h" + #include "owb.h" #include "owb_rmt.h" #include "ds18b20.h" @@ -36,6 +39,57 @@ #define DS18B20_RESOLUTION (DS18B20_RESOLUTION_12_BIT) #define SAMPLE_PERIOD (1000) // milliseconds +static void led_task(void *pvParameters) { + // Prepare and then apply the LEDC PWM timer configuration + ledc_timer_config_t ledc_timer_0 = { + .speed_mode = LEDC_HIGH_SPEED_MODE, + .timer_num = LEDC_TIMER_0, + .duty_resolution = LEDC_TIMER_8_BIT, + .freq_hz = 1000, // Set output frequency at 5 kHz + .clk_cfg = LEDC_AUTO_CLK + }; + ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer_0)); + + // Prepare and then apply the LEDC PWM channel configuration + ledc_channel_config_t ledc_channel_1 = { + .speed_mode = LEDC_HIGH_SPEED_MODE, + .channel = LEDC_CHANNEL_0, + .timer_sel = LEDC_TIMER_0, + .intr_type = LEDC_INTR_DISABLE, + .gpio_num = GPIO_NUM_19, + .duty = 0, // Set duty to 0% + .hpoint = 0 + }; + ledc_channel_config_t ledc_channel_2 = { + .speed_mode = LEDC_HIGH_SPEED_MODE, + .channel = LEDC_CHANNEL_1, + .timer_sel = LEDC_TIMER_0, + .intr_type = LEDC_INTR_DISABLE, + .gpio_num = GPIO_NUM_21, + .duty = 0, // Set duty to 0% + .hpoint = 0 + }; + ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_1)); + ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel_2)); + + int steps[] = { + 0, 16, 32, 48, 64, 80, 96, 112, 128, 128, 112, 96, 80, 64, 48, 32, 16, 0 + }; + int n_steps = sizeof(steps) / sizeof(steps[0]); + for (;;) { + for (int i = 0; i < n_steps; i++) { + // Wait 10s and update the duty cycle + vTaskDelay(100.0 / portTICK_PERIOD_MS); + ESP_ERROR_CHECK(ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, steps[i])); + ESP_ERROR_CHECK(ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1, steps[(i+4)%n_steps])); + ESP_ERROR_CHECK(ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0)); + ESP_ERROR_CHECK(ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1)); + } + } + + vTaskDelete(NULL); +} + _Noreturn void app_main() { // Override global log level @@ -45,6 +99,18 @@ _Noreturn void app_main() //esp_log_level_set("owb", ESP_LOG_DEBUG); //esp_log_level_set("ds18b20", ESP_LOG_DEBUG); + BaseType_t xReturned; + xReturned = xTaskCreate(led_task, + "led_task", + 4096, /* Stack size in words, not bytes. */ + NULL, /* Parameter passed into the task. */ + tskIDLE_PRIORITY + 12, + NULL); + if (xReturned != pdPASS) { + ESP_LOGE("led", "xTaskCreate('led_task'): %d", xReturned); + abort(); + } + // Stable readings require a brief period before communication vTaskDelay(2000.0 / portTICK_PERIOD_MS); @@ -72,50 +138,6 @@ _Noreturn void app_main() } printf("Found %d device%s\n", num_devices, num_devices == 1 ? "" : "s"); - // In this example, if a single device is present, then the ROM code is probably - // not very interesting, so just print it out. If there are multiple devices, - // then it may be useful to check that a specific device is present. - - if (num_devices == 1) - { - // For a single device only: - OneWireBus_ROMCode rom_code; - owb_status status = owb_read_rom(owb, &rom_code); - if (status == OWB_STATUS_OK) - { - char rom_code_s[OWB_ROM_CODE_STRING_LENGTH]; - owb_string_from_rom_code(rom_code, rom_code_s, sizeof(rom_code_s)); - printf("Single device %s present\n", rom_code_s); - } - else - { - printf("An error occurred reading ROM code: %d", status); - } - } - else - { - // Search for a known ROM code (LSB first): - // For example: 0x1502162ca5b2ee28 - OneWireBus_ROMCode known_device = { - .fields.family = { 0x28 }, - .fields.serial_number = { 0xee, 0xb2, 0xa5, 0x2c, 0x16, 0x02 }, - .fields.crc = { 0x15 }, - }; - char rom_code_s[OWB_ROM_CODE_STRING_LENGTH]; - owb_string_from_rom_code(known_device, rom_code_s, sizeof(rom_code_s)); - bool is_present = false; - - owb_status search_status = owb_verify_rom(owb, known_device, &is_present); - if (search_status == OWB_STATUS_OK) - { - printf("Device %s is %s\n", rom_code_s, is_present ? "present" : "not present"); - } - else - { - printf("An error occurred searching for known device: %d", search_status); - } - } - // Create DS18B20 devices on the 1-Wire bus DS18B20_Info * devices[MAX_DEVICES] = {0}; for (int i = 0; i < num_devices; ++i) @@ -136,18 +158,6 @@ _Noreturn void app_main() 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); -// } - // Check for parasitic-powered devices bool parasitic_power = false; ds18b20_check_for_parasite_power(owb, ¶sitic_power);