Browse Source

update

master
zhaohe 1 year ago
parent
commit
45322969bc
  1. 6
      CMakeLists.txt.user
  2. 3
      README.md
  3. 16
      mainwindow.cpp
  4. 358
      mainwindow.ui
  5. 2
      src/electrocardiograph_tester.hpp
  6. 55
      src/filter_algo_mgr.cpp
  7. 12
      src/filter_algo_mgr.hpp
  8. 79
      src/filter_group/algo/iflytop_simple_filter.cpp
  9. 26
      src/filter_group/algo/iflytop_simple_filter.h
  10. 36
      src/filter_group/if/if_filter_group.hpp
  11. 101
      src/filter_group/iir_filter_group.cpp
  12. 60
      src/filter_group/iir_filter_group.hpp

6
CMakeLists.txt.user

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 5.0.2, 2024-05-03T22:00:42. -->
<!-- Written by QtCreator 5.0.2, 2024-05-11T19:35:35. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>
@ -94,7 +94,7 @@
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.12.12 MinGW 64-bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.12.12 MinGW 64-bit</value>
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.51212.win64_mingw73_kit</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">4</value>
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
@ -347,7 +347,7 @@
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">D:/workspace/nordic_wp/build-electrocardiograph_upper-Desktop_Qt_5_12_12_MinGW_64_bit-Release</value>
<value type="QString" key="RunConfiguration.WorkingDirectory.default">D:/workspace/nordic_wp/electrocardiograph_upper/build</value>
</valuemap>
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
</valuemap>

3
README.md

@ -27,6 +27,9 @@ V4:
地址,数值
毫伏变换公式:
+VREF/(2^23– 1)
–VREF/(2^23– 1)
```
```

16
mainwindow.cpp

