这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【肌电传感器(OYMotion)试用】---心肌电传感器初步使用

共1条 1/1 1 跳转至

【肌电传感器(OYMotion)试用】---心肌电传感器初步使用

高工
2025-12-14 23:30:53     打赏
硬件准备

        arduino r4 wifi

        dfrobot sen0240心肌电传感器

资料准备

        通过查询资料,发现心肌电传感器母版上传出的数据线为模拟信号,供电可以使用3.3V~5V 直流供电,因此设计就简单了,直接在arduino板卡上选择一个模拟口便可。

        出于接线便捷性的考虑,我选择了跟地和供电最接近的A0口,以方便调试。

软件安装

        直接去arduino上下载arduino IDE的安装文件,下载位置如下:DOWNLOAD

        下载好后点击安装,安装好后启动软件,设置好库的存储位置

1.jpg

库安装

        设置好库的存储位置后,需要去github上下载到心肌电传感器所需的滤波器实现库,库的链接如下:EMG_Filter

        下载好后,将库文件解压至arduino设置好后的路径下,具体存储方法如下:

1.jpg

校准软件编写

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include "EMGFilters.h"
#define SensorInputPin A0   //输入脚

EMGFilters myFilter;

SAMPLE_FREQUENCY sampleRate = SAMPLE_FREQ_500HZ;
NOTCH_FREQUENCY humFreq = NOTCH_FREQ_50HZ;

void setup()
{
  myFilter.init(sampleRate, humFreq, true, true, true);
  Serial.begin(115200);
}

void loop()
{
  int data = analogRead(SensorInputPin);
  int dataAfterFilter = myFilter.update(data);  // 库中提供的滤波处理
  int envelope = sq(dataAfterFilter);   //对滤波后的信号作平方处理,用于对幅度进行增强

  Serial.println(envelope);
  delayMicroseconds(500); // 500us后再去读取下一次,也就是说,采样率在2K
}

      由于每个人的心肌电都不一样,而且即使是同一个人,也没法保证每次佩戴都是同一位置,此时需要在佩戴后重新做一次校准,或许后面看频域数据后,可能不需要再去做校准了,毕竟看的不是幅度,而是每个操作时的频谱变化趋势,有可能不同的动作,所获得的频谱图是相对固定的(频域幅度可能会有变化,但各频率之间比例变化不大)。

获取标定数据

        软件编写好后,烧录至arduino r4 wifi板卡上,再佩戴好心肌电传感器,看打印数据,当人不动时,打印数据在100以内,说明心肌电传感器已经佩戴好,若超过这个值,说明没贴对位置。

        确认佩戴好后,反复握拳,看能拿到的最大值,由于打印太多,因此我仅关注了最高位,最高位的值为7,因为是三位数,因此我就直接当作700来选取。

效果测试软件编写

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include "EMGFilters.h"
#define SensorInputPin A0   //输入脚

unsigned long threshold = 700;  // 我这次实验佩戴时,检测到最大的值为700左右
unsigned long EMG_num = 0;      // 触发次数

EMGFilters myFilter;

SAMPLE_FREQUENCY sampleRate = SAMPLE_FREQ_500HZ;
NOTCH_FREQUENCY humFreq = NOTCH_FREQ_50HZ;

void setup()
{
  myFilter.init(sampleRate, humFreq, true, true, true);
  Serial.begin(115200);
}

void loop()
{
  int data = analogRead(SensorInputPin);
  int dataAfterFilter = myFilter.update(data);  // 库中提供的滤波处理
  int envelope = sq(dataAfterFilter);   //对滤波后的信号作平方处理,用于对幅度进行增强
  envelope = (envelope > threshold) ? envelope : 0;    // 如果幅度超过了一定值,则认为是有动作

  if (getEMGCount(envelope))
  {
    EMG_num++;
    Serial.print("EMG_num: ");
    Serial.println(EMG_num);
  }
  delayMicroseconds(500); // 500us后再去读取下一次,也就是说,采样率在2K
}

// 如果信号持续200ms超过了门限值,则认为运动了一次
int getEMGCount(int gforce_envelope)
{
  static long integralData = 0;
  static long integralDataEve = 0;
  static bool remainFlag = false;
  static unsigned long timeMillis = 0;
  static unsigned long timeBeginzero = 0;
  static long fistNum = 0;
  static int  TimeStandard = 200;

  integralDataEve = integralData;
  integralData += gforce_envelope;

  if ((integralDataEve == integralData) && (integralDataEve != 0))
  {
     timeMillis = millis();
     if (remainFlag)
     {
       timeBeginzero = timeMillis;
       remainFlag = false;
       return 0;
    }
    
    if ((timeMillis - timeBeginzero) > TimeStandard)
    {
      integralDataEve = integralData = 0;
      return 1;
    }
    return 0;
  }
  else
  {
    remainFlag = true;
    return 0;
  }
}

实验结果

        由于仅仅是对数据进行了幅度上的拉大处理,未对数据进行更加复杂的运算,如采集后使用短时傅里叶去看频谱,看看不同操作时的频率信息等,导致不少动作都能触发判定为操作了,在我此次实验中,就遇到了两种操作会触发操作了,一个是手握拳,另一个是大拇指和食指之间的滑动操作。

EMG_num: 1
EMG_num: 2
EMG_num: 3
EMG_num: 4
EMG_num: 5
EMG_num: 6
EMG_num: 7
EMG_num: 8
EMG_num: 9
EMG_num: 10
EMG_num: 11
EMG_num: 12

下一步计划

      既然按照官方的demo并不能很好的区分手部操作,那就尝试换一些方法看看,计划看看快速傅里叶变化后能不能明显区分不同动作。




关键词: 肌电     传感器     OYMotion     试用    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]