| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- /**
- * @file ALGO_WaveAnalyse_ATY.c
- *
- * @param Project ALGO_Algorithm_ATY_LIB
- *
- * @author ATY
- *
- * @copyright
- * - Copyright 2017 - 2026 MZ-ATY
- * - This code follows:
- * - MZ-ATY Various Contents Joint Statement -
- * <a href="https://mengze.top/MZ-ATY_VCJS">
- * https://mengze.top/MZ-ATY_VCJS</a>
- * - CC 4.0 BY-NC-SA -
- * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
- * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
- * - Your use will be deemed to have accepted the terms of this statement.
- *
- * @brief functions of wave analyse from ad
- *
- * @version
- * - 1_01_220601 > ATY
- * -# Preliminary version, first Release
- * - todo
- ********************************************************************************
- */
- #ifndef __ALGO_WaveAnalyse_ATY_C
- #define __ALGO_WaveAnalyse_ATY_C
- #include "ALGO_WaveAnalyse_ATY.h"
- /******************************* For user *************************************/
- /******************************************************************************/
- // wave_lastWaveAve_Kalman use last calc signal base voltage or direct signal base voltage
- uint16_t wave_lastWaveAve_Kalman = 0;
- // uint16_t wave_lastWaveAve_Kalman = 1468;
- /**
- * @brief find peak and zero points from origin wave data
- * @param inputWave origin wave data from adc
- * @param kalmanWave wave data after kalman filter
- * @param deepKalmanWave wave data after deep kalman filter, wave averange save to [0]
- * @param peakZeroPoints peak and zero points
- * @param size deal size
- * @note inputWave/kalmanWave/deepKalmanWave/peakZeroPoints group size must >= size
- */
- void WavePeakZeroPointFind(
- uint16_t* inputWave,
- uint16_t* kalmanWave,
- uint16_t* deepKalmanWave,
- uint16_t* peakZeroPoints,
- uint16_t size)
- {
- uint16_t i = 0;
- ALGO_Kalman1D_S temp_kfpDeep = {1, 0, 0, 0, 0, 0};
- int tempKalmanDiff = 0; // size should be a multiple of 5
- /* first smoothing in kalman **********************************************/
- ALGO_Kalman1D_S temp_kfp = {1, 0, 0, 0, 0, 0};
- temp_kfp.Q = 0.000000001;
- temp_kfp.R = 0.000001;
- // kalman filter delay 12 points
- for(i = 0; i < size; i++)
- kalmanWave[i] = (uint16_t)ALGO_KalmanFilter1D(&temp_kfp, (float)inputWave[i]);
- /* find difference for peaks and troughs **********************************/
- for(i = 1; i < size; i++)
- {
- if(kalmanWave[i - 1] > kalmanWave[i])
- peakZeroPoints[i] = WAVE_BASE_AVE + 1;
- else if(kalmanWave[i - 1] < kalmanWave[i])
- peakZeroPoints[i] = WAVE_BASE_AVE - 1;
- else
- peakZeroPoints[i] = peakZeroPoints[i - 1];
- }
- /* find peaks point and add base value to display *************************/
- for(i = 1; i < size; i++)
- {
- if(peakZeroPoints[i - 1] < peakZeroPoints[i])
- peakZeroPoints[i - 1] = WAVE_DISPLAY_PEAK_HIGH;
- else if(peakZeroPoints[i - 1] > peakZeroPoints[i])
- peakZeroPoints[i - 1] = WAVE_DISPLAY_PEAK_LOW;
- else
- peakZeroPoints[i - 1] = WAVE_BASE_AVE;
- }
- /* calc averange through deep kalman **************************************/
- temp_kfpDeep.Q = 0;
- temp_kfpDeep.R = 1;
- for(i = 0; i < size; i++)
- deepKalmanWave[i] = (uint16_t)ALGO_KalmanFilter1D(&temp_kfpDeep, (float)inputWave[i]);
- deepKalmanWave[0] = deepKalmanWave[size * 3 / 5];
- for(i = size * 3 / 5; i < size * 4 / 5; i++)
- tempKalmanDiff += deepKalmanWave[i] - deepKalmanWave[size * 3 / 5];
- tempKalmanDiff /= (float)(size / 5.0);
- deepKalmanWave[0] += tempKalmanDiff; // wave averange
- // printf("\r\ndeepKalmanAve: %d\r\n", deepKalmanWave[0]);
- /* find zero points with rise and fall and add base value to display ******/
- for(i = 1; i < size; i++)
- {
- if((kalmanWave[i - 1] < deepKalmanWave[0]) && (kalmanWave[i] >= deepKalmanWave[0]))
- {
- if(deepKalmanWave[0] - kalmanWave[i - 1] <= kalmanWave[i] - deepKalmanWave[0])
- peakZeroPoints[i - 1] = WAVE_DISPLAY_ZERO_RAISE;
- else
- peakZeroPoints[i] = WAVE_DISPLAY_ZERO_RAISE;
- }
- else if((kalmanWave[i - 1] > deepKalmanWave[0]) && (kalmanWave[i] <= deepKalmanWave[0]))
- {
- if(kalmanWave[i - 1] - deepKalmanWave[0] <= deepKalmanWave[0] - kalmanWave[i])
- peakZeroPoints[i - 1] = WAVE_DISPLAY_ZERO_FALL;
- else
- peakZeroPoints[i] = WAVE_DISPLAY_ZERO_FALL;
- }
- }
- }
- /* First wave find ************************************************************/
- uint16_t wave_firstWavePeakPoint = 0, wave_firstWaveZeroPoint = 0;
- /**
- * @brief find peak and zero points from origin wave data
- * @param kalmanWave wave data from kalman filter
- * @param peakZeroPoints peak and zero points
- * @param size deal size
- * @note kalmanWave/peakZeroPoints group size must >= size
- */
- void WaveFirstPulseFind(uint16_t* kalmanWave, uint16_t* peakZeroPoints, uint16_t size)
- {
- // zero point must near mid of high peak and low peak, then count 1 valid wave data
- // step 1: find one high peak higher than vol
- // step 2: this high peak near last zero point is rise and neaxt zero point is fall
- // step 3(todo): high point subtract last zero and next zero, two space little than a value, save this high peak point
- // step 4: find low peak like this
- // step 5: find next 10 point like this
- uint16_t i = 0, j = 0, k = 0;
- uint8_t firstWaveAnalyseStep = 0, firstWaveAnalyseCount = 0;
- uint8_t secondZeroPoint = 0;
- wave_firstWavePeakPoint = 0;
- wave_firstWaveZeroPoint = 0;
- for(i = 1; i < size; i++)
- {
- if((firstWaveAnalyseStep == 0)
- && (peakZeroPoints[i] == WAVE_DISPLAY_PEAK_HIGH))
- {
- if(kalmanWave[i] > FIRST_THRESHOLD_HIGH)
- {
- if(firstWaveAnalyseCount == 0)
- wave_firstWavePeakPoint = i;
- for(j = i - 1; j > 0; j--)
- {
- if(peakZeroPoints[j] != WAVE_BASE_AVE)
- {
- if(peakZeroPoints[j] == WAVE_DISPLAY_ZERO_RAISE)
- {
- if(firstWaveAnalyseCount == 0)
- wave_firstWaveZeroPoint = j;
- for(k = i + 1; k < size; k++)
- {
- if(peakZeroPoints[k] != WAVE_BASE_AVE)
- {
- if(peakZeroPoints[k] == WAVE_DISPLAY_ZERO_FALL)
- {
- firstWaveAnalyseStep = 2;
- }
- else
- {
- wave_firstWavePeakPoint = 0;
- wave_firstWaveZeroPoint = 0;
- firstWaveAnalyseStep = 0;
- firstWaveAnalyseCount = 0;
- }
- break;
- }
- }
- }
- else
- {
- wave_firstWavePeakPoint = 0;
- wave_firstWaveZeroPoint = 0;
- firstWaveAnalyseStep = 0;
- firstWaveAnalyseCount = 0;
- }
- break;
- }
- }
- }
- else
- {
- wave_firstWavePeakPoint = 0;
- wave_firstWaveZeroPoint = 0;
- firstWaveAnalyseStep = 0;
- firstWaveAnalyseCount = 0;
- }
- }
- else if((firstWaveAnalyseStep == 2)
- && (peakZeroPoints[i] == WAVE_DISPLAY_PEAK_LOW))
- {
- if(kalmanWave[i] < FIRST_THRESHOLD_LOW)
- {
- for(j = i - 1; j > 0; j--)
- {
- if(peakZeroPoints[j] != WAVE_BASE_AVE)
- {
- if(peakZeroPoints[j] == WAVE_DISPLAY_ZERO_FALL)
- {
- if(secondZeroPoint == 0)
- {
- secondZeroPoint = j;
- if(((j - wave_firstWavePeakPoint) > (wave_firstWavePeakPoint - wave_firstWaveZeroPoint)
- && (j - wave_firstWavePeakPoint) - (wave_firstWavePeakPoint - wave_firstWaveZeroPoint) > 5)
- || ((wave_firstWavePeakPoint - wave_firstWaveZeroPoint) > (j - wave_firstWavePeakPoint)
- && (wave_firstWavePeakPoint - wave_firstWaveZeroPoint) - (j - wave_firstWavePeakPoint) > 5))
- break;
- }
- for(k = i + 1; k < size; k++)
- {
- if(peakZeroPoints[k] != WAVE_BASE_AVE)
- {
- if(peakZeroPoints[k] == WAVE_DISPLAY_ZERO_RAISE)
- {
- firstWaveAnalyseStep = 4;
- }
- else
- {
- wave_firstWavePeakPoint = 0;
- wave_firstWaveZeroPoint = 0;
- firstWaveAnalyseStep = 0;
- firstWaveAnalyseCount = 0;
- }
- break;
- }
- }
- }
- else
- {
- wave_firstWavePeakPoint = 0;
- wave_firstWaveZeroPoint = 0;
- firstWaveAnalyseStep = 0;
- firstWaveAnalyseCount = 0;
- }
- break;
- }
- }
- }
- else
- {
- wave_firstWavePeakPoint = 0;
- wave_firstWaveZeroPoint = 0;
- firstWaveAnalyseStep = 0;
- firstWaveAnalyseCount = 0;
- }
- }
- if(firstWaveAnalyseStep == 4)
- {
- firstWaveAnalyseStep = 0;
- firstWaveAnalyseCount++;
- if(firstWaveAnalyseCount >= WAVE_FIRST_COUNT)
- break;
- }
- }
- if(firstWaveAnalyseCount < WAVE_FIRST_COUNT)
- {
- wave_firstWavePeakPoint = 0;
- wave_firstWaveZeroPoint = 0;
- firstWaveAnalyseStep = 0;
- firstWaveAnalyseCount = 0;
- }
- }
- /* Calc wave period and frequence *********************************************/
- uint16_t wave_quarterSpace = 0;
- /**
- * @brief calculate period and frequence
- * @param peakZeroPoints wave peak and zero points after WavePeakZeroPointFind()
- * @param firstWavePoint first wave pulse zero point, where to start analyse
- * @param size deal size
- * @note peakZeroPoints group size must >= size, function suit freq < 100KHz
- */
- void WaveParamCalc(uint16_t* peakZeroPoints, uint16_t firstWavePoint, uint16_t size)
- {
- uint16_t i = 0;
- float wavePeriod = 0.0, waveFreq = 0.0;
- uint16_t lastPoint = 0;
- uint16_t lastSpace = 0, newSpace = 0;
- uint16_t repetitionCount = 0;
- ALGO_Kalman1D_S temp_kfpDeep = {1, 0, 0, 0, 0, 0};
- temp_kfpDeep.Q = 0;
- temp_kfpDeep.R = 1;
- for(i = firstWavePoint; i < size; i++)
- {
- if(peakZeroPoints[i] != WAVE_BASE_AVE)
- {
- newSpace = i - lastPoint;
- if(repetitionCount < 2000)
- {
- // filter big changes at begining
- if((newSpace < lastSpace + 3) && (newSpace + 3 > lastSpace) && (newSpace > 5))
- {
- repetitionCount++;
- if(temp_kfpDeep.L_P == 1)
- temp_kfpDeep.L_P = newSpace;
- // carry, float to uint
- wave_quarterSpace = ALGO_KalmanFilter1D(&temp_kfpDeep, (float)newSpace) + 0.6;
- // printf("$%d %d;", newSpace, wave_quarterSpace);
- }
- else
- repetitionCount = 0;
- }
- else
- {
- // printf("$0 %d;", i);
- break;
- }
- lastSpace = newSpace;
- lastPoint = i;
- }
- }
- if(wave_quarterSpace > 0)
- {
- wavePeriod = wave_quarterSpace * 4.0 * ADC_TIME_UNIT;
- waveFreq = 1000.0 / wavePeriod;
- // printf("$%d %f %f;", wave_quarterSpace, wavePeriod, waveFreq);
- peakZeroPoints[0] = wave_quarterSpace;
- }
- }
- /* Calc wave vpp voltage ******************************************************/
- uint16_t wave_maxVpp = 0;
- /**
- * @brief find peak and zero points from origin wave data
- * @param kalmanWave wave data from kalman filter
- * @param peakZeroPoints peak and zero points
- * @param size deal size
- * @note kalmanWave/peakZeroPoints group size must >= size
- */
- void WaveVppCalc(uint16_t* kalmanWave, uint16_t* peakZeroPoints, uint16_t size)
- {
- uint16_t i = 0;
- uint16_t lastWaveValue = 0;
- float maxVppVoltagge;
- for(i = 0; i < size; i++)
- {
- if((peakZeroPoints[i] == WAVE_DISPLAY_PEAK_HIGH) || (peakZeroPoints[i] == WAVE_DISPLAY_PEAK_LOW))
- {
- if(lastWaveValue != 0)
- {
- if(wave_maxVpp < kalmanWave[i] - lastWaveValue)
- wave_maxVpp = kalmanWave[i] - lastWaveValue;
- // printf("$%d %d %d %d;", kalmanWave[i], lastWaveValue, wave_maxVpp);
- }
- lastWaveValue = kalmanWave[i];
- }
- }
- maxVppVoltagge = 2.5 * (wave_maxVpp * WAVE_KALMAN_ATTENUATION) / 4096.0;
- }
- void WaveWholeProcess(
- uint16_t* inputWave,
- uint16_t* kalmanWave,
- uint16_t* deepKalmanWave,
- uint16_t* peakZeroPoints,
- uint16_t size)
- {
- wave_firstWavePeakPoint = 0;
- wave_firstWaveZeroPoint = 0;
- wave_quarterSpace = 0;
- wave_maxVpp = 0;
- WavePeakZeroPointFind(inputWave, kalmanWave, deepKalmanWave, peakZeroPoints, size);
- WaveFirstPulseFind(kalmanWave, peakZeroPoints, size);
- WaveParamCalc(peakZeroPoints, wave_firstWaveZeroPoint, size);
- WaveVppCalc(kalmanWave, peakZeroPoints, size);
- wave_lastWaveAve_Kalman = deepKalmanWave[0];
- }
- #ifdef __DEBUG_WAVE_ATY
- uint16_t kalmanWave_Test[TEST_WAVE_SIZE] = {0};
- uint16_t deepKalmanWave_Test[TEST_WAVE_SIZE] = {0};
- uint16_t peakZeroPoints_Test[TEST_WAVE_SIZE] = {0};
- void WaveAnalyse_Test(uint16_t* testWaveDataIn, uint8_t WAVE_DISPLAY_FLAG)
- {
- uint16_t i = 0;
- // debug WaveAnalyse test
- // IWDG_ENABLE_WRITE_ACCESS(&hiwdg);
- // hiwdg.Instance->PR = IWDG_PRESCALER_256;
- // hiwdg.Instance->RLR = 0xFFFFFFFF;
- // HAL_IWDG_Refresh(&hiwdg);
- WaveWholeProcess(testWaveDataIn, kalmanWave_Test, deepKalmanWave_Test, peakZeroPoints_Test, TEST_WAVE_SIZE);
- // WAVE_DISPLAY_FLAG = 1;
- if(WAVE_DISPLAY_FLAG)
- {
- if(WAVE_DISPLAY_FLAG == 1)
- {
- // for(uint16_t i = 0; i < TEST_WAVE_SIZE; i++)
- for(i = 0; i < 2000; i++)
- {
- // this "for" need feed watch dog or close it
- // HAL_IWDG_Refresh(&hiwdg);
- printf("$");
- printf("%04d ", testWaveDataIn[i]);
- printf("%04d ", kalmanWave_Test[i]);
- // printf("%04d ", deepKalmanWave_Test[i]);
- // printf("%04d ", deepKalmanWave_Test[0]); // wave averange
- printf("%04d ", peakZeroPoints_Test[i]);
- printf("%04d ", peakZeroPoints_Test[0] * 200); // wave 1/4 period points space
- if(i == wave_firstWavePeakPoint)
- printf("%d ", 3000);
- else if(i == wave_firstWaveZeroPoint)
- printf("%d ", 0);
- else
- printf("%d ", deepKalmanWave_Test[0]);
- printf("%d ", wave_firstWavePeakPoint * 10);
- // printf("%f ", wave_firstWavePeakPoint * ADC_TIME_UNIT);
- // printf("%d ", wave_quarterSpace);
- // printf("%f ", wave_quarterSpace * 4.0 * ADC_TIME_UNIT);
- // printf("%f ", 1000.0 / (wave_quarterSpace * 4.0 * ADC_TIME_UNIT));
- // printf("%d ", wave_maxVpp);
- // printf("%f ", 2.5 * (wave_maxVpp * WAVE_KALMAN_ATTENUATION) / 4096.0);
- printf(";");
- }
- }
- else if(WAVE_DISPLAY_FLAG == 2)
- {
- printf("$");
- printf("%d ", wave_firstWavePeakPoint);
- // printf("%f ", wave_firstWavePeakPoint * ADC_TIME_UNIT);
- printf("%d ", wave_quarterSpace * 40);
- // printf("%d ", wave_quarterSpace);
- // printf("%f ", wave_quarterSpace * 4.0 * ADC_TIME_UNIT);
- // printf("%f ", 1000.0 / (wave_quarterSpace * 4.0 * ADC_TIME_UNIT));
- printf("%d ", wave_maxVpp);
- // printf("%f ", 2.5 * (wave_maxVpp * WAVE_KALMAN_ATTENUATION) / 4096.0);
- printf(";");
- }
- // printf("$%d;", 0);
- }
- }
- #endif /* __DEBUG_WAVE_ATY */
- #endif /* __ALGO_WaveAnalyse_ATY_C */
- /******************************** End Of File *********************************/
|