@ -553,9 +553,9 @@ void MainWindow::on_stopCapture_clicked() {
void MainWindow::on_startRealtimeReport_clicked() {
instructionPreviewClear();
try {
wp2d->show();
ElectrocardiographTester::ins()->startRealtimeReport();
ishow("start realtime report success");
wp2d->show();
} catch (zexception &exception) {
processException(exception);
}
@ -566,7 +566,7 @@ void MainWindow::on_stopRealtimeReport_clicked() {
try {
ElectrocardiographTester::ins()->stopRealtimeReport();
ishow("stop realtime report success");
wp2d->hide();
// wp2d->hide();
} catch (zexception &exception) {
processException(exception);
}
@ -718,6 +718,12 @@ void MainWindow::on_FilterUpdateParameter_clicked() {
FilterAlgoMgr::ins()->setWindowsSize(ui->FilterCommon_windowsSize->text().toInt());
FilterAlgoMgr::ins()->setWindowsType(ui->FilterCommon_WindowsType->currentText().toStdString());
FilterAlgoMgr::ins()->SmoothingFilter_setEnable(ui->SmoothingFilter_Enable->isChecked());
FilterAlgoMgr::ins()->SmoothingFilter_setWindowsSize(ui->SmoothingFilter_WindowsSize->text().toInt());
FilterAlgoMgr::ins()->BaselineDriftRemoval_setEnable(ui->BaselineDriftRemoval_Enable->isChecked());
FilterAlgoMgr::ins()->BaselineDriftRemoval_setWindowsSize(ui->BaselineDriftRemoval_WindowsSize->text().toInt());
FilterAlgoMgr::ins()->updateParameter();
on_buttonTabWidget_currentChanged(0);
@ -741,6 +747,12 @@ void MainWindow::on_buttonTabWidget_currentChanged(int index) {
ui->FilterCommon_windowsSize->setText(QString::number(FilterAlgoMgr::ins()->getWindowsSize()));
ui->FilterCommon_WindowsType->setCurrentText(QString::fromStdString(FilterAlgoMgr::ins()->getWindowType()));
ui->SmoothingFilter_Enable->setChecked(FilterAlgoMgr::ins()->SmoothingFilter_getEnable());
ui->SmoothingFilter_WindowsSize->setText(QString::number(FilterAlgoMgr::ins()->SmoothingFilter_getWindowsSize()));
ui->BaselineDriftRemoval_Enable->setChecked(FilterAlgoMgr::ins()->BaselineDriftRemoval_getEnable());
ui->BaselineDriftRemoval_WindowsSize->setText(QString::number(FilterAlgoMgr::ins()->BaselineDriftRemoval_getWindowsSize()));
}
void MainWindow::on_TestCmd_writeSubICAllReg_clicked() {

358
mainwindow.ui

@ -1819,14 +1819,59 @@ p, li { white-space: pre-wrap; }
<string>滤波器配置</string>
</property>
<layout class="QGridLayout" name="gridLayout_12">
<item row="0" column="0">
<widget class="QGroupBox" name="LPFilterBox">
<item row="2" column="0" colspan="3">
<widget class="QGroupBox" name="groupBox_6">
<property name="minimumSize">
<size>
<width>0</width>
<height>150</height>
</size>
</property>
<property name="title">
<string>低通滤波器</string>
<string>通用参数</string>
</property>
<layout class="QGridLayout" name="gridLayout_8">
<layout class="QGridLayout" name="gridLayout_11">
<item row="0" column="1">
<widget class="QLineEdit" name="FilterCommon_SampleTimeMs">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_12">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>windowsSize</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="FilterCommon_windowsSize">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer_7">
<spacer name="verticalSpacer_10">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
@ -1838,8 +1883,59 @@ p, li { white-space: pre-wrap; }
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>数据采样周期(ms)</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<widget class="QLabel" name="label_15">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>windowsType</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="FilterCommon_WindowsType"/>
</item>
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="HPFilter_Box">
<property name="title">
<string>高通滤波器</string>
</property>
<layout class="QGridLayout" name="gridLayout_9">
<item row="3" column="0">
<spacer name="verticalSpacer_8">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
@ -1852,7 +1948,7 @@ p, li { white-space: pre-wrap; }
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="LPFilter_CutoffFreqHz">
<widget class="QLineEdit" name="HPFilter_CutoffFreqHz">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
@ -1865,7 +1961,7 @@ p, li { white-space: pre-wrap; }
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="LPFilter_Enable">
<widget class="QCheckBox" name="HPFilter_Enable">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>1</horstretch>
@ -1878,7 +1974,7 @@ p, li { white-space: pre-wrap; }
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
@ -1891,6 +1987,51 @@ p, li { white-space: pre-wrap; }
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="HPFilter_Order">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>阶级</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QGroupBox" name="LPFilterBox">
<property name="title">
<string>低通滤波器</string>
</property>
<layout class="QGridLayout" name="gridLayout_8">
<item row="0" column="1">
<widget class="QCheckBox" name="LPFilter_Enable">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="LPFilter_Order">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -1900,6 +2041,19 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>截至频率(HZ)</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="sizePolicy">
@ -1913,6 +2067,45 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="LPFilter_CutoffFreqHz">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>使能</string>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer_7">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
@ -2036,14 +2229,14 @@ p, li { white-space: pre-wrap; }
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QGroupBox" name="HPFilter_Box">
<item row="1" column="0">
<widget class="QGroupBox" name="LPFilterBox_2">
<property name="title">
<string>高通滤波器</string>
<string>滑动均值滤波器</string>
</property>
<layout class="QGridLayout" name="gridLayout_9">
<item row="3" column="0">
<spacer name="verticalSpacer_8">
<layout class="QGridLayout" name="gridLayout_13">
<item row="2" column="0">
<spacer name="verticalSpacer_13">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
@ -2055,21 +2248,8 @@ p, li { white-space: pre-wrap; }
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>截至频率(HZ)</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="HPFilter_CutoffFreqHz">
<widget class="QLineEdit" name="SmoothingFilter_WindowsSize">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
@ -2081,21 +2261,8 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="HPFilter_Enable">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<widget class="QLabel" name="label_17">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
@ -2107,98 +2274,82 @@ p, li { white-space: pre-wrap; }
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="HPFilter_Order">
<item row="1" column="0">
<widget class="QLabel" name="label_16">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>windowSize</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_6">
<item row="0" column="1">
<widget class="QCheckBox" name="SmoothingFilter_Enable">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>阶级</string>
<string/>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QGroupBox" name="groupBox_6">
<property name="minimumSize">
<size>
<width>0</width>
<height>150</height>
</size>
</property>
<item row="1" column="1">
<widget class="QGroupBox" name="LPFilterBox_3">
<property name="title">
<string>通用参数</string>
<string>中值去基线</string>
</property>
<layout class="QGridLayout" name="gridLayout_11">
<item row="0" column="1">
<widget class="QLineEdit" name="FilterCommon_SampleTimeMs">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<layout class="QGridLayout" name="gridLayout_14">
<item row="2" column="0">
<spacer name="verticalSpacer_14">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="text">
<string/>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</widget>
</spacer>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_12">
<item row="1" column="1">
<widget class="QLineEdit" name="BaselineDriftRemoval_WindowsSize">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>windowsSize</string>
<string/>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="FilterCommon_windowsSize">
<item row="0" column="0">
<widget class="QLabel" name="label_18">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
<string>使能</string>
</property>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer_10">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_10">
<item row="1" column="0">
<widget class="QLabel" name="label_19">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
@ -2206,26 +2357,23 @@ p, li { white-space: pre-wrap; }
</sizepolicy>
</property>
<property name="text">
<string>数据采样周期(ms)</string>
<string>windowSize</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_15">
<item row="0" column="1">
<widget class="QCheckBox" name="BaselineDriftRemoval_Enable">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>windowsType</string>
<string/>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="FilterCommon_WindowsType"/>
</item>
</layout>
</widget>
</item>
@ -2237,7 +2385,13 @@ p, li { white-space: pre-wrap; }
<property name="minimumSize">
<size>
<width>0</width>
<height>50</height>
<height>30</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="text">

2
src/electrocardiograph_tester.hpp

@ -110,7 +110,7 @@ class ElectrocardiographTester {
void set_ecg_in_test_mode(int32_t testmode);
void set_ecg_report_data_in_raw_mode(int32_t rawmode);
void testCmdStartCapture();
void testCmdStartCapture();
void testCmdStopCapture();
uint8_t ecg_subic_read_reg(uint8_t addr);
void ecg_subic_write_reg(uint8_t addr, uint8_t val);

55
src/filter_algo_mgr.cpp

@ -162,9 +162,7 @@ string FilterAlgoMgr::getWindowType() {
}
return "";
}
vector<string> FilterAlgoMgr::windowsTypes() {
return IF_FilterGroup::windowsTypes();
}
vector<string> FilterAlgoMgr::windowsTypes() { return IF_FilterGroup::windowsTypes(); }
void FilterAlgoMgr::LPFilter_setOrder(int order) { //
// filter.LPFilter_setOrder(order);
@ -178,7 +176,6 @@ int FilterAlgoMgr::LPFilter_getOrder() { //
return it.second->LPFilter_getOrder();
}
return 0;
}
void FilterAlgoMgr::HPFilter_setOrder(int order) { //
// filter.HPFilter_setOrder(order);
@ -192,7 +189,6 @@ int FilterAlgoMgr::HPFilter_getOrder() { //
return it.second->HPFilter_getOrder();
}
return 0;
}
void FilterAlgoMgr::NOTCHFilter_setOrder(int order) { //
// filter.NOTCHFilter_setOrder(order);
@ -206,7 +202,6 @@ int FilterAlgoMgr::NOTCHFilter_getOrder() { //
return it.second->NOTCHFilter_getOrder();
}
return 0;
}
void FilterAlgoMgr::updateParameter() { //
@ -215,3 +210,51 @@ void FilterAlgoMgr::updateParameter() { //
it.second->updateParameter();
}
}
void FilterAlgoMgr::SmoothingFilter_setWindowsSize(int windows_size) {
for (auto& it : m_filter_map) {
it.second->SmoothingFilter_setWindowsSize(windows_size);
}
}
void FilterAlgoMgr::SmoothingFilter_setEnable(bool enable) {
for (auto& it : m_filter_map) {
it.second->SmoothingFilter_setEnable(enable);
}
}
int FilterAlgoMgr::SmoothingFilter_getWindowsSize() {
for (auto& it : m_filter_map) {
return it.second->SmoothingFilter_getWindowsSize();
}
return 0;
}
bool FilterAlgoMgr::SmoothingFilter_getEnable() {
for (auto& it : m_filter_map) {
return it.second->SmoothingFilter_getEnable();
}
return 0;
}
void FilterAlgoMgr::BaselineDriftRemoval_setWindowsSize(int windows_size) {
for (auto& it : m_filter_map) {
it.second->BaselineDriftRemoval_setWindowsSize(windows_size);
}
}
void FilterAlgoMgr::BaselineDriftRemoval_setEnable(bool enable) {
for (auto& it : m_filter_map) {
it.second->BaselineDriftRemoval_setEnable(enable);
}
}
int FilterAlgoMgr::BaselineDriftRemoval_getWindowsSize() {
for (auto& it : m_filter_map) {
return it.second->BaselineDriftRemoval_getWindowsSize();
}
return 0;
}
bool FilterAlgoMgr::BaselineDriftRemoval_getEnable() {
for (auto& it : m_filter_map) {
return it.second->BaselineDriftRemoval_getEnable();
}
return 0;
}

12
src/filter_algo_mgr.hpp

@ -78,6 +78,18 @@ class FilterAlgoMgr {
float NOTCHFilter_getCenterFreqHz();
float NOTCHFilter_getNotchWidthHz();
int NOTCHFilter_getOrder();
void SmoothingFilter_setWindowsSize(int windows_size);
void SmoothingFilter_setEnable(bool enable);
int SmoothingFilter_getWindowsSize();
bool SmoothingFilter_getEnable();
void BaselineDriftRemoval_setWindowsSize(int windows_size);
void BaselineDriftRemoval_setEnable(bool enable);
int BaselineDriftRemoval_getWindowsSize();
bool BaselineDriftRemoval_getEnable();
};
} // namespace iflytop

79
src/filter_group/algo/iflytop_simple_filter.cpp

@ -3,8 +3,8 @@
#include <math.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#include "logger.hpp"
@ -25,7 +25,7 @@ void LPFilter_Init(LPFilter_t *filter, float cutoffFreqHz, float sampleTimeS, bo
filter->enable = enable;
ZLOGI("FILTER","LPFilter_Init: cutoffFreqHz=%f, sampleTimeS=%f, enable=%d", cutoffFreqHz, sampleTimeS, enable);
ZLOGI("FILTER", "LPFilter_Init: cutoffFreqHz=%f, sampleTimeS=%f, enable=%d", cutoffFreqHz, sampleTimeS, enable);
}
float LPFilter_Update(LPFilter_t *filter, float v_in) {
@ -131,4 +131,77 @@ float NOTCHFilter_Update(NOTCHFilter_t *filter, float vin) {
filter->vout[0] = (filter->alpha * filter->vin[0] + 2.0 * (filter->alpha - 8.0) * filter->vin[1] + filter->alpha * filter->vin[2] - (2.0f * (filter->alpha - 8.0) * filter->vout[1] + (filter->alpha - filter->beta) * filter->vout[2])) / (filter->alpha + filter->beta);
return (filter->vout[0]);
}
}
void SmoothingFilter_Init(SmoothingFilter_t *filter, int windows_size, bool enable) {
if (windows_size > 1000) {
windows_size = 1000;
}
filter->windows_size = windows_size;
filter->datanum = 0;
filter->sum = 0;
filter->datanum = 0;
for (int i = 0; i < windows_size; i++) {
filter->datawindows[i] = 0;
}
filter->data_offset = 0;
filter->enable = enable;
}
float SmoothingFilter_Update(SmoothingFilter_t *filter, float vin) {
if (!filter->enable) return vin;
filter->sum -= filter->datawindows[filter->data_offset];
filter->datawindows[filter->data_offset] = vin;
filter->sum += filter->datawindows[filter->data_offset];
filter->data_offset = (filter->data_offset + 1) % filter->windows_size;
filter->datanum++;
if (filter->datanum > filter->windows_size) {
filter->datanum = filter->windows_size;
}
return filter->sum / filter->datanum;
}
void BaselineDriftRemoval_Init(BaselineDriftRemoval_t *filter, int windows_size, bool enable) {
if (windows_size > MEDIAN_FILTER_SIZE) {
windows_size = MEDIAN_FILTER_SIZE;
}
filter->windows_size = windows_size;
filter->datanum = 0;
filter->enable = enable;
for (int i = 0; i < windows_size; i++) {
filter->fifo[i] = 0;
}
}
float BaselineDriftRemoval_Update(BaselineDriftRemoval_t *filter, float vin) {
if (!filter->enable) return vin;
memmove(filter->fifo, filter->fifo + 1, (filter->windows_size - 1) * sizeof(float));
filter->fifo[filter->windows_size - 1] = vin;
filter->datanum++;
if (filter->datanum > filter->windows_size) {
filter->datanum = filter->windows_size;
}
if (filter->datanum < filter->windows_size) {
return 0;
}
// 求中值
memcpy(filter->processcache, filter->fifo, filter->windows_size * sizeof(float));
for (int i = 0; i < filter->windows_size; i++) {
for (int j = i + 1; j < filter->windows_size; j++) {
if (filter->processcache[i] > filter->processcache[j]) {
float temp = filter->processcache[i];
filter->processcache[i] = filter->processcache[j];
filter->processcache[j] = temp;
}
}
}
float mid = filter->processcache[filter->windows_size / 2];
float min_data_in_fifo = filter->fifo[filter->windows_size / 2];
return min_data_in_fifo - mid;
}

26
src/filter_group/algo/iflytop_simple_filter.h

@ -6,7 +6,6 @@
// extern "C" {
// #endif
/********************************************************************************************************
* LOW PASS FILTER
********************************************************************************************************/
@ -65,6 +64,31 @@ typedef struct {
void NOTCHFilter_Init(NOTCHFilter_t *filter, float centerFreqHz, float notchWidthHz, float sampleTimeS, bool enable);
float NOTCHFilter_Update(NOTCHFilter_t *filter, float vin);
typedef struct {
float datawindows[30];
int windows_size;
int datanum;
int data_offset;
float sum;
bool enable;
} SmoothingFilter_t;
void SmoothingFilter_Init(SmoothingFilter_t *filter, int windows_size, bool enable);
float SmoothingFilter_Update(SmoothingFilter_t *filter, float vin);
#define MEDIAN_FILTER_SIZE 1000
typedef struct {
float fifo[MEDIAN_FILTER_SIZE];
float processcache[MEDIAN_FILTER_SIZE];
bool enable;
int windows_size;
int datanum;
} BaselineDriftRemoval_t;
void BaselineDriftRemoval_Init(BaselineDriftRemoval_t *filter, int windows_size, bool enable);
float BaselineDriftRemoval_Update(BaselineDriftRemoval_t *filter, float vin);
// #ifdef __cplusplus
// }
// #endif

36
src/filter_group/if/if_filter_group.hpp

@ -17,7 +17,9 @@ using namespace std;
class IF_FilterGroup {
protected:
float _sampleTimeMs;
float _sampleTimeMs;
int _windows_size = 500;
string _windowType = "hamming";
bool _LPFilter_Enable = false;
float _LPFilter_CutoffFreqHz = 0;
@ -32,15 +34,19 @@ class IF_FilterGroup {
float _NOTCHFilter_NotchWidthHz = 0;
float _NOTCHFilter_Order = 1;
int _windows_size = 1000;
bool _SmoothingFilter_Enable = false;
int _SmoothingFilter_WindowsSize = 100;
int _BaselineDriftRemoval_WindowsSize = 500;
bool _BaselineDriftRemoval_Enable = false;
// BaselineDriftRemoval_Enable
const string kwindow_type_hamming = "hamming";
const string kwindow_type_triangle = "triangle";
const string kwindow_type_hanning = "hanning";
const string kwindow_type_blackman = "blackman";
string _windowType = "hamming";
public:
virtual ~IF_FilterGroup() {}
@ -96,5 +102,25 @@ class IF_FilterGroup {
virtual float NOTCHFilter_getCenterFreqHz() { return _NOTCHFilter_CenterFreqHz; }
virtual float NOTCHFilter_getNotchWidthHz() { return _NOTCHFilter_NotchWidthHz; }
virtual int NOTCHFilter_getOrder() { return _NOTCHFilter_Order; }
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
// SmoothingFilter_t
virtual void SmoothingFilter_setWindowsSize(int windows_size) { _SmoothingFilter_WindowsSize = windows_size; }
virtual void SmoothingFilter_setEnable(bool enable) { _SmoothingFilter_Enable = enable; }
virtual int SmoothingFilter_getWindowsSize() { return _SmoothingFilter_WindowsSize; }
virtual bool SmoothingFilter_getEnable() { return _SmoothingFilter_Enable; }
/***********************************************************************************************************************
* 线 *
***********************************************************************************************************************/
// BaselineDriftRemoval_t
virtual void BaselineDriftRemoval_setWindowsSize(int windows_size) { _BaselineDriftRemoval_WindowsSize = windows_size; }
virtual void BaselineDriftRemoval_setEnable(bool enable) { _BaselineDriftRemoval_Enable = enable; }
virtual int BaselineDriftRemoval_getWindowsSize() { return _BaselineDriftRemoval_WindowsSize; }
virtual bool BaselineDriftRemoval_getEnable() { return _BaselineDriftRemoval_Enable; }
};
} // namespace iflytop
} // namespace iflytop

101
src/filter_group/iir_filter_group.cpp

@ -1,12 +1,16 @@
#include "iir_filter_group.hpp"
#include "libzqt\zexception.hpp"
#include "ify_hrs_protocol\heart_rate_sensor_protocol.h"
#include <mutex>
#include "ify_hrs_protocol\heart_rate_sensor_protocol.h"
#include "libzqt\zexception.hpp"
using namespace iflytop;
void IIRFilterGroup::initialize() {}
void IIRFilterGroup::initialize() {
//
updateParameter();
}
int32_t IIRFilterGroup::processData(int32_t data) { //
std::lock_guard<std::recursive_mutex> lock(lock_);
@ -24,6 +28,9 @@ int32_t IIRFilterGroup::processData(int32_t data) { //
v0 = NOTCHFilter_Update(&notchfilter[i], v0);
}
v0 = BaselineDriftRemoval_Update(&baselineDriftRemoval, v0);
v0 = SmoothingFilter_Update(&smoothingFilter, v0);
return (int32_t)v0;
}
@ -31,89 +38,19 @@ void IIRFilterGroup::updateParameter() {
std::lock_guard<std::recursive_mutex> lock(lock_);
for (int i = 0; i < FILTER_MAX_ORDER; i++) {
LPFilter_Init(&lpfilter[i], LPFilter_cutoffFreqHz, sampleTimeMs / 1000.0, lpfilter_enable);
LPFilter_Init(&lpfilter[i], _LPFilter_CutoffFreqHz, _sampleTimeMs / 1000.0, _LPFilter_Enable);
}
for (int i = 0; i < FILTER_MAX_ORDER; i++) {
HPFilter_Init(&hpfilter[i], HPFilter_cutoffFreqHz, sampleTimeMs / 1000.0, hpfilter_enable);
HPFilter_Init(&hpfilter[i], _HPFilter_CutoffFreqHz, _sampleTimeMs / 1000.0, _HPFilter_Enable);
}
for (int i = 0; i < FILTER_MAX_ORDER; i++) {
NOTCHFilter_Init(&notchfilter[i], NOTCHFilter_centerFreqHz, NOTCHFilter_notchWidthHz, sampleTimeMs / 1000.0, notchfilter_enable);
NOTCHFilter_Init(&notchfilter[i], _NOTCHFilter_CenterFreqHz, _NOTCHFilter_NotchWidthHz, _sampleTimeMs / 1000.0, _NOTCHFilter_Enable);
}
// SmoothingFilter_Init(&smoothingFilter, _windows_size);
__lpfilter_order = _LPFilter_Order;
__hpfilter_order = _HPFilter_Order;
__notchfilter_order = _NOTCHFilter_Order;
__lpfilter_order = lpfilter_order;
__hpfilter_order = hpfilter_order;
__notchfilter_order = notchfilter_order;
}
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void IIRFilterGroup::setSampleTimeMs(float sampleTimeMs) {
if (sampleTimeMs < 0.4) {
throw zexception(kifyhrs_ecode_upper_exception, "sampleTimeMs must be greater than 0.4ms");
}
this->sampleTimeMs = sampleTimeMs;
}
float IIRFilterGroup::getSampleTimeMs() { return sampleTimeMs; }
void IIRFilterGroup::LPFilter_setOrder(int order) {
if (order < 1) {
order = 1;
}
if (order > FILTER_MAX_ORDER) {
order = FILTER_MAX_ORDER;
}
lpfilter_order = order;
}
int IIRFilterGroup::LPFilter_getOrder() { return lpfilter_order; }
void IIRFilterGroup::HPFilter_setOrder(int order) {
if (order < 1) {
order = 1;
}
if (order > FILTER_MAX_ORDER) {
order = FILTER_MAX_ORDER;
}
hpfilter_order = order;
}
int IIRFilterGroup::HPFilter_getOrder() { return hpfilter_order; }
void IIRFilterGroup::NOTCHFilter_setOrder(int order) {
if (order < 1) {
order = 1;
}
if (order > FILTER_MAX_ORDER) {
order = FILTER_MAX_ORDER;
}
notchfilter_order = order;
SmoothingFilter_Init(&smoothingFilter, _SmoothingFilter_WindowsSize, _SmoothingFilter_Enable);
BaselineDriftRemoval_Init(&baselineDriftRemoval, _BaselineDriftRemoval_WindowsSize, _BaselineDriftRemoval_Enable);
}
int IIRFilterGroup::NOTCHFilter_getOrder() { return notchfilter_order; }
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void IIRFilterGroup::LPFilter_setEnable(bool enable) { lpfilter_enable = enable; }
void IIRFilterGroup::LPFilter_setCutoffFreqHz(float cutoffFreqHz) { LPFilter_cutoffFreqHz = cutoffFreqHz; }
bool IIRFilterGroup::LPFilter_getEnable() { return lpfilter_enable; }
float IIRFilterGroup::LPFilter_getCutoffFreqHz() { return LPFilter_cutoffFreqHz; }
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void IIRFilterGroup::HPFilter_setEnable(bool enable) { hpfilter_enable = enable; }
void IIRFilterGroup::HPFilter_setCutoffFreqHz(float cutoffFreqHz) { HPFilter_cutoffFreqHz = cutoffFreqHz; }
bool IIRFilterGroup::HPFilter_getEnable() { return hpfilter_enable; }
float IIRFilterGroup::HPFilter_getCutoffFreqHz() { return HPFilter_cutoffFreqHz; }
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
void IIRFilterGroup::NOTCHFilter_setEnable(bool enable) { notchfilter_enable = enable; }
void IIRFilterGroup::NOTCHFilter_setCenterFreqHz(float centerFreqHz) { NOTCHFilter_centerFreqHz = centerFreqHz; }
void IIRFilterGroup::NOTCHFilter_setNotchWidthHz(float notchWidthHz) { NOTCHFilter_notchWidthHz = notchWidthHz; }
bool IIRFilterGroup::NOTCHFilter_getEnable() { return notchfilter_enable; }
float IIRFilterGroup::NOTCHFilter_getCenterFreqHz() { return NOTCHFilter_centerFreqHz; }
float IIRFilterGroup::NOTCHFilter_getNotchWidthHz() { return NOTCHFilter_notchWidthHz; }

60
src/filter_group/iir_filter_group.hpp

@ -25,6 +25,9 @@ class IIRFilterGroup : public IF_FilterGroup {
HPFilter_t hpfilter[FILTER_MAX_ORDER] = {0};
NOTCHFilter_t notchfilter[FILTER_MAX_ORDER] = {0};
SmoothingFilter_t smoothingFilter;
BaselineDriftRemoval_t baselineDriftRemoval;
int __lpfilter_order = 1;
int __hpfilter_order = 1;
int __notchfilter_order = 1;
@ -33,21 +36,6 @@ class IIRFilterGroup : public IF_FilterGroup {
* *
***********************************************************************************************************************/
bool lpfilter_enable = false;
bool hpfilter_enable = false;
bool notchfilter_enable = false;
int lpfilter_order = 1;
int hpfilter_order = 1;
int notchfilter_order = 1;
float LPFilter_cutoffFreqHz = 0;
float HPFilter_cutoffFreqHz = 0;
float NOTCHFilter_centerFreqHz = 0;
float NOTCHFilter_notchWidthHz = 0;
float sampleTimeMs = 2; // 1ms
std::recursive_mutex lock_;
public:
@ -56,47 +44,5 @@ class IIRFilterGroup : public IF_FilterGroup {
virtual int32_t processData(int32_t data) override;
virtual void updateParameter() override;
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
virtual void setSampleTimeMs(float sampleTimeMs) override;
virtual float getSampleTimeMs() override;
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
virtual void LPFilter_setEnable(bool enable) override;
virtual void LPFilter_setCutoffFreqHz(float cutoffFreqHz) override;
virtual void LPFilter_setOrder(int order) override;
virtual bool LPFilter_getEnable() override;
virtual float LPFilter_getCutoffFreqHz() override;
virtual int LPFilter_getOrder() override;
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
virtual void HPFilter_setEnable(bool enable) override;
virtual void HPFilter_setCutoffFreqHz(float cutoffFreqHz) override;
virtual void HPFilter_setOrder(int order) override;
virtual bool HPFilter_getEnable() override;
virtual float HPFilter_getCutoffFreqHz() override;
virtual int HPFilter_getOrder() override;
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
virtual void NOTCHFilter_setEnable(bool enable) override;
virtual void NOTCHFilter_setCenterFreqHz(float centerFreqHz) override;
virtual void NOTCHFilter_setNotchWidthHz(float notchWidthHz) override;
virtual void NOTCHFilter_setOrder(int order) override;
virtual bool NOTCHFilter_getEnable() override;
virtual float NOTCHFilter_getCenterFreqHz() override;
virtual float NOTCHFilter_getNotchWidthHz() override;
virtual int NOTCHFilter_getOrder() override;
};
} // namespace iflytop
Loading…
Cancel
Save