Browse Source

add ledc

main
Nicolas Massé 4 years ago
parent
commit
9f4a609964
  1. 6
      .gitmodules
  2. 37
      .travis.yml
  3. 55
      README.md
  4. 122
      main/app_main.c

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

37
.travis.yml

@ -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

55
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

122
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, &parasitic_power);

Loading…
Cancel
Save