ups/main/main.c

213 lines
5.1 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"
#include "driver/gpio.h"
#include "driver/adc.h"
#include "driver/ledc.h"
#include "esp_adc_cal.h"
#include "esp_log.h"
#include "screen.c"
#define LED_BLUE_GPIO (5)
#define LED_GREEN_GPIO (4)
#define LED_RED_GPIO (3)
#define POWER_OUT_CTL_GPIO (6)
#define ATTEN_DB ADC_ATTEN_DB_11
#define ADC_CANNEL ADC1_CHANNEL_1
#define BEEP_GPIO LED_RED_GPIO
#define BEEP_FREQ (650)
static uint32_t adc_raw;
static esp_adc_cal_characteristics_t adc_chars;
static bool adc_calibration_init(void)
{
esp_err_t ret;
bool cali_enable = false;
ret = esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP);
if (ret == ESP_ERR_NOT_SUPPORTED)
{
ESP_LOGW("ADC", "Calibration scheme not supported, skip software calibration");
}
else if (ret == ESP_ERR_INVALID_VERSION)
{
ESP_LOGW("ADC", "eFuse not burnt, skip software calibration");
}
else if (ret == ESP_OK)
{
cali_enable = true;
esp_adc_cal_characterize(ADC_UNIT_1, ATTEN_DB, ADC_WIDTH_BIT_12, 1100, &adc_chars);
}
else
{
ESP_LOGE("ADC", "Invalid arg");
}
return cali_enable;
}
static bool cali_enable;
void initAdc()
{
gpio_reset_pin(LED_BLUE_GPIO);
gpio_set_direction(LED_BLUE_GPIO, GPIO_MODE_OUTPUT);
gpio_reset_pin(LED_GREEN_GPIO);
gpio_set_direction(LED_GREEN_GPIO, GPIO_MODE_OUTPUT);
gpio_reset_pin(LED_RED_GPIO);
gpio_set_direction(LED_RED_GPIO, GPIO_MODE_OUTPUT);
cali_enable = adc_calibration_init();
ESP_ERROR_CHECK(adc1_config_width(ADC_WIDTH_BIT_12));
ESP_ERROR_CHECK(adc1_config_channel_atten(ADC_CANNEL, ATTEN_DB));
}
void initLEDc()
{
ledc_timer_config_t ledc_timer = {
.duty_resolution = LEDC_TIMER_10_BIT,
.freq_hz = BEEP_FREQ,
.speed_mode = LEDC_LOW_SPEED_MODE,
.timer_num = LEDC_TIMER_0};
ESP_ERROR_CHECK(ledc_timer_config(&ledc_timer));
ledc_channel_config_t ledc_channel = {
.channel = LEDC_CHANNEL_0,
.duty = 128,
.hpoint = 0,
.gpio_num = BEEP_GPIO,
.speed_mode = LEDC_LOW_SPEED_MODE,
.timer_sel = LEDC_TIMER_0};
ESP_ERROR_CHECK(ledc_channel_config(&ledc_channel));
}
void blink_task(void *pvParameter)
{
uint8_t s_blink_state = 0;
ESP_LOGI("BLINK", "Started");
while (1)
{
s_blink_state = !s_blink_state;
gpio_set_level(LED_BLUE_GPIO, s_blink_state);
vTaskDelay(500 / portTICK_PERIOD_MS);
}
vTaskDelete(NULL);
}
void powerOutOff(TimerHandle_t pxTimer)
{
ESP_LOGW("POWER", "OFF");
gpio_set_level(POWER_OUT_CTL_GPIO, 1);
}
void powerOutOn()
{
ESP_LOGW("POWER", "ON");
ESP_ERROR_CHECK(gpio_set_level(POWER_OUT_CTL_GPIO, 0));
}
void getVoltage(void *pvParameter)
{
uint32_t voltage = 0;
uint8_t beep_state = 0;
TimerHandle_t power_out_off_timer = NULL;
display_print8_str(0, 0, "Poser Monitor");
gpio_reset_pin(POWER_OUT_CTL_GPIO);
gpio_set_direction(POWER_OUT_CTL_GPIO, GPIO_MODE_OUTPUT);
powerOutOn();
while (1)
{
adc_raw = adc1_get_raw(ADC_CANNEL);
if (cali_enable)
{
voltage = esp_adc_cal_raw_to_voltage(adc_raw, &adc_chars);
char voltageStr[8];
itoa(voltage, voltageStr, 10);
if (voltage > 1000)
{
display_print8_str(32, 3, voltageStr);
}
else if (voltage > 100)
{
display_print8_str(32, 3, " ");
display_print8_str(40, 3, voltageStr);
}
else if (voltage > 10)
{
display_print8_str(32, 3, " ");
display_print8_str(48, 3, voltageStr);
}
else
{
display_print8_str(32, 3, " ");
display_print8_str(56, 3, voltageStr);
}
display_print8_str(72, 3, "mV");
if (voltage > 100)
{
ESP_ERROR_CHECK(ledc_stop(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 0));
beep_state = 0;
if (power_out_off_timer != NULL)
{
xTimerStop(power_out_off_timer, 0);
power_out_off_timer = NULL;
powerOutOn();
printf("POWER_HAS_BEEN_RESTORED\n");
}
}
else
{
if (beep_state == 0)
{
ESP_ERROR_CHECK(ledc_set_freq(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, BEEP_FREQ));
ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0));
}
else if (beep_state == 1)
{
ESP_ERROR_CHECK(ledc_set_freq(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, BEEP_FREQ - 50));
if (power_out_off_timer == NULL)
{
ESP_LOGW("POWER", "PRE POWER OFF");
power_out_off_timer = xTimerCreate("power_out_off_timer", pdMS_TO_TICKS(10 * 1000), pdFALSE, NULL, powerOutOff);
xTimerStart(power_out_off_timer, 0);
printf("POWER_SUPPLY_FAILURE\n");
}
}
else
{
ESP_ERROR_CHECK(ledc_stop(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, 0));
}
if (++beep_state > 6)
{
beep_state = 0;
}
}
}
vTaskDelay(pdMS_TO_TICKS(500));
}
vTaskDelete(NULL);
}
void app_main(void)
{
initAdc();
initDisplay();
initLEDc();
xTaskCreate(blink_task, "BLINK", 4096, NULL, 1, NULL);
xTaskCreate(getVoltage, "Voltage", 4096, NULL, 10, NULL);
}