третья часть, плюс добавил программу для анализа результатов из курского проекта. правда она что-то не то показывает.... но разберусь завтра
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.28)
|
||||||
|
project(tests)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
|
add_executable(tests main.cpp computing.cpp computing.h)
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
#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);
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#ifndef KURSK_F407_SLAVES_H
|
||||||
|
#define KURSK_F407_SLAVES_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
// 64к = 0x10000, words 16к = 0x4000
|
||||||
|
// 32к = 0x8000, words 16к = 0x2000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Размер буфера внешнего ADC
|
||||||
|
*/
|
||||||
|
#define EXT_ADC_BUFFER_SIZE 0x8000
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Буфер, куда попадают данные внешнего ADC.
|
||||||
|
*/
|
||||||
|
extern uint8_t ExtAdcBuffer[EXT_ADC_BUFFER_SIZE];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Функция, выполняющая расчет частоты и амплитуды на основании данных АЦП.
|
||||||
|
* Определение этой функции можно будет изменить, если это требуется
|
||||||
|
* @param freq частота
|
||||||
|
* @param amplitude амплитуда
|
||||||
|
* @param dc постоянная составляющая
|
||||||
|
* @return true, в случае если в процессе обработки не возникло ошибок, в противном случае false
|
||||||
|
*/
|
||||||
|
bool computeAdcResults(uint32_t &freq, double &litude, double &dc);
|
||||||
|
|
||||||
|
#endif //__cplusplus
|
||||||
|
|
||||||
|
#endif //KURSK_F407_SLAVES_H
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <regex>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstring>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "computing.h"
|
||||||
|
|
||||||
|
bool computeAdcResults(uint32_t &freq, double &litude, double &dc);
|
||||||
|
|
||||||
|
struct TestInfo {
|
||||||
|
uint32_t referenceFreqKhz;
|
||||||
|
double referenceAmplitudeMv;
|
||||||
|
std::filesystem::path fileName;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::optional<TestInfo> parseFileName(const std::filesystem::path &path) {
|
||||||
|
static const std::regex re(R"((\d+)\s*khz.*?(\d+)\s*mv)",
|
||||||
|
std::regex::icase);
|
||||||
|
|
||||||
|
std::smatch match;
|
||||||
|
std::string name = path.stem().string();
|
||||||
|
|
||||||
|
if (!std::regex_search(name, match, re))
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
TestInfo info;
|
||||||
|
info.referenceFreqKhz = std::stoul(match[1].str());
|
||||||
|
info.referenceAmplitudeMv = std::stod(match[2].str());
|
||||||
|
info.fileName = path;
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool loadSamples(const std::filesystem::path &path, std::vector<uint8_t> &samples) {
|
||||||
|
std::ifstream file(path);
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
samples.clear();
|
||||||
|
|
||||||
|
unsigned value;
|
||||||
|
|
||||||
|
while (file >> value) {
|
||||||
|
if (value > 255)
|
||||||
|
return false;
|
||||||
|
samples.push_back(static_cast<uint8_t>(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return !samples.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
std::cout
|
||||||
|
<< "File\t"
|
||||||
|
<< "Freq_ref_kHz\t"
|
||||||
|
<< "Amp_ref_mV\t"
|
||||||
|
<< "Freq_alg_kHz\t"
|
||||||
|
<< "Amp_alg_mV\t"
|
||||||
|
<< "Freq_abs_err_kHz\t"
|
||||||
|
<< "Freq_rel_err_% \t"
|
||||||
|
<< "Amp_abs_err_mV\t"
|
||||||
|
<< "Amp_rel_err_%"
|
||||||
|
<< '\n';
|
||||||
|
|
||||||
|
for (const auto &entry : fs::directory_iterator("."))
|
||||||
|
{
|
||||||
|
if (!entry.is_regular_file())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (entry.path().extension() != ".txt")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto info = parseFileName(entry.path());
|
||||||
|
|
||||||
|
if (!info)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::vector<uint8_t> samples;
|
||||||
|
|
||||||
|
if (!loadSamples(entry.path(), samples))
|
||||||
|
{
|
||||||
|
std::cerr << "Cannot read " << entry.path() << '\n';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (samples.size() != EXT_ADC_BUFFER_SIZE) {
|
||||||
|
std::cerr << "ERROR: " << entry.path() << " invalid samples count: expect " << EXT_ADC_BUFFER_SIZE << ", got " << samples.size() << '\n';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
memcpy(ExtAdcBuffer, samples.data(), samples.size());
|
||||||
|
|
||||||
|
uint32_t freqHz = 0;
|
||||||
|
double amplitude = 0.0;
|
||||||
|
double dc = 0.0;
|
||||||
|
|
||||||
|
if (!computeAdcResults(freqHz, amplitude, dc)) {
|
||||||
|
std::cerr << "Processing failed: " << entry.path() << '\n';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const double freq = static_cast<double>(freqHz) / 1000.0;
|
||||||
|
amplitude = amplitude * 1000.0;
|
||||||
|
|
||||||
|
double freqAbsError = std::abs(static_cast<double>(freq) - info->referenceFreqKhz);
|
||||||
|
double freqRelError = freqAbsError / info->referenceFreqKhz * 100.0;
|
||||||
|
double ampAbsError = std::abs(amplitude - info->referenceAmplitudeMv);
|
||||||
|
double ampRelError = ampAbsError / info->referenceAmplitudeMv * 100.0;
|
||||||
|
|
||||||
|
std::cout
|
||||||
|
<< entry.path().filename().string() << '\t'
|
||||||
|
<< info->referenceFreqKhz << '\t'
|
||||||
|
<< info->referenceAmplitudeMv << '\t'
|
||||||
|
<< freq << '\t'
|
||||||
|
<< std::fixed << std::setprecision(2) << amplitude << '\t'
|
||||||
|
<< freqAbsError << '\t'
|
||||||
|
<< freqRelError << '\t'
|
||||||
|
<< ampAbsError << '\t'
|
||||||
|
<< ampRelError
|
||||||
|
<< '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,398 +0,0 @@
|
|||||||
// Статические переменные
|
|
||||||
|
|
||||||
funcprot(0);
|
|
||||||
|
|
||||||
Fx = 330000; // Измеряемая частота
|
|
||||||
|
|
||||||
F1 = Fx*1.1; // Максимальная частота
|
|
||||||
F11 = Fx*0.9; // Минимальная чстота
|
|
||||||
|
|
||||||
A1 = 0.25; // Амплитуда измеряемой величины
|
|
||||||
Fp = 100; // Частота помехи
|
|
||||||
Ap = 1; // Амплитуда помехи
|
|
||||||
// Tm = 10e-3; // Время выборки
|
|
||||||
Fd = 168/9*1e6; // Частота дискретизации
|
|
||||||
NADC = 8; // Количество бит АЦП
|
|
||||||
|
|
||||||
nmem = 2^16; // количество ячеек памяти
|
|
||||||
// определим время выборки
|
|
||||||
Td = 1/Fd;
|
|
||||||
Tm = nmem * Td
|
|
||||||
nn=int(Tm/Td);
|
|
||||||
Aop=(1.25+1);
|
|
||||||
Amax=(1.25+1)+Aop;
|
|
||||||
AmaxADC = Amax*1.2;
|
|
||||||
|
|
||||||
StepADC = AmaxADC / (2^NADC);
|
|
||||||
|
|
||||||
// Fi1 - начальная фаза исходного сигнала
|
|
||||||
// Fip - начальная фаза помехи
|
|
||||||
// Генерация выборок исходного сигнала
|
|
||||||
Fi1=0
|
|
||||||
|
|
||||||
function s1 = ADC1()
|
|
||||||
// Fi1 = rand()*2*%pi;
|
|
||||||
//Fi1=Fi1+%pi/100;
|
|
||||||
disp(Fi1);
|
|
||||||
Fip = rand()*2*%pi;
|
|
||||||
Omega1 = 2*%pi*F1;
|
|
||||||
Omegap = 2*%pi*Fp;
|
|
||||||
s1=zeros(nn);
|
|
||||||
// Отклонение частоты генератора
|
|
||||||
if rand()>0.5 then
|
|
||||||
Td123 = Td*1.0001;
|
|
||||||
else
|
|
||||||
Td123 = Td*0.9999;
|
|
||||||
end
|
|
||||||
disp(1/Td123/1e6)
|
|
||||||
for ii=1:nn
|
|
||||||
ti = Td123*ii
|
|
||||||
sTMP = A1*cos(Omega1*ti+Fi1) + Ap*cos(Omegap*ti+Fip) + Aop;
|
|
||||||
s1(ii) = int(sTMP/StepADC)*StepADC; // Округление АЦП
|
|
||||||
end
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
// Формирование целочисленного массива 256 уровней
|
|
||||||
function s1 = ADC2()
|
|
||||||
// Fi1 = rand()*2*%pi;
|
|
||||||
//Fi1=Fi1+%pi/100;
|
|
||||||
disp(Fi1);
|
|
||||||
Fip = rand()*2*%pi;
|
|
||||||
Omega1 = 2*%pi*F1;
|
|
||||||
Omegap = 2*%pi*Fp;
|
|
||||||
s1=zeros(nn);
|
|
||||||
// Отклонение частоты генератора
|
|
||||||
if rand()>0.5 then
|
|
||||||
Td123 = Td*1.0001;
|
|
||||||
else
|
|
||||||
Td123 = Td*0.9999;
|
|
||||||
end
|
|
||||||
disp(1/Td123/1e6)
|
|
||||||
for ii=1:nn
|
|
||||||
ti = Td123*ii
|
|
||||||
sTMP = A1*cos(Omega1*ti+Fi1) + Ap*cos(Omegap*ti+Fip) + Aop;
|
|
||||||
s1(ii) = int(sTMP/StepADC); // Округление АЦП
|
|
||||||
end
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
// Медианный фильтр по пяти точкам
|
|
||||||
function s2 = Median5(s1)
|
|
||||||
nn=size(s1,1);
|
|
||||||
for ii = 1:(nn-5)
|
|
||||||
v1(1)=s1(ii);
|
|
||||||
v1(2)=s1(ii+1);
|
|
||||||
v1(3)=s1(ii+2);
|
|
||||||
v1(4)=s1(ii+3);
|
|
||||||
v1(5)=s1(ii+4);
|
|
||||||
v2 = gsort(v1);
|
|
||||||
s2(ii) = v2(3);
|
|
||||||
end
|
|
||||||
s2(nn-4)=s1(nn-4);
|
|
||||||
s2(nn-3)=s1(nn-3);
|
|
||||||
s2(nn-2)=s1(nn-2);
|
|
||||||
s2(nn-1)=s1(nn-1);
|
|
||||||
s2(nn)=s1(nn);
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
// Медианный фильтр по трём точкам
|
|
||||||
function s2 = Median3(s1)
|
|
||||||
nn = size(s1,1);
|
|
||||||
for ii = 1:(nn-5)
|
|
||||||
v1(1)=s1(ii);
|
|
||||||
v1(2)=s1(ii+1);
|
|
||||||
v1(3)=s1(ii+2);
|
|
||||||
v1(4)=s1(ii+3);
|
|
||||||
v1(5)=s1(ii+4);
|
|
||||||
v2 = gsort(v1);
|
|
||||||
s2(ii) = v2(3);
|
|
||||||
end
|
|
||||||
s2(nn-4)=s1(nn-4);
|
|
||||||
s2(nn-3)=s1(nn-3);
|
|
||||||
s2(nn-2)=s1(nn-2);
|
|
||||||
s2(nn-1)=s1(nn-1);
|
|
||||||
s2(nn)=s1(nn);
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
// Скользящее среднее по пяти точкам
|
|
||||||
function s2 = Mov_avg(s1)
|
|
||||||
nn = size(s1,1);
|
|
||||||
s2 = zeros(1:nn);
|
|
||||||
x1 = 0;
|
|
||||||
for i=1:5
|
|
||||||
x1 = x1 + s1(i);
|
|
||||||
s2(i) = s1(i);
|
|
||||||
end
|
|
||||||
for i=5:nn-1
|
|
||||||
s2(i) = int(x1/5);
|
|
||||||
x1 = x1-s1(i-4);
|
|
||||||
x1 = x1+s1(i+1);
|
|
||||||
end
|
|
||||||
s2(nn) = s1(nn);
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
// Средний размах + Оценка периода
|
|
||||||
function [Fest, Sum1, s3] = Filter2(s2)
|
|
||||||
nx = int((2/F11)/Td);
|
|
||||||
nx2 = int((1/4/F11)/Td);
|
|
||||||
// disp(nx);
|
|
||||||
// disp(nx2);
|
|
||||||
|
|
||||||
if nx2<2 then
|
|
||||||
nx2 = 2;
|
|
||||||
end
|
|
||||||
s5 = zeros(nn);
|
|
||||||
// for ii=1:nn-nx+1
|
|
||||||
// s4(1:nx) = s2(ii:ii+nx-1)
|
|
||||||
// vmax=max(s4);
|
|
||||||
// vmin=min(s4);
|
|
||||||
// vref=(vmax+vmin)/2;
|
|
||||||
// s5(ii) = s2(ii) - vref;
|
|
||||||
// s3(ii) = vmax-vmin;
|
|
||||||
// end
|
|
||||||
|
|
||||||
for ii=0:int(nn/nx)-1
|
|
||||||
s4(1:nx) = s2(1+ii*nx:ii*nx+nx)
|
|
||||||
vmax=max(s4);
|
|
||||||
vmin=min(s4);
|
|
||||||
vref=(vmax+vmin)/2;
|
|
||||||
s5(1+ii*nx:ii*nx+nx) = s2(1+ii*nx:ii*nx+nx) - vref;
|
|
||||||
s3(1+ii*nx:ii*nx+nx) = vmax-vmin;
|
|
||||||
end
|
|
||||||
|
|
||||||
Sum1=0;
|
|
||||||
for ii=1:nn-nx;
|
|
||||||
Sum1=Sum1+s3(ii);
|
|
||||||
end
|
|
||||||
Sum1=Sum1/(nn-nx);
|
|
||||||
// Считаем периоды и оцениваем частоту
|
|
||||||
nper = 0;
|
|
||||||
jj=1;
|
|
||||||
while s5(jj)>0
|
|
||||||
jj=jj+1
|
|
||||||
end
|
|
||||||
while s5(jj)<0
|
|
||||||
jj=jj+1
|
|
||||||
end
|
|
||||||
kk1 = jj
|
|
||||||
while jj<nn-nx
|
|
||||||
jj = jj + nx2;
|
|
||||||
while (jj<nn-nx) && (s5(jj)<0)
|
|
||||||
jj=jj+1;
|
|
||||||
end
|
|
||||||
nper = nper +1;
|
|
||||||
kk2 = jj;
|
|
||||||
jj = jj + nx2;
|
|
||||||
while (jj<nn-nx) &&(s5(jj)>0)
|
|
||||||
jj=jj+1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Fest = 1/(((kk2-kk1)*Td)/nper);
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function gg=MyHist1(sw1)
|
|
||||||
// Формируем гистограмму из массива
|
|
||||||
// знаем, что разрядность АЦП 8 бит - 256 значений
|
|
||||||
gg=zeros(1:256);
|
|
||||||
for i=1:size(sw1,1)
|
|
||||||
nn=int(sw1(i)/StepADC);
|
|
||||||
gg(nn)=gg(nn)+1;
|
|
||||||
end
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function gg=MyHist2(sw1)
|
|
||||||
// Формируем гистограмму из массива
|
|
||||||
// знаем, что разрядность АЦП 8 бит - 256 значений
|
|
||||||
gg=zeros(1:256)
|
|
||||||
for i=1:size(sw1,1)
|
|
||||||
gg(sw1(i))=gg(sw1(i))+1
|
|
||||||
end
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
function [gg, Fest, Vest]=Estim2(s1)
|
|
||||||
// !!!!!!! Обработка целочисленных данных !!!!!!!!
|
|
||||||
// Размер окна примерно 10 периодов на минимальной частоте
|
|
||||||
wn = int(Fd/F11)*10;
|
|
||||||
// Объём входных данных
|
|
||||||
nmax = size(s1,1);
|
|
||||||
ymin = 256;
|
|
||||||
ymax = 0;
|
|
||||||
ypp = 0;
|
|
||||||
yhist = zeros(1:256);
|
|
||||||
xhist = zeros(1:256);
|
|
||||||
prlag = 8; // Защитный интервал
|
|
||||||
prtmp = 8;
|
|
||||||
Tr2 = 0;
|
|
||||||
xzero = 0;
|
|
||||||
xn1 = 1;
|
|
||||||
xn2 = wn;
|
|
||||||
|
|
||||||
// Первый цикл - инициализация
|
|
||||||
for i=xn1:xn2
|
|
||||||
if ymin>s1(i) then ymin = s1(i) end;
|
|
||||||
if ymax<s1(i) then ymax = s1(i) end;
|
|
||||||
end
|
|
||||||
ypp = ymax-ymin;
|
|
||||||
yhist(ypp) = yhist(ypp)+1;
|
|
||||||
trh = int(ypp/2)+ymin;
|
|
||||||
// Первый перход через 0
|
|
||||||
Tr3 = 0;
|
|
||||||
for i=xn1:xn2
|
|
||||||
// Поиск переходов через 0
|
|
||||||
stmp = s1(i);
|
|
||||||
if prtmp >= prlag then
|
|
||||||
if Tr2 == 1 then
|
|
||||||
if stmp>trh then
|
|
||||||
prtmp = 0;
|
|
||||||
if Tr3 == 1 then
|
|
||||||
xhist(i-xzero)=xhist(i-xzero)+1;
|
|
||||||
end
|
|
||||||
xzero = i;
|
|
||||||
Tr3 = 1;
|
|
||||||
Tr2 = 0;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if stmp<trh then
|
|
||||||
prtmp = 0;
|
|
||||||
Tr2 = 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
prtmp = prtmp+1;
|
|
||||||
end;
|
|
||||||
|
|
||||||
while xn2<nmax
|
|
||||||
xn1 = xn1+1;
|
|
||||||
xn2 = xn2+1;
|
|
||||||
stmp = s1(xn2);
|
|
||||||
Tr1 = 0;
|
|
||||||
if s1(xn2)>ymax then
|
|
||||||
ymax = stmp;
|
|
||||||
elseif s1(xn1-1)==ymax then
|
|
||||||
Tr1=1;
|
|
||||||
end
|
|
||||||
if s1(xn2)<ymin then
|
|
||||||
ymin = stmp;
|
|
||||||
elseif s1(xn1-1)==ymin then
|
|
||||||
Tr1 = 1;
|
|
||||||
end
|
|
||||||
if Tr1==1 then
|
|
||||||
ymin = 256;
|
|
||||||
ymax = 0;
|
|
||||||
for i=xn1:xn2
|
|
||||||
if ymin>s1(i) then ymin = s1(i) end;
|
|
||||||
if ymax<s1(i) then ymax = s1(i) end;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
ypp = ymax-ymin;
|
|
||||||
yhist(ypp) = yhist(ypp)+1;
|
|
||||||
|
|
||||||
// Поиск переходов через 0
|
|
||||||
trh = int(ypp/2)+ymin;
|
|
||||||
if prtmp >= prlag then
|
|
||||||
if Tr2 == 1 then
|
|
||||||
if stmp>trh then
|
|
||||||
prtmp = 0;
|
|
||||||
xhist(xn2-xzero)=xhist(xn2-xzero)+1;
|
|
||||||
xzero = xn2;
|
|
||||||
Tr2 = 0;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if stmp<trh then
|
|
||||||
prtmp = 0;
|
|
||||||
Tr2 = 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
prtmp = prtmp+1;
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
gg = yhist;
|
|
||||||
// Оценка гистограмм
|
|
||||||
x=0;
|
|
||||||
y=0;
|
|
||||||
for i=1:256
|
|
||||||
if yhist(i)>y then
|
|
||||||
y=yhist(i);
|
|
||||||
Vest=i;
|
|
||||||
end
|
|
||||||
if xhist(i)>x then
|
|
||||||
x=xhist(i);
|
|
||||||
Fest=i;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
rand("uniform");
|
|
||||||
rand("seed");
|
|
||||||
//Fi1 = 0.1570796-%pi/1000;
|
|
||||||
//Fi1 = 0
|
|
||||||
//for rkk=1:100
|
|
||||||
// disp(rkk);
|
|
||||||
// Fi1=Fi1+%pi/1000;
|
|
||||||
// s1 = ADC1();
|
|
||||||
// s2 = Filter1(s1);
|
|
||||||
// [Fest, Sum1, s3] = Filter2(s2);
|
|
||||||
// disp((Sum1/2-A1)/A1*100);
|
|
||||||
// disp((Fest-F1)/F1*100);
|
|
||||||
//end
|
|
||||||
|
|
||||||
//s1 = ADC1();
|
|
||||||
//sw1 = s1(1:1024);
|
|
||||||
//gg = MyHist1(sw1);
|
|
||||||
//plot2d(gg);
|
|
||||||
|
|
||||||
fl1(1)="c:\TestADC\10khz_809mv_without_R.txt";
|
|
||||||
fl1(2)="c:\TestADC\10khz_809mv_with_R.txt";
|
|
||||||
|
|
||||||
fl1(3)="c:\TestADC\300khz_201mv_without_R.txt";
|
|
||||||
fl1(4)="c:\TestADC\300khz_201mv_with_R.txt";
|
|
||||||
fl1(5)="c:\TestADC\300khz_802mv_without_R.txt";
|
|
||||||
fl1(6)="c:\TestADC\300khz_802mv_with_R.txt";
|
|
||||||
fl1(7)="c:\TestADC\400khz_201mv_without_R.txt";
|
|
||||||
fl1(8)="c:\TestADC\400khz_201mv_with_R.txt";
|
|
||||||
fl1(9)="c:\TestADC\400khz_802mv_without_R.txt";
|
|
||||||
fl1(10)="c:\TestADC\400khz_802mv_with_R.txt";
|
|
||||||
fl1(11)="c:\TestADC\500khz_201mv_without_R.txt";
|
|
||||||
fl1(12)="c:\TestADC\500khz_201mv_with_R.txt";
|
|
||||||
fl1(13)="c:\TestADC\500khz_802mv_without_R.txt";
|
|
||||||
fl1(14)="c:\TestADC\500khz_802mv_with_R.txt";
|
|
||||||
|
|
||||||
|
|
||||||
uinp(1) = 809;
|
|
||||||
uinp(2) = 809;
|
|
||||||
uinp(3) = 201;
|
|
||||||
uinp(4) = 201;
|
|
||||||
uinp(5) = 802;
|
|
||||||
uinp(6) = 802;
|
|
||||||
uinp(7) = 201;
|
|
||||||
uinp(8) = 201;
|
|
||||||
uinp(9) = 802;
|
|
||||||
uinp(10) = 802;
|
|
||||||
uinp(11) = 201;
|
|
||||||
uinp(12) = 201;
|
|
||||||
uinp(13) = 802;
|
|
||||||
uinp(14) = 802;
|
|
||||||
|
|
||||||
|
|
||||||
for fff=3:14
|
|
||||||
s1 = read(fl1(fff),-1,1);
|
|
||||||
s2 = Mov_avg(s1);
|
|
||||||
h=scf(1);
|
|
||||||
clf;
|
|
||||||
plot2d(s1);
|
|
||||||
[gg, Fest, Vest]=Estim2(s2);
|
|
||||||
Err1 = Vest/255*1000;
|
|
||||||
Err1 = (Err1-uinp(fff))/uinp(fff)*100;
|
|
||||||
disp(fl1(fff), Err1);
|
|
||||||
h=scf(2);
|
|
||||||
clf;
|
|
||||||
plot2d(gg);
|
|
||||||
pause;
|
|
||||||
end
|
|
||||||
|
|
||||||
//sw1 = s1(1:1500);
|
|
||||||
//gg = MyHist2(sw1);
|
|
||||||
//plot2d(s1);
|
|
||||||
|
|
||||||
//s1 = ADC2();
|
|
||||||
@@ -1,339 +0,0 @@
|
|||||||
// Статические переменные
|
|
||||||
|
|
||||||
funcprot(0);
|
|
||||||
|
|
||||||
Fd = 168/9*1e6; // Частота дискретизации
|
|
||||||
NADC = 8; // Количество бит АЦП
|
|
||||||
|
|
||||||
nmem1 = 2^16; // количество ячеек памяти
|
|
||||||
nmem2 = nmem1 -5; // после медианного фильтра
|
|
||||||
|
|
||||||
// определим время выборки
|
|
||||||
Td = 1/Fd;
|
|
||||||
Tm = nmem * Td
|
|
||||||
|
|
||||||
// Медианный фильтр по пяти точкам
|
|
||||||
function s2 = Median5(s1, nn)
|
|
||||||
s2 = zeros(1:nn-5); // Обнуление выходного массива
|
|
||||||
for ii = 1:(nn-5)
|
|
||||||
v1(1)=s1(ii);
|
|
||||||
v1(2)=s1(ii+1);
|
|
||||||
v1(3)=s1(ii+2);
|
|
||||||
v1(4)=s1(ii+3);
|
|
||||||
v1(5)=s1(ii+4);
|
|
||||||
v2 = gsort(v1);
|
|
||||||
s2(ii) = v2(3);
|
|
||||||
end
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
// Скользящее среднее по пяти точкам
|
|
||||||
function s2 = Mov_avg(s1, nn)
|
|
||||||
s2 = zeros(1:nn); // Обнуление выходного массива
|
|
||||||
x1 = 0;
|
|
||||||
for ii = 1:5
|
|
||||||
x1 = x1 + s1(ii);
|
|
||||||
s2(ii) = s1(ii);
|
|
||||||
end
|
|
||||||
for ii = 1:(nn-5)
|
|
||||||
s2(ii) = int(x1/5);
|
|
||||||
x1 = x1 - s1(ii+1);
|
|
||||||
x1 = x1 + s1(ii+2);
|
|
||||||
end
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
// Получение оценки максимума и минимума по гистограмме
|
|
||||||
function [ymin, ymax] = Histo1(s2)
|
|
||||||
// Формируем гистограмму из массива
|
|
||||||
// знаем, что разрядность АЦП 8 бит - 256 значений
|
|
||||||
// тип данных gg unsigned short
|
|
||||||
gg = zeros(1:256); // Обнуление массива
|
|
||||||
for ii = 1:nmem2
|
|
||||||
gg(s2(ii)) = gg(s2(ii)) + 1;
|
|
||||||
end
|
|
||||||
|
|
||||||
// Поиск максимумов в гистограмме
|
|
||||||
|
|
||||||
ymin = 0;
|
|
||||||
ymax = 0;
|
|
||||||
y = 0;
|
|
||||||
for ii = 1:124 // Серединку не обрабатываем
|
|
||||||
if gg(ii) > y then
|
|
||||||
y = gg(ii);
|
|
||||||
ymin = ii;
|
|
||||||
end
|
|
||||||
y = 0;
|
|
||||||
for ii = 130:256
|
|
||||||
if gg(ii) > y then
|
|
||||||
y = g(ii);
|
|
||||||
ymax = ii;
|
|
||||||
end
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
// Последовательный поиск максимумов и минимумов, оценка пиков
|
|
||||||
// и вычисление среднего размаха
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Средний размах + Оценка периода
|
|
||||||
function [Fest, Sum1, s3] = Filter2(s2)
|
|
||||||
nx = int((2/F11)/Td);
|
|
||||||
nx2 = int((1/4/F11)/Td);
|
|
||||||
// disp(nx);
|
|
||||||
// disp(nx2);
|
|
||||||
|
|
||||||
if nx2<2 then
|
|
||||||
nx2 = 2;
|
|
||||||
end
|
|
||||||
s5 = zeros(nn);
|
|
||||||
// for ii=1:nn-nx+1
|
|
||||||
// s4(1:nx) = s2(ii:ii+nx-1)
|
|
||||||
// vmax=max(s4);
|
|
||||||
// vmin=min(s4);
|
|
||||||
// vref=(vmax+vmin)/2;
|
|
||||||
// s5(ii) = s2(ii) - vref;
|
|
||||||
// s3(ii) = vmax-vmin;
|
|
||||||
// end
|
|
||||||
|
|
||||||
for ii=0:int(nn/nx)-1
|
|
||||||
s4(1:nx) = s2(1+ii*nx:ii*nx+nx)
|
|
||||||
vmax=max(s4);
|
|
||||||
vmin=min(s4);
|
|
||||||
vref=(vmax+vmin)/2;
|
|
||||||
s5(1+ii*nx:ii*nx+nx) = s2(1+ii*nx:ii*nx+nx) - vref;
|
|
||||||
s3(1+ii*nx:ii*nx+nx) = vmax-vmin;
|
|
||||||
end
|
|
||||||
|
|
||||||
Sum1=0;
|
|
||||||
for ii=1:nn-nx;
|
|
||||||
Sum1=Sum1+s3(ii);
|
|
||||||
end
|
|
||||||
Sum1=Sum1/(nn-nx);
|
|
||||||
// Считаем периоды и оцениваем частоту
|
|
||||||
nper = 0;
|
|
||||||
jj=1;
|
|
||||||
while s5(jj)>0
|
|
||||||
jj=jj+1
|
|
||||||
end
|
|
||||||
while s5(jj)<0
|
|
||||||
jj=jj+1
|
|
||||||
end
|
|
||||||
kk1 = jj
|
|
||||||
while jj<nn-nx
|
|
||||||
jj = jj + nx2;
|
|
||||||
while (jj<nn-nx) && (s5(jj)<0)
|
|
||||||
jj=jj+1;
|
|
||||||
end
|
|
||||||
nper = nper +1;
|
|
||||||
kk2 = jj;
|
|
||||||
jj = jj + nx2;
|
|
||||||
while (jj<nn-nx) &&(s5(jj)>0)
|
|
||||||
jj=jj+1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Fest = 1/(((kk2-kk1)*Td)/nper);
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function [gg, Fest, Vest]=Estim2(s1)
|
|
||||||
// !!!!!!! Обработка целочисленных данных !!!!!!!!
|
|
||||||
// Размер окна примерно 10 периодов на минимальной частоте
|
|
||||||
wn = int(Fd/F11)*10;
|
|
||||||
// Объём входных данных
|
|
||||||
nmax = size(s1,1);
|
|
||||||
ymin = 256;
|
|
||||||
ymax = 0;
|
|
||||||
ypp = 0;
|
|
||||||
yhist = zeros(1:256);
|
|
||||||
xhist = zeros(1:256);
|
|
||||||
prlag = 8; // Защитный интервал
|
|
||||||
prtmp = 8;
|
|
||||||
Tr2 = 0;
|
|
||||||
xzero = 0;
|
|
||||||
xn1 = 1;
|
|
||||||
xn2 = wn;
|
|
||||||
|
|
||||||
// Первый цикл - инициализация
|
|
||||||
for i=xn1:xn2
|
|
||||||
if ymin>s1(i) then ymin = s1(i) end;
|
|
||||||
if ymax<s1(i) then ymax = s1(i) end;
|
|
||||||
end
|
|
||||||
ypp = ymax-ymin;
|
|
||||||
yhist(ypp) = yhist(ypp)+1;
|
|
||||||
trh = int(ypp/2)+ymin;
|
|
||||||
// Первый перход через 0
|
|
||||||
Tr3 = 0;
|
|
||||||
for i=xn1:xn2
|
|
||||||
// Поиск переходов через 0
|
|
||||||
stmp = s1(i);
|
|
||||||
if prtmp >= prlag then
|
|
||||||
if Tr2 == 1 then
|
|
||||||
if stmp>trh then
|
|
||||||
prtmp = 0;
|
|
||||||
if Tr3 == 1 then
|
|
||||||
xhist(i-xzero)=xhist(i-xzero)+1;
|
|
||||||
end
|
|
||||||
xzero = i;
|
|
||||||
Tr3 = 1;
|
|
||||||
Tr2 = 0;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if stmp<trh then
|
|
||||||
prtmp = 0;
|
|
||||||
Tr2 = 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
prtmp = prtmp+1;
|
|
||||||
end;
|
|
||||||
|
|
||||||
while xn2<nmax
|
|
||||||
xn1 = xn1+1;
|
|
||||||
xn2 = xn2+1;
|
|
||||||
stmp = s1(xn2);
|
|
||||||
Tr1 = 0;
|
|
||||||
if s1(xn2)>ymax then
|
|
||||||
ymax = stmp;
|
|
||||||
elseif s1(xn1-1)==ymax then
|
|
||||||
Tr1=1;
|
|
||||||
end
|
|
||||||
if s1(xn2)<ymin then
|
|
||||||
ymin = stmp;
|
|
||||||
elseif s1(xn1-1)==ymin then
|
|
||||||
Tr1 = 1;
|
|
||||||
end
|
|
||||||
if Tr1==1 then
|
|
||||||
ymin = 256;
|
|
||||||
ymax = 0;
|
|
||||||
for i=xn1:xn2
|
|
||||||
if ymin>s1(i) then ymin = s1(i) end;
|
|
||||||
if ymax<s1(i) then ymax = s1(i) end;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
ypp = ymax-ymin;
|
|
||||||
yhist(ypp) = yhist(ypp)+1;
|
|
||||||
|
|
||||||
// Поиск переходов через 0
|
|
||||||
trh = int(ypp/2)+ymin;
|
|
||||||
if prtmp >= prlag then
|
|
||||||
if Tr2 == 1 then
|
|
||||||
if stmp>trh then
|
|
||||||
prtmp = 0;
|
|
||||||
xhist(xn2-xzero)=xhist(xn2-xzero)+1;
|
|
||||||
xzero = xn2;
|
|
||||||
Tr2 = 0;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if stmp<trh then
|
|
||||||
prtmp = 0;
|
|
||||||
Tr2 = 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
prtmp = prtmp+1;
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
gg = yhist;
|
|
||||||
// Оценка гистограмм
|
|
||||||
x=0;
|
|
||||||
y=0;
|
|
||||||
for i=1:256
|
|
||||||
if yhist(i)>y then
|
|
||||||
y=yhist(i);
|
|
||||||
Vest=i;
|
|
||||||
end
|
|
||||||
if xhist(i)>x then
|
|
||||||
x=xhist(i);
|
|
||||||
Fest=i;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
rand("uniform");
|
|
||||||
rand("seed");
|
|
||||||
//Fi1 = 0.1570796-%pi/1000;
|
|
||||||
//Fi1 = 0
|
|
||||||
//for rkk=1:100
|
|
||||||
// disp(rkk);
|
|
||||||
// Fi1=Fi1+%pi/1000;
|
|
||||||
// s1 = ADC1();
|
|
||||||
// s2 = Filter1(s1);
|
|
||||||
// [Fest, Sum1, s3] = Filter2(s2);
|
|
||||||
// disp((Sum1/2-A1)/A1*100);
|
|
||||||
// disp((Fest-F1)/F1*100);
|
|
||||||
//end
|
|
||||||
|
|
||||||
//s1 = ADC1();
|
|
||||||
//sw1 = s1(1:1024);
|
|
||||||
//gg = MyHist1(sw1);
|
|
||||||
//plot2d(gg);
|
|
||||||
|
|
||||||
fl1(1)="c:\TestADC\10khz_809mv_without_R.txt";
|
|
||||||
fl1(2)="c:\TestADC\10khz_809mv_with_R.txt";
|
|
||||||
|
|
||||||
fl1(3)="c:\TestADC\300khz_201mv_without_R.txt";
|
|
||||||
fl1(4)="c:\TestADC\300khz_201mv_with_R.txt";
|
|
||||||
fl1(5)="c:\TestADC\300khz_802mv_without_R.txt";
|
|
||||||
fl1(6)="c:\TestADC\300khz_802mv_with_R.txt";
|
|
||||||
fl1(7)="c:\TestADC\400khz_201mv_without_R.txt";
|
|
||||||
fl1(8)="c:\TestADC\400khz_201mv_with_R.txt";
|
|
||||||
fl1(9)="c:\TestADC\400khz_802mv_without_R.txt";
|
|
||||||
fl1(10)="c:\TestADC\400khz_802mv_with_R.txt";
|
|
||||||
fl1(11)="c:\TestADC\500khz_201mv_without_R.txt";
|
|
||||||
fl1(12)="c:\TestADC\500khz_201mv_with_R.txt";
|
|
||||||
fl1(13)="c:\TestADC\500khz_802mv_without_R.txt";
|
|
||||||
fl1(14)="c:\TestADC\500khz_802mv_with_R.txt";
|
|
||||||
|
|
||||||
|
|
||||||
uinp(1) = 809;
|
|
||||||
uinp(2) = 809;
|
|
||||||
uinp(3) = 201;
|
|
||||||
uinp(4) = 201;
|
|
||||||
uinp(5) = 802;
|
|
||||||
uinp(6) = 802;
|
|
||||||
uinp(7) = 201;
|
|
||||||
uinp(8) = 201;
|
|
||||||
uinp(9) = 802;
|
|
||||||
uinp(10) = 802;
|
|
||||||
uinp(11) = 201;
|
|
||||||
uinp(12) = 201;
|
|
||||||
uinp(13) = 802;
|
|
||||||
uinp(14) = 802;
|
|
||||||
|
|
||||||
|
|
||||||
for fff=3:14
|
|
||||||
s1 = read(fl1(fff),-1,1);
|
|
||||||
s2 = Mov_avg(s1);
|
|
||||||
h=scf(1);
|
|
||||||
clf;
|
|
||||||
plot2d(s2);
|
|
||||||
[gg, Fest, Vest]=Estim2(s2);
|
|
||||||
Err1 = Vest/255*1000;
|
|
||||||
Err1 = (Err1-uinp(fff))/uinp(fff)*100;
|
|
||||||
disp(fl1(fff), Err1);
|
|
||||||
h=scf(2);
|
|
||||||
clf;
|
|
||||||
plot2d(gg);
|
|
||||||
pause;
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//sw1 = s1(1:1500);
|
|
||||||
//gg = MyHist2(sw1);
|
|
||||||
//plot2d(s1);
|
|
||||||
|
|
||||||
//s1 = ADC2();
|
|
||||||
BIN
Binary file not shown.
Reference in New Issue
Block a user