new meter

This commit is contained in:
2025-06-14 11:46:10 +01:00
parent 6f95c7ba59
commit a0b2e048d4
20 changed files with 17741 additions and 74 deletions

735
projeto_parte6.c Executable file
View File

@@ -0,0 +1,735 @@
// === Início de: components/network/include/wifi.h ===
#ifndef WIFI_H_
#define WIFI_H_
#include <stdbool.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_err.h"
#include "esp_netif.h"
#define WIFI_SCAN_SCAN_LIST_SIZE 10
#define WIFI_AP_CONNECTED_BIT BIT0
#define WIFI_AP_DISCONNECTED_BIT BIT1
#define WIFI_STA_CONNECTED_BIT BIT2
#define WIFI_STA_DISCONNECTED_BIT BIT3
#define WIFI_AP_MODE_BIT BIT4
#define WIFI_STA_MODE_BIT BIT5
typedef struct
{
char ssid[32];
int rssi;
bool auth;
} wifi_scan_ap_t;
/**
* @brief WiFi event group WIFI_AP_CONNECTED_BIT | WIFI_AP_DISCONNECTED_BIT | WIFI_STA_CONNECTED_BIT | WIFI_STA_DISCONNECTED_BIT | WIFI_AP_MODE_BIT | WIFI_STA_MODE_BIT
*
*/
extern EventGroupHandle_t wifi_event_group;
/**
* @brief Initialize WiFi
*
*/
void wifi_ini(void);
/**
* @brief Return WiFi STA network interface
*
* @return esp_netif_t*
*/
esp_netif_t* wifi_get_sta_netif(void);
/**
* @brief Return WiFi AP network interface
*
* @return esp_netif_t*
*/
esp_netif_t* wifi_get_ap_netif(void);
/**
* @brief Set WiFi config
*
* @param enabled
* @param ssid NULL value will be skiped
* @param password NULL value will be skiped
* @return esp_err_t
*/
esp_err_t wifi_set_config(bool enabled, const char* ssid, const char* password);
/**
* @brief Get WiFi STA enabled, stored in NVS
*
* @return true
* @return false
*/
bool wifi_get_enabled(void);
/**
* @brief Scan for AP
*
* @param scan_aps array with length WIFI_SCAN_SCAN_LIST_SIZE
* @return uint16_t number of available AP
*/
uint16_t wifi_scan(wifi_scan_ap_t *scan_aps);
/**
* @brief Get WiFi STA ssid, string length 32, stored in NVS
*
* @param value
*/
void wifi_get_ssid(char* value);
/**
* @brief Get WiFi STA password, string length 32, stored in NVS
*
* @param value
*/
void wifi_get_password(char* value);
/**
* @brief Start WiFi AP mode
*
*/
void wifi_ap_start(void);
/**
* @brief Stop WiFi AP mode
*
*/
void wifi_ap_stop(void);
#endif /* WIFI_H_ */
// === Fim de: components/network/include/wifi.h ===
// === Início de: components/peripherals/src/ac_relay.c ===
#include "esp_log.h"
#include "driver/gpio.h"
#include "ac_relay.h"
#include "board_config.h"
static const char* TAG = "ac_relay";
/**
* @brief Initialize the AC relay GPIO.
*
* Configures the specified GPIO pin as an output and sets its initial state to OFF (low).
*/
void ac_relay_init(void)
{
gpio_config_t conf = {
.pin_bit_mask = BIT64(board_config.ac_relay_gpio),
.mode = GPIO_MODE_OUTPUT,
.pull_down_en = GPIO_PULLDOWN_DISABLE, ///< Disabled unless required
.pull_up_en = GPIO_PULLUP_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
esp_err_t ret = gpio_config(&conf);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to configure GPIO (error: %s)", esp_err_to_name(ret));
return;
}
gpio_set_level(board_config.ac_relay_gpio, false); ///< Ensure relay starts OFF
ESP_LOGI(TAG, "AC relay initialized. Pin: %d", board_config.ac_relay_gpio);
}
/**
* @brief Set the state of the AC relay.
*
* @param state True to turn the relay ON, False to turn it OFF.
*/
void ac_relay_set_state(bool state)
{
ESP_LOGI(TAG, "Setting AC relay state: Pin: %d, State: %d", board_config.ac_relay_gpio, state);
esp_err_t ret = gpio_set_level(board_config.ac_relay_gpio, state);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to set GPIO level (error: %s)", esp_err_to_name(ret));
}
}
/**
* @brief Get the current state of the AC relay.
*
* @return true if the relay is ON, false if OFF.
*/
bool ac_relay_get_state(void)
{
int level = gpio_get_level(board_config.ac_relay_gpio);
ESP_LOGD(TAG, "Current AC relay state: Pin: %d, State: %d", board_config.ac_relay_gpio, level);
return level;
}
// === Fim de: components/peripherals/src/ac_relay.c ===
// === Início de: components/peripherals/src/ntc_sensor.c ===
#include <sys/param.h>
#include <freertos/FreeRTOS.h>
#include "freertos/task.h"
#include "esp_log.h"
#include "ntc_sensor.h"
#include "ntc_driver.h"
#include "adc.h"
static const char *TAG = "temp_sensor";
#define MEASURE_PERIOD 15000 // 10s
static float temp = 0.0;
static ntc_device_handle_t ntc = NULL;
static portMUX_TYPE temp_mux = portMUX_INITIALIZER_UNLOCKED;
static void ntc_sensor_task_func(void *param) {
float t;
while (true) {
if (ntc_dev_get_temperature(ntc, &t) == ESP_OK) {
portENTER_CRITICAL(&temp_mux);
temp = t;
portEXIT_CRITICAL(&temp_mux);
}
vTaskDelay(pdMS_TO_TICKS(MEASURE_PERIOD));
}
}
float ntc_temp_sensor(void) {
float t;
portENTER_CRITICAL(&temp_mux);
t = temp;
portEXIT_CRITICAL(&temp_mux);
return t;
}
void ntc_sensor_init(void)
{
ESP_LOGI(TAG, "ntc_sensor_init");
// Select the NTC sensor and initialize the hardware parameters
ntc_config_t ntc_config = {
.b_value = 3950,
.r25_ohm = 10000,
.fixed_ohm = 4700,
.vdd_mv = 3300,
.circuit_mode = CIRCUIT_MODE_NTC_GND,
.atten = ADC_ATTEN_DB_12,
.channel = ADC_CHANNEL_0,
.unit = ADC_UNIT_1};
// Create the NTC Driver and Init ADC
// ntc_device_handle_t ntc = NULL;
// adc_oneshot_unit_handle_t adc_handle = NULL;
ESP_ERROR_CHECK(ntc_dev_create(&ntc_config, &ntc, &adc_handle));
ESP_ERROR_CHECK(ntc_dev_get_adc_handle(ntc, &adc_handle));
xTaskCreate(ntc_sensor_task_func, "ntc_sensor_task", 5 * 1024, NULL, 3, NULL);
}
// === Fim de: components/peripherals/src/ntc_sensor.c ===
// === Início de: components/peripherals/src/proximity.c ===
#include "esp_log.h"
#include "proximity.h"
#include "board_config.h"
#include "adc.h"
static const char *TAG = "proximity";
void proximity_init(void)
{
if (board_config.proximity)
{
adc_oneshot_chan_cfg_t config = {
.bitwidth = ADC_BITWIDTH_DEFAULT,
.atten = ADC_ATTEN_DB_12};
ESP_ERROR_CHECK(adc_oneshot_config_channel(adc_handle, board_config.proximity_adc_channel, &config));
}
}
uint8_t proximity_get_max_current(void)
{
int voltage;
adc_oneshot_read(adc_handle, board_config.proximity_adc_channel, &voltage);
adc_cali_raw_to_voltage(adc_cali_handle, voltage, &voltage);
ESP_LOGI(TAG, "Measured: %dmV", voltage);
uint8_t current;
if (voltage >= board_config.proximity_down_threshold_8)
{
current = 8;
}
else if (voltage >= board_config.proximity_down_threshold_10)
{
current = 10;
}
else if (voltage >= board_config.proximity_down_threshold_13)
{
current = 13;
}
else if (voltage >= board_config.proximity_down_threshold_20)
{
current = 20;
}
else if (voltage >= board_config.proximity_down_threshold_25)
{
current = 25;
}
else if (voltage >= board_config.proximity_down_threshold_32)
{
current = 32;
}
else
{
current = 32;
}
ESP_LOGI(TAG, "Max current: %dA", current);
return current;
}
// === Fim de: components/peripherals/src/proximity.c ===
// === Início de: components/peripherals/src/buzzer.c ===
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include "board_config.h"
#include "buzzer.h"
#include "evse_api.h"
static gpio_num_t buzzer_gpio = GPIO_NUM_NC;
static evse_state_t last_buzzer_state = -1;
static QueueHandle_t buzzer_queue = NULL;
void buzzer_on(void) {
if (buzzer_gpio != GPIO_NUM_NC)
gpio_set_level(buzzer_gpio, 1);
}
void buzzer_off(void) {
if (buzzer_gpio != GPIO_NUM_NC)
gpio_set_level(buzzer_gpio, 0);
}
// ----------------------
// Padrões de Buzzer
// ----------------------
typedef struct {
uint16_t on_ms;
uint16_t off_ms;
} buzzer_pattern_step_t;
typedef enum {
BUZZER_PATTERN_NONE = 0,
BUZZER_PATTERN_PLUGGED,
BUZZER_PATTERN_UNPLUGGED,
BUZZER_PATTERN_CHARGING,
} buzzer_pattern_id_t;
static const buzzer_pattern_step_t pattern_plugged[] = {
{100, 100}, {200, 0}
};
static const buzzer_pattern_step_t pattern_unplugged[] = {
{150, 150}, {150, 150}, {150, 0}
};
static const buzzer_pattern_step_t pattern_charging[] = {
{80, 150}, {100, 120}, {120, 100}, {140, 0}
};
// ----------------------
// Executor de padrões
// ----------------------
static void buzzer_execute_pattern(buzzer_pattern_id_t pattern_id) {
const buzzer_pattern_step_t *pattern = NULL;
size_t length = 0;
switch (pattern_id) {
case BUZZER_PATTERN_PLUGGED:
pattern = pattern_plugged;
length = sizeof(pattern_plugged) / sizeof(pattern_plugged[0]);
break;
case BUZZER_PATTERN_UNPLUGGED:
pattern = pattern_unplugged;
length = sizeof(pattern_unplugged) / sizeof(pattern_unplugged[0]);
break;
case BUZZER_PATTERN_CHARGING:
pattern = pattern_charging;
length = sizeof(pattern_charging) / sizeof(pattern_charging[0]);
break;
default:
return;
}
for (size_t i = 0; i < length; i++) {
buzzer_on();
vTaskDelay(pdMS_TO_TICKS(pattern[i].on_ms));
buzzer_off();
if (pattern[i].off_ms > 0)
vTaskDelay(pdMS_TO_TICKS(pattern[i].off_ms));
}
}
// ----------------------
// Task que toca o buzzer
// ----------------------
static void buzzer_worker_task(void *arg) {
buzzer_pattern_id_t pattern_id;
while (true) {
if (xQueueReceive(buzzer_queue, &pattern_id, portMAX_DELAY)) {
//buzzer_execute_pattern(pattern_id);
}
}
}
// ----------------------
// Task de monitoramento
// ----------------------
static void buzzer_monitor_task(void *arg) {
while (true) {
evse_state_t current = evse_get_state();
if (current != last_buzzer_state) {
buzzer_pattern_id_t pattern_id = BUZZER_PATTERN_NONE;
switch (current) {
case EVSE_STATE_A:
if (last_buzzer_state != EVSE_STATE_A)
pattern_id = BUZZER_PATTERN_UNPLUGGED;
break;
case EVSE_STATE_B1:
case EVSE_STATE_B2:
if (last_buzzer_state != EVSE_STATE_B1 && last_buzzer_state != EVSE_STATE_B2)
pattern_id = BUZZER_PATTERN_PLUGGED;
break;
case EVSE_STATE_C2:
case EVSE_STATE_D2:
if (last_buzzer_state != EVSE_STATE_C2 && last_buzzer_state != EVSE_STATE_D2)
pattern_id = BUZZER_PATTERN_CHARGING;
break;
default:
break;
}
if (pattern_id != BUZZER_PATTERN_NONE) {
xQueueSend(buzzer_queue, &pattern_id, 0); // Não bloqueia
}
last_buzzer_state = current;
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
// ----------------------
// Inicialização
// ----------------------
void buzzer_init(void) {
if (board_config.buzzer) {
buzzer_gpio = board_config.buzzer_gpio;
gpio_config_t io_conf = {
.pin_bit_mask = BIT64(buzzer_gpio),
.mode = GPIO_MODE_OUTPUT,
.pull_down_en = GPIO_PULLDOWN_ENABLE,
.pull_up_en = GPIO_PULLUP_DISABLE,
.intr_type = GPIO_INTR_DISABLE
};
gpio_config(&io_conf);
gpio_set_level(buzzer_gpio, 0);
}
buzzer_queue = xQueueCreate(4, sizeof(buzzer_pattern_id_t));
xTaskCreate(buzzer_monitor_task, "buzzer_monitor", 2048, NULL, 3, NULL);
xTaskCreate(buzzer_worker_task, "buzzer_worker", 2048, NULL, 3, NULL);
}
// === Fim de: components/peripherals/src/buzzer.c ===
// === Início de: components/peripherals/src/ds18x20.h ===
/*
* Copyright (c) 2016 Grzegorz Hetman <ghetman@gmail.com>
* Copyright (c) 2016 Alex Stewart <foogod@gmail.com>
* Copyright (c) 2018 Ruslan V. Uss <unclerus@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of itscontributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _DS18X20_H
#define _DS18X20_H
#include <esp_err.h>
#include "onewire.h"
typedef onewire_addr_t ds18x20_addr_t;
/** An address value which can be used to indicate "any device on the bus" */
#define DS18X20_ANY ONEWIRE_NONE
/** Family ID (lower address byte) of DS18B20 sensors */
#define DS18B20_FAMILY_ID 0x28
/** Family ID (lower address byte) of DS18S20 sensors */
#define DS18S20_FAMILY_ID 0x10
/**
* @brief Find the addresses of all ds18x20 devices on the bus.
*
* Scans the bus for all devices and places their addresses in the supplied
* array. If there are more than `addr_count` devices on the bus, only the
* first `addr_count` are recorded.
*
* @param pin The GPIO pin connected to the ds18x20 bus
* @param addr_list A pointer to an array of ::ds18x20_addr_t values.
* This will be populated with the addresses of the found
* devices.
* @param addr_count Number of slots in the `addr_list` array. At most this
* many addresses will be returned.
* @param found The number of devices found. Note that this may be less
* than, equal to, or more than `addr_count`, depending on
* how many ds18x20 devices are attached to the bus.
*
* @returns `ESP_OK` if the command was successfully issued
*/
esp_err_t ds18x20_scan_devices(gpio_num_t pin, ds18x20_addr_t *addr_list, size_t addr_count, size_t *found);
/**
* @brief Tell one or more sensors to perform a temperature measurement and
* conversion (CONVERT_T) operation.
*
* This operation can take up to 750ms to complete.
*
* If `wait=true`, this routine will automatically drive the pin high for the
* necessary 750ms after issuing the command to ensure parasitically-powered
* devices have enough power to perform the conversion operation (for
* non-parasitically-powered devices, this is not necessary but does not
* hurt). If `wait=false`, this routine will drive the pin high, but will
* then return immediately. It is up to the caller to wait the requisite time
* and then depower the bus using onewire_depower() or by issuing another
* command once conversion is done.
*
* @param pin The GPIO pin connected to the ds18x20 device
* @param addr The 64-bit address of the device on the bus. This can be set
* to ::DS18X20_ANY to send the command to all devices on the bus
* at the same time.
* @param wait Whether to wait for the necessary 750ms for the ds18x20 to
* finish performing the conversion before returning to the
* caller (You will normally want to do this).
*
* @returns `ESP_OK` if the command was successfully issued
*/
esp_err_t ds18x20_measure(gpio_num_t pin, ds18x20_addr_t addr, bool wait);
/**
* @brief Read the value from the last CONVERT_T operation.
*
* This should be called after ds18x20_measure() to fetch the result of the
* temperature measurement.
*
* @param pin The GPIO pin connected to the ds18x20 device
* @param addr The 64-bit address of the device to read. This can be set
* to ::DS18X20_ANY to read any device on the bus (but note
* that this will only work if there is exactly one device
* connected, or they will corrupt each others' transmissions)
* @param temperature The temperature in degrees Celsius
*
* @returns `ESP_OK` if the command was successfully issued
*/
esp_err_t ds18x20_read_temperature(gpio_num_t pin, ds18x20_addr_t addr, int16_t *temperature);
/**
* @brief Read the value from the last CONVERT_T operation (ds18b20 version).
*
* This should be called after ds18x20_measure() to fetch the result of the
* temperature measurement.
*
* @param pin The GPIO pin connected to the ds18x20 device
* @param addr The 64-bit address of the device to read. This can be set
* to ::DS18X20_ANY to read any device on the bus (but note
* that this will only work if there is exactly one device
* connected, or they will corrupt each others' transmissions)
* @param temperature The temperature in degrees Celsius
*
* @returns `ESP_OK` if the command was successfully issued
*/
esp_err_t ds18b20_read_temperature(gpio_num_t pin, ds18x20_addr_t addr, int16_t *temperature);
/**
* @brief Read the value from the last CONVERT_T operation (ds18s20 version).
*
* This should be called after ds18x20_measure() to fetch the result of the
* temperature measurement.
*
* @param pin The GPIO pin connected to the ds18x20 device
* @param addr The 64-bit address of the device to read. This can be set
* to ::DS18X20_ANY to read any device on the bus (but note
* that this will only work if there is exactly one device
* connected, or they will corrupt each others' transmissions)
* @param temperature The temperature in degrees Celsius
*
* @returns `ESP_OK` if the command was successfully issued
*/
esp_err_t ds18s20_read_temperature(gpio_num_t pin, ds18x20_addr_t addr, int16_t *temperature);
/**
* @brief Read the value from the last CONVERT_T operation for multiple devices.
*
* This should be called after ds18x20_measure() to fetch the result of the
* temperature measurement.
*
* @param pin The GPIO pin connected to the ds18x20 bus
* @param addr_list A list of addresses for devices to read.
* @param addr_count The number of entries in `addr_list`.
* @param result_list An array of int16_ts to hold the returned temperature
* values. It should have at least `addr_count` entries.
*
* @returns `ESP_OK` if all temperatures were fetched successfully
*/
esp_err_t ds18x20_read_temp_multi(gpio_num_t pin, ds18x20_addr_t *addr_list, size_t addr_count, int16_t *result_list);
/** Perform a ds18x20_measure() followed by ds18s20_read_temperature()
*
* @param pin The GPIO pin connected to the ds18s20 device
* @param addr The 64-bit address of the device to read. This can be set
* to ::DS18X20_ANY to read any device on the bus (but note
* that this will only work if there is exactly one device
* connected, or they will corrupt each others' transmissions)
* @param temperature The temperature in degrees Celsius
*/
esp_err_t ds18s20_measure_and_read(gpio_num_t pin, ds18x20_addr_t addr, int16_t *temperature);
/** Perform a ds18x20_measure() followed by ds18b20_read_temperature()
*
* @param pin The GPIO pin connected to the ds18x20 device
* @param addr The 64-bit address of the device to read. This can be set
* to ::DS18X20_ANY to read any device on the bus (but note
* that this will only work if there is exactly one device
* connected, or they will corrupt each others' transmissions)
* @param temperature The temperature in degrees Celsius
*/
esp_err_t ds18b20_measure_and_read(gpio_num_t pin, ds18x20_addr_t addr, int16_t *temperature);
/** Perform a ds18x20_measure() followed by ds18x20_read_temperature()
*
* @param pin The GPIO pin connected to the ds18x20 device
* @param addr The 64-bit address of the device to read. This can be set
* to ::DS18X20_ANY to read any device on the bus (but note
* that this will only work if there is exactly one device
* connected, or they will corrupt each others' transmissions)
* @param temperature The temperature in degrees Celsius
*/
esp_err_t ds18x20_measure_and_read(gpio_num_t pin, ds18x20_addr_t addr, int16_t *temperature);
/**
* @brief Perform a ds18x20_measure() followed by ds18x20_read_temp_multi()
*
* @param pin The GPIO pin connected to the ds18x20 bus
* @param addr_list A list of addresses for devices to read.
* @param addr_count The number of entries in `addr_list`.
* @param result_list An array of int16_ts to hold the returned temperature
* values. It should have at least `addr_count` entries.
*
* @returns `ESP_OK` if all temperatures were fetched successfully
*/
esp_err_t ds18x20_measure_and_read_multi(gpio_num_t pin, ds18x20_addr_t *addr_list, size_t addr_count, int16_t *result_list);
/**
* @brief Read the scratchpad data for a particular ds18x20 device.
*
* This is not generally necessary to do directly. It is done automatically
* as part of ds18x20_read_temperature().
*
* @param pin The GPIO pin connected to the ds18x20 device
* @param addr The 64-bit address of the device to read. This can be set
* to ::DS18X20_ANY to read any device on the bus (but note
* that this will only work if there is exactly one device
* connected, or they will corrupt each others' transmissions)
* @param buffer An 8-byte buffer to hold the read data.
*
* @returns `ESP_OK` if the command was successfully issued
*/
esp_err_t ds18x20_read_scratchpad(gpio_num_t pin, ds18x20_addr_t addr, uint8_t *buffer);
/**
* @brief Write the scratchpad data for a particular ds18x20 device.
*
* @param pin The GPIO pin connected to the ds18x20 device
* @param addr The 64-bit address of the device to write. This can be set
* to ::DS18X20_ANY to read any device on the bus (but note
* that this will only work if there is exactly one device
* connected, or they will corrupt each others' transmissions)
* @param buffer An 3-byte buffer to hold the data to write
*
* @returns `ESP_OK` if the command was successfully issued
*/
esp_err_t ds18x20_write_scratchpad(gpio_num_t pin, ds18x20_addr_t addr, uint8_t *buffer);
/**
* @brief Issue the copy scratchpad command, copying current scratchpad to
* EEPROM.
*
* @param pin The GPIO pin connected to the ds18x20 device
* @param addr The 64-bit address of the device to command. This can be set
* to ::DS18X20_ANY to read any device on the bus (but note
* that this will only work if there is exactly one device
* connected, or they will corrupt each others' transmissions)
*
* @returns `ESP_OK` if the command was successfully issued
*/
esp_err_t ds18x20_copy_scratchpad(gpio_num_t pin, ds18x20_addr_t addr);
#endif /* _DS18X20_H */
// === Fim de: components/peripherals/src/ds18x20.h ===