/
ellersseer
/
MyCheat
Обзор
Документация
Войти
/
ellersseer
/
MyCheat
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
2
CI/CD
Аналитика
Безопасность
master
src/onewire_handler.cpp
248 строк
9 KB
Dmitry Zhiltsov
fix(core): Исправть рассинхрон
21 фев 2026, 02:07
21 фев 2026, 02:07
a0af0ee
Код
Авторство
О чём код?
#include "onewire_handler.h" #include "app_state.h" #include "debug_log.h" #include "log_buffer.h" #include "esp_task_wdt.h" // ============================================ // 1-Wire Bus Safety Functions // ============================================ void release1WireBus() { // Set pin to INPUT (Hi-Z) - releases the bus pinMode(ONEWIRE_PIN, INPUT); // Small delay to ensure bus settles delayMicroseconds(100); } void shutdownHandler() { logCapture.println("[Shutdown] Saving temperatures to NVS..."); // Save current temperatures before restart if (xSemaphoreTake(tempMutex, pdMS_TO_TICKS(100)) == pdTRUE) { for (int i = 0; i < NUM_SENSORS; i++) { sensorSettings.lastTemperatures[i] = temperatures[i]; sensorSettings.sensorEnabled[i] = sensorStates[i].enabled; } xSemaphoreGive(tempMutex); settingsManager.saveSensorSettings(sensorSettings); logCapture.println("[Shutdown] Temperatures saved"); } else { logCapture.println("[Shutdown] WARNING: Could not save temperatures (mutex timeout)"); } logCapture.println("[Shutdown] Releasing 1-Wire bus..."); release1WireBus(); logCapture.println("[Shutdown] Bus released, safe to restart"); Serial.flush(); } void safeRestart() { DEBUG_EVENT(EVT_INFO, "Safe restart initiated"); shutdownHandler(); ESP.restart(); } // ============================================ // 1-Wire Setup // ============================================ void setup1Wire() { logCapture.println("[1-Wire] Initializing emulation..."); int enabledCount = 0; for (int i = 0; i < NUM_SENSORS; i++) { sensors[i] = new DS18B20(DS18B20::family_code, SENSOR_ADDRESSES[i][1], SENSOR_ADDRESSES[i][2], SENSOR_ADDRESSES[i][3], SENSOR_ADDRESSES[i][4], SENSOR_ADDRESSES[i][5], SENSOR_ADDRESSES[i][6]); // Only attach enabled sensors if (sensorStates[i].enabled) { hub.attach(*sensors[i]); sensors[i]->setTemperature(sensorStates[i].temperature); enabledCount++; } logCapture.printf(" Sensor %d: ", i); for (int j = 0; j < 8; j++) { logCapture.printf("%02X", SENSOR_ADDRESSES[i][j]); if (j < 7) logCapture.print(":"); } logCapture.printf(" = %.2f°C [%s]\n", sensorStates[i].temperature, sensorStates[i].enabled ? "enabled" : "disabled"); } logCapture.printf("[1-Wire] Hub ready on GPIO%d with %d/%d sensors enabled\n", ONEWIRE_PIN, enabledCount, NUM_SENSORS); } // ============================================ // 1-Wire Task (Time Critical!) // ============================================ void oneWireTask(void *pvParameters) { // NO Serial output here - it can block due to mutex/interrupt issues // Signal that task started via LED blink digitalWrite(STATUS_LED_PIN, HIGH); vTaskDelay(pdMS_TO_TICKS(100)); digitalWrite(STATUS_LED_PIN, LOW); vTaskDelay(pdMS_TO_TICKS(100)); // Register with Task WDT for crash protection // hub.poll() calls esp_task_wdt_reset() internally esp_task_wdt_add(NULL); SensorCommand_t cmd; while (true) { // Poll 1-Wire hub - CRITICAL for timing! // Note: hub.poll() internally calls esp_task_wdt_reset() hub.poll(); // Increment stats if (xSemaphoreTake(statsMutex, 0) == pdTRUE) { stats.oneWirePolls++; xSemaphoreGive(statsMutex); } // Check for sensor commands (non-blocking) while (xQueueReceive(sensorCommandQueue, &cmd, 0) == pdTRUE) { switch (cmd.type) { case SensorCommandType::SET_ALL_TEMPS: // Update all sensors if (xSemaphoreTake(tempMutex, pdMS_TO_TICKS(10)) == pdTRUE) { for (int i = 0; i < NUM_SENSORS; i++) { if (sensorStates[i].enabled && sensorStates[i].status != SensorStatus::OFF) { float temp = constrain(cmd.allTemperatures[i], -55.0f, 125.0f); temperatures[i] = temp; sensorStates[i].temperature = temp; sensorStates[i].lastUpdateMs = millis(); sensorStates[i].status = SensorStatus::ACTIVE; sensors[i]->setTemperature(temp); temperaturesChanged = true; } } xSemaphoreGive(tempMutex); if (xSemaphoreTake(statsMutex, 0) == pdTRUE) { stats.tempUpdates += NUM_SENSORS; xSemaphoreGive(statsMutex); } } break; case SensorCommandType::SET_TEMPERATURE: // Update single sensor if (cmd.sensorIndex < NUM_SENSORS) { if (xSemaphoreTake(tempMutex, pdMS_TO_TICKS(10)) == pdTRUE) { if (sensorStates[cmd.sensorIndex].enabled) { float temp = constrain(cmd.temperature, -55.0f, 125.0f); temperatures[cmd.sensorIndex] = temp; sensorStates[cmd.sensorIndex].temperature = temp; sensorStates[cmd.sensorIndex].lastUpdateMs = millis(); sensorStates[cmd.sensorIndex].status = SensorStatus::ACTIVE; sensors[cmd.sensorIndex]->setTemperature(temp); temperaturesChanged = true; } xSemaphoreGive(tempMutex); if (xSemaphoreTake(statsMutex, 0) == pdTRUE) { stats.tempUpdates++; xSemaphoreGive(statsMutex); } } } break; case SensorCommandType::ENABLE_SENSOR: if (cmd.sensorIndex < NUM_SENSORS) { if (xSemaphoreTake(tempMutex, pdMS_TO_TICKS(10)) == pdTRUE) { sensorStates[cmd.sensorIndex].enabled = true; sensorStates[cmd.sensorIndex].status = SensorStatus::ACTIVE; sensorStates[cmd.sensorIndex].lastUpdateMs = millis(); // Set to power-on reset temperature (85°C) when enabling sensorStates[cmd.sensorIndex].temperature = POWER_ON_RESET_TEMPERATURE; temperatures[cmd.sensorIndex] = POWER_ON_RESET_TEMPERATURE; sensors[cmd.sensorIndex]->setTemperature(POWER_ON_RESET_TEMPERATURE); hub.attach(*sensors[cmd.sensorIndex]); sensorSettings.sensorEnabled[cmd.sensorIndex] = true; xSemaphoreGive(tempMutex); // Save to NVS settingsManager.saveSensorEnabled(cmd.sensorIndex, true); } } break; case SensorCommandType::DISABLE_SENSOR: if (cmd.sensorIndex < NUM_SENSORS) { if (xSemaphoreTake(tempMutex, pdMS_TO_TICKS(10)) == pdTRUE) { sensorStates[cmd.sensorIndex].enabled = false; sensorStates[cmd.sensorIndex].status = SensorStatus::OFF; hub.detach(*sensors[cmd.sensorIndex]); sensorSettings.sensorEnabled[cmd.sensorIndex] = false; xSemaphoreGive(tempMutex); // Save to NVS settingsManager.saveSensorEnabled(cmd.sensorIndex, false); } } break; case SensorCommandType::SET_STALE: if (cmd.sensorIndex < NUM_SENSORS) { if (xSemaphoreTake(tempMutex, pdMS_TO_TICKS(10)) == pdTRUE) { if (sensorStates[cmd.sensorIndex].enabled) { sensorStates[cmd.sensorIndex].status = SensorStatus::STALE; temperatures[cmd.sensorIndex] = POWER_ON_RESET_TEMPERATURE; sensorStates[cmd.sensorIndex].temperature = POWER_ON_RESET_TEMPERATURE; sensors[cmd.sensorIndex]->setTemperature(POWER_ON_RESET_TEMPERATURE); } xSemaphoreGive(tempMutex); } } break; } } // Small delay to allow other tasks (including loop()) to run // vTaskDelay guarantees yielding, unlike vTaskDelayUntil which may skip if behind schedule vTaskDelay(pdMS_TO_TICKS(1)); } }