// === Início de: components/network/include/wifi.h === #ifndef WIFI_H_ #define WIFI_H_ #include #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 #include #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 * Copyright (c) 2016 Alex Stewart * Copyright (c) 2018 Ruslan V. Uss * * 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 #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 ===