肌电传感器 SEN0240

传感器采购自 DFRobot,基本上是即买即用。

Arduino 驱动代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
* Copyright 2017, OYMotion Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
*/

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

#include "EMGFilters.h"

#define TIMING_DEBUG 1

#define SensorInputPin A0 // input pin number

EMGFilters myFilter;
// discrete filters must works with fixed sample frequence
// our emg filter only support "SAMPLE_FREQ_500HZ" or "SAMPLE_FREQ_1000HZ"
// other sampleRate inputs will bypass all the EMG_FILTER
int sampleRate = SAMPLE_FREQ_1000HZ;
// For countries where power transmission is at 50 Hz
// For countries where power transmission is at 60 Hz, need to change to
// "NOTCH_FREQ_60HZ"
// our emg filter only support 50Hz and 60Hz input
// other inputs will bypass all the EMG_FILTER
int humFreq = NOTCH_FREQ_50HZ;

// Calibration:
// put on the sensors, and release your muscles;
// wait a few seconds, and select the max value as the threshold;
// any value under threshold will be set to zero
static int Threshold = 0;

unsigned long timeStamp;
unsigned long timeBudget;

void setup() {
/* add setup code here */
myFilter.init(sampleRate, humFreq, true, true, true);

// open serial
Serial.begin(115200);

// setup for time cost measure
// using micros()
timeBudget = 1e6 / sampleRate;
// micros will overflow and auto return to zero every 70 minutes
}

void loop() {
/* add main program code here */
// In order to make sure the ADC sample frequence on arduino,
// the time cost should be measured each loop
/*------------start here-------------------*/
timeStamp = micros();

int Value = analogRead(SensorInputPin);

// filter processing
int DataAfterFilter = myFilter.update(Value);

int envlope = sq(DataAfterFilter);
// any value under threshold will be set to zero
envlope = (envlope > Threshold) ? envlope : 0;

timeStamp = micros() - timeStamp;
if (TIMING_DEBUG) {
// Serial.print("Read Data: "); Serial.println(Value);
// Serial.print("Filtered Data: ");Serial.println(DataAfterFilter);
Serial.print("Squared Data: ");
Serial.println(envlope);
// Serial.print("Filters cost time: "); Serial.println(timeStamp);
// the filter cost average around 520 us
}

/*------------end here---------------------*/
// if less than timeBudget, then you still have (timeBudget - timeStamp) to
// do your work
delayMicroseconds(500);
// if more than timeBudget, the sample rate need to reduce to
// SAMPLE_FREQ_500HZ
}

驱动代码需要用到 EMGFilters 库,下载地址

推荐每次使用时都校准一次,因为即使是同一个人,不同位置的肌电信号也是不同的。

校准流程:

  • 将样例代码中的 Threshold 变量改成 0,即:static int Threshold = 0;
  • 上传样例代码至 Arduino 控制板中,然后打开 Arduino IDE 的串口监视器,观察打印的数值;
  • 放松手臂上的肌肉,观察串口打印的数值。身心平静,让肌肉放松一会,观察串口监视器打印的最大数值,并记录之。如果数值太大,比如 1000 以上,可尝试微调干电极的放置位置;
  • 将样例代码中的 Threshold 变量改成刚才记录的最大数值,重新上传样例代码至 Arduino 主控板。

需要注意的是:

  • 使用时必须要把笔记本电脑电源断开才能出正确的波形,不然会有噪音;
  • 传感器必须「紧贴」皮肤(肌肉处),否则会出现 0-40000 的规律读值。这是 Arduino 模拟输入引脚的信号。就算不接入传感器,引脚也会有读值。而驱动代码会将该读值放大。

肌电传感器 SEN0240
https://wonderhoi.com/2023/08/14/肌电传感器-SEN0240/
作者
wonderhoi
发布于
2023年8月14日
许可协议