/
singlwolf
/
Radiola-2S3
Обзор
Документация
Войти
/
singlwolf
/
Radiola-2S3
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/hardware.cpp
299 строк
7 KB
SinglWolf
Public access
27 мар 2026, 07:00
27 мар 2026, 07:00
642fcfc
Код
Авторство
О чём код?
/** hardware.cpp **/ #include "pinout.h" #include "hardware.h" #include "eeStorage.h" #include "web_server.h" #include "prio_.h" #if defined(CONFIG_IDF_TARGET_ESP32) #define SPEED_MODE LEDC_HIGH_SPEED_MODE #elif defined(CONFIG_IDF_TARGET_ESP32S2) or (CONFIG_IDF_TARGET_ESP32S3) #define SPEED_MODE LEDC_LOW_SPEED_MODE #endif bool current_mute = false; SemaphoreHandle_t xAnalogSemaphore = nullptr; static uint8_t old_brg_level = 0; // Предыдущее состояние уровня подсветки дисплея uint16_t adc_bit = 0x0000; // Hardware dev; // void Hardware::init() { xAnalogSemaphore = xSemaphoreCreateMutex(); InitPWM(); InitLDR(); LedBacklightInit(); InitGPIOS(); // initI2Cdev(); } // void Hardware::InitGPIOS() { // // 1. Проверяем на Pull-Down // pinMode(PIN_MUTE, INPUT_PULLUP); // delay(1); // bool pulled_up = digitalRead(PIN_MUTE); // // 2. Проверяем на Pull-Up // pinMode(PIN_MUTE, INPUT_PULLDOWN); // delay(1); // bool pulled_down = !digitalRead(PIN_MUTE); // // Если оба раза пин послушно ушел за внутренним резистором ESP32 // if (pulled_up && pulled_down) // { // // Пин "голый", внешнего резистора НЕТ. // // Тут твоя логика "запоминания" mute_lvl превращается в лотерею. // } pinMode(PIN_MUTE, INPUT); mute_lvl = digitalRead(PIN_MUTE); // txtPrintInfo("PIN_MUTE LVL: %i", mute_lvl); delay(1); pinMode(PIN_MUTE, OUTPUT); digitalWrite(PIN_MUTE, mute_lvl); } // void Hardware::initI2Cdev() { StartTask(); } void Hardware::InitPWM() { if (Config->led.on) { // ledcAttachChannel(uint8_t pin, uint32_t freq, uint8_t resolution, uint8_t channel) ledcAttachChannel(PIN_LED, 50000, LEDC_TIMER_8_BIT, DISPLAY_BRG); } if (Config->beep.on) { ledcAttachChannel(PIN_BUZZ, 2000, LEDC_TIMER_8_BIT, BEEPER); } } void Hardware::InitLDR() { if ((!Config->led.ldr) || (adc_bit != 0)) { return; } #if defined(CONFIG_IDF_TARGET_ESP32S2) // adc1_config_width(ADC_WIDTH_BIT_13); analogReadResolution(13); adc_bit = 0x1FFF; // 13 BITs #elif defined(CONFIG_IDF_TARGET_ESP32) // adc1_config_width(ADC_WIDTH_BIT_9); // ADC_WIDTH_9Bit analogReadResolution(9); adc_bit = 0x1FF; // 9 BITs #elif defined(CONFIG_IDF_TARGET_ESP32S3) // adc1_config_width(ADC_WIDTH_BIT_12); // ADC_WIDTH_12Bit analogReadResolution(12); adc_bit = 0xFFF; // 12 BITs #endif } void Hardware::forseSensor() { counter = 4096; } // void Hardware::LedBacklightInit() { if (!Config->led.on) return; if (Config->led.mode == NOT_ADJUSTABLE) { BRG_Level = MAX_LEVEL; } ledcWriteChannel(DISPLAY_BRG, 0); } // void Hardware::SetBRG() { if (!Config->led.on) return; ledcWriteChannel(DISPLAY_BRG, BRG_Level); } uint16_t Hardware::AnalogR(uint8_t pin) { uint16_t raw = 0; if (xSemaphoreTake(xAnalogSemaphore, portMAX_DELAY)) { raw = analogRead(pin); xSemaphoreGive(xAnalogSemaphore); } return raw; } void Hardware::set_mute_ON() { if (current_mute) return; current_mute = true; digitalWrite(PIN_MUTE, mute_lvl); } void Hardware::set_mute_OFF() { if (!current_mute) return; current_mute = false; digitalWrite(PIN_MUTE, mute_lvl ^ 1); } void Hardware::beep(uint8_t time) { if (!Config->beep.on) return; // start ledcWriteTone(PIN_BUZZ, 2000); vTaskDelay(time / portTICK_PERIOD_MS); // stop ledcWriteTone(PIN_BUZZ, 0); vTaskDelay(1); } // void Hardware::taskWrapper(void *param) { Hardware *runner = static_cast<Hardware *>(param); runner->sensorsTask(); } void Hardware::StartTask() { if (xTaskCreatePinnedToCore( &Hardware::taskWrapper, NAME_SENSORS, STACK_SENSORS, this, PRIO_SENSORS, nullptr /* &pxCreatedTask */, CPU_SENSORS) != pdPASS) { ESP_LOGE("SENSORS", "ERROR creating task! Out of memory?"); } } void Hardware::sensorsTask() { float old_temperature(NAN), old_pressure(NAN), old_humidity(NAN); // esp_err_t err; // while (1) { if (dev.Stop) { goto exit; } if (Config->i2c.bmp) dev.counter++; else dev.counter = 0; if (dev.counter >= 4096) { if (Config->i2c.bmp != 1) { BME280::TempUnit tempUnit(Config->sensor.cels ? BME280::TempUnit_Celsius : BME280::TempUnit_Fahrenheit); BME280::PresUnit pressUnit(Config->sensor.torr ? BME280::PresUnit_torr : BME280::PresUnit_hPa); xSemaphoreTake(eeprom.eeI2C, portMAX_DELAY); eeprom.bme->read(old_pressure, old_temperature, old_humidity, tempUnit, pressUnit); xSemaphoreGive(eeprom.eeI2C); } else { // TODO: код для bmp180 goto next; } } else { goto next; } old_temperature = (float)(old_temperature + (Config->sensor.offset / 10.0)); dev.counter = 0; if (old_temperature != dev.Temperature) { dev.Temperature = old_temperature; web.requestOnChange(TEMPERATURE); } // if (old_pressure != dev.Pressure) { dev.Pressure = old_pressure; web.requestOnChange(PRESSURE); } // if (old_humidity != dev.Humidity) { dev.Humidity = old_humidity; web.requestOnChange(HUMIDITY); } // int uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL); // ESP_LOGD("bmp280Task", "watermark: %d heap: %d", uxHighWaterMark, xPortGetFreeHeapSize()); next: // Опрос фоторезистора или датчика освещённости if (!Config->led.on) goto exit; if (Config->led.mode == NOT_ADJUSTABLE) { dev.BRG_Level = MAX_LEVEL; } else if (Config->led.mode == BY_TIME) { // Уровень подсветки в зависимости от времени суток time_t now; struct tm timeinfo; time(&now); localtime_r(&now, &timeinfo); if ((timeinfo.tm_hour >= Config->led.begin) && (timeinfo.tm_hour <= Config->led.end)) { dev.BRG_Level = Config->led.day; } else { dev.BRG_Level = Config->led.night; } } else if ((Config->led.mode == BY_LIGHTING) && (Config->led.ldr)) { // Снимаем напряжение. uint32_t voltage = dev.AnalogR(PIN_LDR); // vTaskDelay(1); // map(long x, long in_min, long in_max, long out_min, long out_max) dev.BRG_Level = map( (long)voltage, 0, adc_bit, Config->led.day, Config->led.night); // txtPrintError("ldr voltage: %u\n", voltage); // txtPrintError("brg_level: %u\n", (uint8_t)BRG_Level); } else if (Config->led.mode == BY_HAND) { // Ручная регулировка уровня подсветки dev.BRG_Level = Config->led.hand; } if (dev.BRG_Level != old_brg_level) { // Если уровень изменился, применяем к дисплею // txtPrintError("ldr voltage: %lu\n", voltage); // txtPrintError("BRG_Level: %u\n", BRG_Level); dev.SetBRG(); // Запоминаем текущий уровень подсветки old_brg_level = dev.BRG_Level; } exit: vTaskDelay(5); } }