
如果 loop 只运行一个模拟引脚,并且使用一个过滤器,即可正常输出( 0~500 ),但是创建数组储存多个过滤后的模拟引脚数值就有问题了,输出异常(1000~20000)
#include "EMGFilters.h" const int SensorInputPin[] = {A0, A1, A2, A3, A4, A5}; 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() { Serial.println(square(myFilter.update(analogRead(SensorInputPin[0])))); } long unsigned int square(unsigned int x) { return (x * x); } 
只修改 loop
void loop() { int envelops[12] = {0}; for (int i = 0; i < 2; i++) { for (int x = 0; x < 6; x++) { envelops[i * 6 + x] = square(myFilter.update(analogRead(SensorInputPin[x]))); } delayMicroseconds(50); Serial.println(envelops[i * 6 + 1]); } } 
我搞不懂了,逐次打印看看变量名
void loop() { int envelops[12]; for (int i = 0; i < 2; i++) { int ii = 0; for (int x = 0; x < 6; x++) { Serial.printf("i:%d x:%d\n", i, x); envelops[((i * 6) + x)] = square(myFilter.update(analogRead(SensorInputPin[x]))); Serial.printf("Output:%d index: %d\n", envelops[((i * 6) + x)], ((i * 6) + x)); } ii++; delay(1000); } } long unsigned int square(unsigned int x) { return (x*x); } 
搞不明白,咋输出上万的值了呢?
再看看正常输出的
void loop() { int x1= square(myFilter.update(analogRead(SensorInputPin[0]))); Serial.printf("analogRead:%d\n",analogRead(SensorInputPin[0])); Serial.printf("output:%d\n",x1); delay(1000); } 
这很正常啊,怎么一用 for 循环函数就有问题了
然后尝试
void loop() { int x1= square(myFilter.update(analogRead(SensorInputPin[0]))); int x2=square(myFilter.update(analogRead(SensorInputPin[1]))); int x3=square(myFilter.update(analogRead(SensorInputPin[2]))); int x4=square(myFilter.update(analogRead(SensorInputPin[3]))); int x5=square(myFilter.update(analogRead(SensorInputPin[4]))); int x6= square(myFilter.update(analogRead(SensorInputPin[5]))); Serial.printf("analogRead:%d\n",analogRead(SensorInputPin[0])); Serial.printf("output:%d\n",x1); delay(1000); } 发现原本输出动辄几万的,已经下降到一千左右了,但仍然是异常输出

