Compare commits
	
		
			6 Commits
		
	
	
		
			testing/la
			...
			feature/wi
		
	
	| Author | SHA256 | Date | |
|---|---|---|---|
| d14ae528c0 | |||
| a72c0673b1 | |||
| 999af9d888 | |||
| 8a8bcd078b | |||
| 59b8c3e2b2 | |||
| 06c6612ef6 | 
| @ -12,7 +12,7 @@ | ||||
|  | ||||
| #define RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_DAY 30.0 | ||||
| #define RETURN_FLOW_TEMPERATURE_LOWER_LIMIT_NIGHT 25.0 | ||||
| #define CHAMPER_TEMPERATURE_TARGET 70.0 | ||||
| #define CHAMPER_TEMPERATURE_TARGET 80.0 | ||||
| #define BURNER_FAULT_DETECTION_THRESHOLD (60U * 3U) // Detect burner fault if after 3 minutes no burner start detected | ||||
|  | ||||
| static const char *TAG = "smart-oil-heater-control-system-control"; | ||||
| @ -59,13 +59,18 @@ void taskControl(void *pvParameters) | ||||
|     bool bBurnerFaultDetected = false; | ||||
|     int64_t i64BurnerEnableTimestamp = esp_timer_get_time(); | ||||
|  | ||||
|     time_t now; | ||||
|  | ||||
|     while (1) | ||||
|     { | ||||
|         // Get the current time | ||||
|         time(&now); | ||||
|         ESP_LOGW(TAG, "Control loop time: %lli", now); | ||||
|         vTaskDelay(PERIODIC_INTERVAL * 1000U / portTICK_PERIOD_MS); | ||||
|  | ||||
|         if (getSafetyState() != SAFETY_NO_ERROR) | ||||
|         { | ||||
|             ESP_LOGW(TAG, "Control not possible due to safety fault!"); | ||||
|             //ESP_LOGW(TAG, "Control not possible due to safety fault!"); | ||||
|             sControlState = CONTROL_FAULT_SAFETY; | ||||
|             if (bHeatingInAction == true) | ||||
|             { | ||||
| @ -98,7 +103,7 @@ void taskControl(void *pvParameters) | ||||
|  | ||||
|         if (bHeatingInAction == true) | ||||
|         { | ||||
|             if (getChamberTemperature().fCurrentValue >= currentControlEntry.fChamberTemperature) | ||||
|             if ((getChamberTemperature().fCurrentValue >= currentControlEntry.fChamberTemperature) || (getChamberTemperature().predict60s.fValue >= currentControlEntry.fChamberTemperature)) | ||||
|             { | ||||
|                 ESP_LOGI(TAG, "Chamber Target Temperature reached: Disable burner"); | ||||
|                 bHeatingInAction = false; | ||||
|  | ||||
| @ -16,10 +16,10 @@ static const char *TAG = "smart-oil-heater-control-system-inputs"; | ||||
| const uint8_t uBurnerFaultPin = 19U; | ||||
| const uint8_t uDS18B20Pin = 4U; | ||||
|  | ||||
| const onewire_addr_t uChamperTempSensorAddr = 0x78000000c6c2f728; | ||||
| const onewire_addr_t uChamperTempSensorAddr = 0xd00000108cd01d28; | ||||
| const onewire_addr_t uOutdoorTempSensorAddr = 0x78000000c6c2f728; | ||||
| const onewire_addr_t uInletFlowTempSensorAddr = 0x78000000c6c2f728; | ||||
| const onewire_addr_t uReturnFlowTempSensorAddr = 0x78000000c6c2f728; | ||||
| const onewire_addr_t uInletFlowTempSensorAddr = 0x410000108b8c0628; | ||||
| const onewire_addr_t uReturnFlowTempSensorAddr = 0x90000108cc77c28; | ||||
|  | ||||
| onewire_addr_t uOneWireAddresses[MAX_DN18B20_SENSORS]; | ||||
| float fDS18B20Temps[MAX_DN18B20_SENSORS]; | ||||
| @ -36,7 +36,7 @@ void taskInput(void *pvParameters); | ||||
| void initMeasurement(sMeasurement *pMeasurement); | ||||
| void updateAverage(sMeasurement *pMeasurement); | ||||
| void updatePrediction(sMeasurement *pMeasurement); | ||||
| float linearRegressionPredict(const float *samples, size_t count, float futureIndex); | ||||
| float linearRegressionPredict(const float *samples, size_t count, size_t bufferIndex, float futureIndex); | ||||
|  | ||||
| void initInputs(void) | ||||
| { | ||||
| @ -162,6 +162,7 @@ void updatePrediction(sMeasurement *pMeasurement) | ||||
|     predict60s->fValue = linearRegressionPredict( | ||||
|         predict60s->samples, | ||||
|         predict60s->bufferCount, | ||||
|         predict60s->bufferIndex, | ||||
|         predict60s->bufferCount + 60.0f); | ||||
| } | ||||
|  | ||||
| @ -188,12 +189,12 @@ void taskInput(void *pvParameters) | ||||
|  | ||||
|             if (ds18x20_scan_devices(uDS18B20Pin, uOneWireAddresses, MAX_DN18B20_SENSORS, &sSensorCount) != ESP_OK) | ||||
|             { | ||||
|                 ESP_LOGE(TAG, "1-Wire device scan error!"); | ||||
|                // ESP_LOGE(TAG, "1-Wire device scan error!"); | ||||
|             } | ||||
|  | ||||
|             if (!sSensorCount) | ||||
|             { | ||||
|                 ESP_LOGW(TAG, "No 1-Wire devices detected!"); | ||||
|                // ESP_LOGW(TAG, "No 1-Wire devices detected!"); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
| @ -202,14 +203,14 @@ void taskInput(void *pvParameters) | ||||
|                 if (sSensorCount > MAX_DN18B20_SENSORS) | ||||
|                 { | ||||
|                     sSensorCount = MAX_DN18B20_SENSORS; | ||||
|                     ESP_LOGW(TAG, "More 1-Wire devices found than expected!"); | ||||
|                    // ESP_LOGW(TAG, "More 1-Wire devices found than expected!"); | ||||
|                 } | ||||
|  | ||||
|                 for (size_t iReadLoop = 0; iReadLoop < ONE_WIRE_LOOPS; iReadLoop++) | ||||
|                 { | ||||
|                     if (ds18x20_measure_and_read_multi(uDS18B20Pin, uOneWireAddresses, sSensorCount, fDS18B20Temps) != ESP_OK) | ||||
|                     { | ||||
|                         ESP_LOGE(TAG, "1-Wire devices read error"); | ||||
|                       //  ESP_LOGE(TAG, "1-Wire devices read error"); | ||||
|                         vTaskDelay(PERIODIC_INTERVAL * 100U / portTICK_PERIOD_MS); // Wait 100ms if bus error occurred | ||||
|                     } | ||||
|                     else | ||||
| @ -217,7 +218,7 @@ void taskInput(void *pvParameters) | ||||
|                         for (int j = 0; j < sSensorCount; j++) | ||||
|                         { | ||||
|                             float temp_c = fDS18B20Temps[j]; | ||||
|                             ESP_LOGI(TAG, "Sensor: %08" PRIx64 " reports %lf°C", (uint64_t)uOneWireAddresses[j], temp_c); | ||||
|                             // ESP_LOGI(TAG, "Sensor: %08" PRIx64 " reports %lf°C", (uint64_t)uOneWireAddresses[j], temp_c); | ||||
|  | ||||
|                             switch ((uint64_t)uOneWireAddresses[j]) | ||||
|                             { | ||||
| @ -226,17 +227,20 @@ void taskInput(void *pvParameters) | ||||
|                                 sChamperTemperature.state = MEASUREMENT_NO_ERROR; | ||||
|                                 updateAverage(&sChamperTemperature); | ||||
|                                 updatePrediction(&sChamperTemperature); | ||||
|  | ||||
|                                 break; | ||||
|                             case ((uint64_t)uOutdoorTempSensorAddr): | ||||
|                                 sOutdoorTemperature.fCurrentValue = temp_c; | ||||
|                                 sOutdoorTemperature.state = MEASUREMENT_NO_ERROR; | ||||
|                                 updateAverage(&sOutdoorTemperature); | ||||
|                                 updatePrediction(&sOutdoorTemperature); | ||||
|  | ||||
|                                 break; | ||||
|                             case ((uint64_t)uInletFlowTempSensorAddr): | ||||
|                                 sInletFlowTemperature.fCurrentValue = temp_c; | ||||
|                                 sInletFlowTemperature.state = MEASUREMENT_NO_ERROR; | ||||
|                                 updateAverage(&sInletFlowTemperature); | ||||
|                                 updatePrediction(&sInletFlowTemperature); | ||||
|  | ||||
|                                 break; | ||||
|                             case ((uint64_t)uReturnFlowTempSensorAddr): | ||||
|                                 sReturnFlowTemperature.fCurrentValue = temp_c; | ||||
|                                 sReturnFlowTemperature.state = MEASUREMENT_NO_ERROR; | ||||
|                                 updateAverage(&sReturnFlowTemperature); | ||||
| @ -264,7 +268,7 @@ void taskInput(void *pvParameters) | ||||
|     } | ||||
| } | ||||
|  | ||||
| float linearRegressionPredict(const float *samples, size_t count, float futureIndex) | ||||
| float linearRegressionPredict(const float *samples, size_t count, size_t bufferIndex, float futureIndex) | ||||
| { | ||||
|     if (count == 0) | ||||
|         return 0.0f; // No prediction possible with no data | ||||
| @ -273,8 +277,11 @@ float linearRegressionPredict(const float *samples, size_t count, float futureIn | ||||
|  | ||||
|     for (size_t i = 0; i < count; i++) | ||||
|     { | ||||
|         float x = (float)i;   // Time index | ||||
|         float y = samples[i]; // Sample value | ||||
|         // Calculate the circular buffer index for the current sample | ||||
|         size_t circularIndex = (bufferIndex + i + 1) % count; | ||||
|  | ||||
|         float x = (float)i;               // Time index | ||||
|         float y = samples[circularIndex]; // Sample value | ||||
|  | ||||
|         sumX += x; | ||||
|         sumY += y; | ||||
| @ -284,8 +291,8 @@ float linearRegressionPredict(const float *samples, size_t count, float futureIn | ||||
|  | ||||
|     // Calculate slope (m) and intercept (b) of the line: y = mx + b | ||||
|     float denominator = (count * sumX2 - sumX * sumX); | ||||
|     if (fabs(denominator) < 1e-6)  // Avoid division by zero | ||||
|         return samples[count - 1]; // Return last value as prediction | ||||
|     if (fabs(denominator) < 1e-6)    // Avoid division by zero | ||||
|         return samples[bufferIndex]; // Return the latest value as prediction | ||||
|  | ||||
|     float m = (count * sumXY - sumX * sumY) / denominator; | ||||
|     float b = (sumY - m * sumX) / count; | ||||
|  | ||||
| @ -85,7 +85,7 @@ void checkSensorSanity(void) | ||||
|  | ||||
|         if (sCurrentMeasurement.state == MEASUREMENT_FAULT) | ||||
|         { | ||||
|             ESP_LOGE(TAG, "%s Sensor not found!", sanityChecks[i].name); | ||||
|             //ESP_LOGE(TAG, "%s Sensor not found!", sanityChecks[i].name); | ||||
|             sanityChecks[i].state = SENSOR_NOT_FOUND; | ||||
|             sSafetyState = SAFETY_SENSOR_ERROR; | ||||
|         } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user