/* * meas_tasks.c * * Created on: Sep 5, 2024 * Author: jakubski */ #include "meas_tasks.h" #include "adc_buffers.h" #include "measurements.h" #include "node-red-config.h" #include "cmsis_os.h" #include "main.h" #ifdef PV_BOARD #define VOLTAGES_COUNT 1 #define CURRENTS_COUNT 1 #else #define VOLTAGES_COUNT 3 #define CURRENTS_COUNT 3 #endif #define CIRC_BUFF_LEN 10 osThreadId_t adc1MeasTaskHandle = NULL; osThreadId_t adc2MeasTaskHandle = NULL; osThreadId_t adc3MeasTaskHandle = NULL; osMessageQueueId_t adc1MeasDataQueue = NULL; osMessageQueueId_t adc2MeasDataQueue = NULL; osMessageQueueId_t adc3MeasDataQueue = NULL; osMutexId_t vRefmVMutex; osMutexId_t resMeasurementsMutex; osMutexId_t sensorsInfoMutex; osMutexId_t ILxRefMutex; volatile uint32_t vRefmV = 3000; RESMeasurements resMeasurements = { 0 }; SesnorsInfo sensorsInfo = { 0 }; uint16_t ILxRef[CURRENTS_COUNT] = { 0 }; void MeasTasksInit (void) { vRefmVMutex = osMutexNew (NULL); resMeasurementsMutex = osMutexNew (NULL); sensorsInfoMutex = osMutexNew (NULL); ILxRefMutex = osMutexNew (NULL); adc1MeasDataQueue = osMessageQueueNew (8, sizeof (ADC1_Data), NULL); adc2MeasDataQueue = osMessageQueueNew (8, sizeof (ADC2_Data), NULL); adc3MeasDataQueue = osMessageQueueNew (8, sizeof (ADC3_Data), NULL); osThreadAttr_t osThreadAttradc1MeasTask = { 0 }; osThreadAttr_t osThreadAttradc2MeasTask = { 0 }; osThreadAttr_t osThreadAttradc3MeasTask = { 0 }; osThreadAttradc1MeasTask.stack_size = configMINIMAL_STACK_SIZE * 2; osThreadAttradc1MeasTask.priority = (osPriority_t)osPriorityRealtime; osThreadAttradc2MeasTask.stack_size = configMINIMAL_STACK_SIZE * 2; osThreadAttradc2MeasTask.priority = (osPriority_t)osPriorityRealtime; osThreadAttradc3MeasTask.stack_size = configMINIMAL_STACK_SIZE * 2; osThreadAttradc3MeasTask.priority = (osPriority_t)osPriorityNormal; adc1MeasTaskHandle = osThreadNew (ADC1MeasTask, NULL, &osThreadAttradc1MeasTask); adc2MeasTaskHandle = osThreadNew (ADC2MeasTask, NULL, &osThreadAttradc2MeasTask); adc3MeasTaskHandle = osThreadNew (ADC3MeasTask, NULL, &osThreadAttradc3MeasTask); } void ADC1MeasTask (void* arg) { float circBuffer[VOLTAGES_COUNT][CIRC_BUFF_LEN]; float rms[VOLTAGES_COUNT]; ADC1_Data adcData = { 0 }; uint32_t circBuffPos = 0; float gainCorrection = 1.0; while (pdTRUE) { osMessageQueueGet (adc1MeasDataQueue, &adcData, 0, osWaitForever); #ifdef GAIN_AUTO_CORRECTION if (osMutexAcquire (vRefmVMutex, osWaitForever) == osOK) { gainCorrection = (float)vRefmV; osMutexRelease (vRefmVMutex); } gainCorrection = gainCorrection / EXT_VREF_mV; #endif for (uint8_t i = 0; i < VOLTAGES_COUNT; i++) { float val = adcData.adcDataBuffer[i] * deltaADC * U_CHANNEL_CONST * gainCorrection * U_MeasCorrectionData[i].gain + U_MeasCorrectionData[i].offset; circBuffer[i][circBuffPos] = val; rms[i] = 0.0; for (uint8_t c = 0; c < CIRC_BUFF_LEN; c++) { rms[i] += circBuffer[i][c]; } rms[i] = rms[i] / CIRC_BUFF_LEN; if (osMutexAcquire (resMeasurementsMutex, osWaitForever) == osOK) { if (fabs(resMeasurements.voltagePeak[i]) < fabs(val)) { resMeasurements.voltagePeak[i] = val; } resMeasurements.voltageRMS[i] = rms[i]; resMeasurements.power[i] = resMeasurements.voltageRMS[i] * resMeasurements.currentRMS[i]; osMutexRelease (resMeasurementsMutex); } } ++circBuffPos; circBuffPos = circBuffPos % CIRC_BUFF_LEN; if (osMutexAcquire (ILxRefMutex, osWaitForever) == osOK) { uint8_t refIdx = 0; for (uint8_t i = (uint8_t)IL1Ref; i <= (uint8_t)IL3Ref; i++) { ILxRef[refIdx++] = adcData.adcDataBuffer[i]; } osMutexRelease (ILxRefMutex); } } } void ADC2MeasTask (void* arg) { float circBuffer[CURRENTS_COUNT][CIRC_BUFF_LEN]; float rms[CURRENTS_COUNT]; ADC2_Data adcData = { 0 }; uint32_t circBuffPos = 0; float gainCorrection = 1.0; while (pdTRUE) { osMessageQueueGet (adc2MeasDataQueue, &adcData, 0, osWaitForever); if (osMutexAcquire (vRefmVMutex, osWaitForever) == osOK) { gainCorrection = (float)vRefmV; osMutexRelease (vRefmVMutex); } gainCorrection = gainCorrection / EXT_VREF_mV; float ref[CURRENTS_COUNT] = { 0 }; if (osMutexAcquire (ILxRefMutex, osWaitForever) == osOK) { for (uint8_t i = 0; i < CURRENTS_COUNT; i++) { ref[i] = (float)ILxRef[i]; } osMutexRelease (ILxRefMutex); } for (uint8_t i = 0; i < CURRENTS_COUNT; i++) { float adcVal = (float)adcData.adcDataBuffer[i]; float val = (adcVal - ref[i]) * deltaADC * I_CHANNEL_CONST * gainCorrection * I_MeasCorrectionData[i].gain + I_MeasCorrectionData[i].offset; circBuffer[i][circBuffPos] = val; rms[i] = 0.0; for (uint8_t c = 0; c < CIRC_BUFF_LEN; c++) { rms[i] += circBuffer[i][c]; } rms[i] = rms[i] / CIRC_BUFF_LEN; if (osMutexAcquire (resMeasurementsMutex, osWaitForever) == osOK) { if (resMeasurements.currentPeak[i] < val) { resMeasurements.currentPeak[i] = val; } resMeasurements.currentRMS[i] = rms[i]; osMutexRelease (resMeasurementsMutex); } } ++circBuffPos; circBuffPos = circBuffPos % CIRC_BUFF_LEN; } } void ADC3MeasTask (void* arg) { ADC3_Data adcData = { 0 }; while (pdTRUE) { osMessageQueueGet (adc3MeasDataQueue, &adcData, 0, osWaitForever); uint32_t vRef = __LL_ADC_CALC_VREFANALOG_VOLTAGE (adcData.adcDataBuffer[VrefInt], LL_ADC_RESOLUTION_16B); if (osMutexAcquire (vRefmVMutex, osWaitForever) == osOK) { vRefmV = vRef; osMutexRelease (vRefmVMutex); } } }