115 lines
3.6 KiB
C++
115 lines
3.6 KiB
C++
#include <cstring>
|
|
#include "computing.h"
|
|
|
|
uint8_t ExtAdcBuffer[EXT_ADC_BUFFER_SIZE];
|
|
|
|
|
|
bool computeAdcResults(uint32_t &freq, double &litude, double &dc) {
|
|
// Краевые значения не обрабатываем
|
|
#define edge1 32
|
|
|
|
// Частота АЦП
|
|
const double Fd = (168.0f / 9.0f) * 1e6f; // Частота дискретизации в герцах
|
|
|
|
// uint8_t ExtAdcBuffer[EXT_ADC_BUFFER_SIZE];
|
|
|
|
// Применем медианный фильтр
|
|
// MedianFilter3();
|
|
|
|
// Применим фильтр скользящего среднеего
|
|
// MovAvgFilter5();
|
|
|
|
// **************************************************************************
|
|
// Оценка размаха. Построим гистограмму
|
|
// знаем, что разрядность АЦП 8 бит - 256 значений
|
|
|
|
// Обнуляем вспомогательный массив
|
|
int gg[256];
|
|
memset(gg, 0, sizeof(gg));
|
|
|
|
// Формируем гистограмму
|
|
for (uint16_t i = edge1; i < EXT_ADC_BUFFER_SIZE - edge1; i++)
|
|
gg[ExtAdcBuffer[i]]++;
|
|
|
|
// Оцениваем пики гистограммы
|
|
|
|
int xm = 0;
|
|
uint8_t km1 = 0;
|
|
uint8_t km2 = 0;
|
|
for (uint16_t i = 0; i < 120; i++) {
|
|
if (xm < gg[i]) {
|
|
xm = gg[i];
|
|
km1 = i;
|
|
}
|
|
}
|
|
|
|
xm = 0;
|
|
for (uint16_t i = 134; i <= 0xFF; i++) {
|
|
if (xm < gg[i]) {
|
|
xm = gg[i];
|
|
km2 = i;
|
|
}
|
|
}
|
|
|
|
// Определяем оценку напряжения в милливольтах, применительно к размаху АЦП
|
|
amplitude = (double) (km2 - km1) / 256.0;
|
|
amplitude *= 2.6048450117218023; // NOTE: магический кофицент для схемы
|
|
|
|
// расчет постоянной составляющей
|
|
dc = ((((double) km1 + (double) km2) / 2.0f) / 256.0f * 1000.0f) + 2000.0f;
|
|
// y = 2 + x
|
|
|
|
|
|
// **************************************************************************
|
|
// Оцениваем частоту
|
|
// Считаем, что 128й уровень находится ровно посередине
|
|
|
|
const uint16_t z = 8; // Защитный интервал
|
|
uint32_t xk1 = 0;
|
|
uint32_t xk2 = 0;
|
|
uint32_t xsum = 0;
|
|
uint32_t xnum = 0;
|
|
|
|
uint32_t i = edge1;
|
|
// ищем переходы через 128
|
|
while ((i < EXT_ADC_BUFFER_SIZE - edge1) && (ExtAdcBuffer[i] > 128))
|
|
i++;
|
|
i = i + z;
|
|
while ((i < EXT_ADC_BUFFER_SIZE - edge1) && (ExtAdcBuffer[i] < 128))
|
|
i++;
|
|
xk1 = i;
|
|
while ((i < EXT_ADC_BUFFER_SIZE - edge1) && (ExtAdcBuffer[i] > 128))
|
|
i++;
|
|
i = i + z;
|
|
while ((i < EXT_ADC_BUFFER_SIZE - edge1) && (ExtAdcBuffer[i] < 128))
|
|
i++;
|
|
xk2 = i;
|
|
i = i + i;
|
|
xsum = xk2 - xk1;
|
|
xnum = 1;
|
|
|
|
// Находим много периодов
|
|
while (i < EXT_ADC_BUFFER_SIZE - edge1) {
|
|
while ((i < EXT_ADC_BUFFER_SIZE - edge1) && (ExtAdcBuffer[i] > 128))
|
|
i++;
|
|
i = i + z;
|
|
while ((i < EXT_ADC_BUFFER_SIZE - edge1) && (ExtAdcBuffer[i] < 128))
|
|
i++;
|
|
if (i < EXT_ADC_BUFFER_SIZE - edge1) {
|
|
xsum = xsum + (i - xk2);
|
|
xnum++;
|
|
xk2 = i;
|
|
}
|
|
i = i + z;
|
|
}
|
|
// Оценка частоты в герцах
|
|
freq = (uint32_t) (Fd / (double) xsum * (double) xnum);
|
|
|
|
// Посмотрим, если есть переполнение АЦП в одну или в друнгую сторону, то
|
|
// выдадим ошибку
|
|
if ((km1 == 0) | (km2 == 255))
|
|
return (false);
|
|
else
|
|
return (true);
|
|
}
|