过滤器就是一个函数计算输出的,怎么调用的时候出现问题了?
loop 仅用一条指令Serial.println(square(myFilter.update(analogRead(每个模拟引脚输入)))),正常输出 0~500 的值,如果用多个变量或 for 啥,就输出上万的值了。。。我尝试创建多个过滤器,给每个输入单独用Filter1,Filter2等等,问题依旧。。。
过滤器代码链接:https://github.com/oymotion/EMGFilters/blob/master/EMGFilters.cpp
咋解决啊
1 Eiden 2022 年 4 月 13 日 每一路输入都需要新建一个过滤器对象吧 |
2 ALLROBOT OP @Eiden #1 我曾经尝试这么做,EMGFilters myFilters[6]; 先初始化然后在 loop 使用 envelops[i * 6 + x] = square(myFilters[x].update(analogRead(SensorInputPin[x])));,问题依旧 |
4 villivateur 2022 年 4 月 13 日 具体是什么单片机啊?如果有 FPU 的话尝试把 FPU 关掉试试看 |
5 ALLROBOT OP @villivateur #4 用的 Seeeduino XIAO 微控制器 XIAO 一般说明: https://wiki.seeedstudio.com/Seeeduino-XIAO/ 微控制器 XIAO 说明手册: https://files.seeedstudio.com/wiki/Seeeduino-XIAO/res/ATSAMD21G18A-MU-Datasheet.pdf 我是硬件半吊子的,所以才学 Arduino,图它 Arduino 原型设计快的,我不知道 XIAO 的 MCU 是否有 FPU |
6 ALLROBOT OP @Eiden #1 @villivateur #4 发现在 loop 函数使用 1,2 个传感器的过滤器,是正常输出的,但增加过滤器时就异常输出了 是单片机自己的问题吗?实在解决不了,推荐啥 Arduino 采集 MCU ?在 XIAO 浪费了太多时间 |
7 DataSheep 2022 年 4 月 14 日 via iPhone 跟单片机应该没关系,每个滤波器新建一个实例对象是应该的,另外这个滤波器库既然有采样频率参数你应该需要控制采样间隔,好像没看到有写,注意滤波计算也是需要毫秒级时间的,根据运算能力差异非常大。根据你的描述很可能是这个原因。 btw ,这个东西你好像捣鼓蛮久了 |
8 ALLROBOT OP @DataSheep #7 不好意思,嵌入式很少涉及(没学过数电模电),每月只有几天的空闲时间来研究 Arduino 的,没能折腾出什么结果 https://gist.github.com/allrobot/1d105671a5186adb792bfbc5d8bd5030 我曾经为每个输出添加 500 微秒、1 毫秒、或 5 毫秒来控制采样频率,但均为输出异常 上面的黄似乎是随机的,如果 index 为 4 个,即输出 4 个滤波计算的值,第 2 ,4 个输出异常; index 为 3 个的话,第 3 个输出异常; index 再次为 4 个,第 3 个和第 4 个模拟引脚输出异常。。。 |
9 sujin190 2022 年 4 月 14 日 不滤波也异常的那那就是读取问题?似乎看不出来是滤波异常还是读取异常啊 |
11 DataSheep 2022 年 4 月 14 日 via iPhone @ALLROBOT 你没理解我意思,你既然选择的频率是 500 ,那么采样间隔需要控制在 2 毫秒。 也就是 update 间隔需要严格控制在 2 毫秒,而且一般也是用定时器中断来控制,不过 arduino 一般不用中断。所以如果你要用我 delay 来控制采样间隔的话,需要把函数运行时间也加进去,那么延时时间会在 0-2 毫秒之间,具体需要计算一下你的函数运行时间是多久。 |
12 darkengine 2022 年 4 月 14 日 应该把 square(myFilter.update(analogRead(SensorInputPin[x]))) 这里每个调用的中间结果打出来,才知道是哪个函数调用出的问题吧。 |
13 ALLROBOT OP @DataSheep #11 这样的话,也只是在 loop 函数加 long time=millis();在执行过滤器语句的下面( loop 函数末尾)增加 while((millis()-time)<2){delayMicroseconds(100);} 对于异常输出没有什么太大改善 就这样暂时将就吧,肌肉运动能看到一点起伏 |
14 DataSheep 2022 年 4 月 14 日 via iPhone @ALLROBOT 如果还有问题,确认 ad 读取没问题的话滤波函数可以自己写的。 这东西看你踩的坑太多了,不如上个树莓派用 python 早搞定了 |
15 ALLROBOT OP @darkengine #12 7 小时前用 analogread 函数读数已经检测出问题所在,是 ADC 读数不一致产生了问题 只要连续读取 A0 ,A1 模拟引脚没问题,连续读取 A0,A1,A2,A3,A4 就产生了问题,不知道为啥 |
16 ALLROBOT OP @darkengine #12 噢,好吧,收回之前的话,这是中午的测试图,现在的测试图如下: Serial.printf("%d %d %d %d %d %d\n",analogRead(A0),analogRead(A1),analogRead(A2),analogRead(A3),analogRead(A4),analogRead(A5)); 模拟输出太莫名其妙了。。。中午的电路接线结构没啥变动,到了现在输出乱七八糟了 @DataSheep #14 也许你说得对。。。。 |