Hi everyone,
This might be a long shot, but I can't seem to be able to simplify a signal collected from an EMG sensor.
I have tried most of the arduino signal filters available online : https://github.com/sebnil/Moving-Ava...duino-Library-
http://www.schwietering.com/jayduino/filtuino/
but they don't really give me the signal that I need to control a set of leds.
What I'm trying to do is to compare logged data to real time data and control a strip of neopixel leds. However, since the signal is so jagged by its nature, I'm having a hard time finding matches when I compare it. I'm attaching an image of the signal, in yellow is the actual plot of the real time data with me mildly contracting my muscle, and the larger circle is a full contraction. In green is what I would like to get.

I'm attaching the full code, and posting here the two functions that read and compare and the filtering that I do know.
Your help would be tremendously appreciated since finals are around the corner!
Smoothing
void smoothing(){
val1 = analogRead(EMG_PIN1);
val2 = analogRead(EMG_PIN2);
val3 = analogRead(EMG_PIN3);
outputEMG1 = round (movingAvarageFilter.process(val1)); // here we call the fir routine with the input. The value 'fir' spits out is stored in the output variable.
outputEMG2 = round (movingAvarageFilter.process(val2)); // here we call the fir routine with the input. The value 'fir' spits out is stored in the output variable.
outputEMG3 = round (movingAvarageFilter.process(val3)); // here we call the fir routine with the input. The value 'fir' spits out is stored in the output variable.
delay(5); // delay in between reads for stability
}
int emgTreshold = 10;
void itterate2(){
Serial.print("outputEMG1 :");
Serial.println(outputEMG1);
Serial.print("EMG1[counterEMG]");
Serial.println(EMG1[counterEMG]);
if (fabs(EMG1[counterEMG]-outputEMG1)< emgTreshold ){
EMGroundGrader++;
}
else{
}
if (counterEMG==lengthRead){
counterEMG=0;
}
else{
float temp = lengthRead / 36 ;
EMGarrBlock = (int)temp;
if (EMGmainArr == false){
EMGupperLimit = EMGarrBlock;
EMGmainArr = true;
}
// Serial.print("EMGroundGrader? :");
// Serial.println(EMGroundGrader);
if( counterEMG == EMGupperLimit){
if(EMGroundGrader>=((float)EMGarrBlock)/2){
EMGlowerLimit+=EMGarrBlock;
EMGupperLimit+=EMGarrBlock;
EMGoverallProgCounter++;
EMGpixelOn(1);
EMGroundGrader=0;
}
else {
counterEMG = 0;
EMGroundGrader=0;
EMGlowerLimit=0;
EMGupperLimit=arrBlock;
EMGoverallProgCounter=0;
EMGoverallProgress= 0;
EMGpixelOn(0);
}
if(EMGoverallProgCounter==6){
overallProgress(1);
}
}
}
counterEMG++;
}
I am not understanding your terminology but after reading it the gist of seem to be (without having specifically stated it) is that you want to AMPLIFY the signal. I really don't know what you mean by SIMPLIFY. There are basically only two terms that apply here, neither of which you have used. The first is AMPLIFICATION. This is what you need to do before applying the second term which is
SIGNAL CONDITIONING. After doing that , you could go on and apply an FFT , but let's keep it SIMPLE for the moment. You are
wasting your time trying to read the signal with the ADC on the arduino , unless you use the
analogReference(INTERNAL);
statement which will immediately limit your analog range to 0 to 1.1 volts, which it would seem is more appropriate for your signal.
Without any amplitude data for your signal (while you image looks nice, it has no amplitude data) there is no way to know what you are receiving in terms of analog values. Your code has Serial prints but you did not attach a serial monitor terminal capture file showing what you received. If you do that , we will have a better idea of what we are dealing with. It would seem that you need an analog input amplifier (op amp). We can talk about that , when we know more about the level of your signal.
Thank you for your reply raschemmel, you are absolutely right about me using the wrong terminology. I frankly don't know what is the appropriate name for what I need that is why tried to draw it in the image so someone would guess
what I'm asking.
With that said, I'm using Teensy 3.1 which is a 32bit arm processor and it seems to be doing very well. at collecting the data.
I'm attaching a log file that mainly has data with the arm at rest.
I can add one with me doing full contractions if you think it will help.
GMOTION3.csv (13.7 KB)
Have you checked your data if there is an interference between channels? Simple ground one input at the time and see a data log, if there is "0" leaking in the neighboring channel.
Looking at the diagram, my understanding that green line represents an envelope of the signal. You can't get envelope using LPF, as the nature of your input a noise similar, or AC signal. First of all, you need subtract DC offset from your data ( offset is a value w/o a signal), than you may run averaging or similar LPF filtering using squared up values ( x^2).
can add one with me doing full contractions if you think it will help.
Add one with you doing Marine DIAMOND PUSHUPS. XD
Since I don't get internet sarcasm I'm going to go that means yes.
millis EMG1
29412 475
29490 483
29622 481
29692 459
34979 452
35100 463
35221 472
35343 463
35464 458
35585 426
35707 420
35828 412
35949 413
36073 457
36195 470
36317 474
36471 471
36603 500
36724 484
36846 481
36967 501
37089 475
37210 468
37332 463
37453 460
37574 475
37696 478
37817 497
37942 502
38064 492
38185 484
38307 447
38471 449
38592 423
38714 432
38835 467
38957 470
39078 480
39200 473
39321 480
39443 473
39564 469
39689 477
39811 476
39932 476
40054 470
40175 461
40297 449
40471 440
40592 436
40714 439
40835 444
40957 455
41078 457
41200 459
41321 458
41446 460
41567 465
41689 469
41810 462
41932 457
42053 469
42175 468
42296 465
42491 468
42613 466
42734 478
42856 466
42977 463
43099 461
43220 462
43375 468
43497 461
43618 462
43751 468
43872 467
43994 468
44115 474
44237 484
44358 510
44573 484
44694 469
44816 470
44937 467
45059 466
45184 465
45305 446
45426 438
45548 439
45669 434
45791 477
45912 478
46034 472
46155 474
46277 474
46409 467
46697 430
46818 457
46940 460
47064 452
47186 476
47307 462
47429 443
47550 443
47672 449
47793 452
47915 465
48036 471
48158 472
48279 481
48401 453
48522 454
48696 449
48820 439
48942 447
49063 448
49185 459
49306 470
49428 469
49549 460
49671 461
49792 463
49914 458
50035 456
50157 464
50278 463
50399 459
50521 463
50718 463
50839 472
50961 453
51082 461
51204 463
51325 472
51447 469
51568 463
51690 472
51811 472
51933 466
52054 460
52175 472
52297 463
52440 458
52562 459
52776 480
52897 478
53031 489
53152 497
53285 497
53406 485
53527 474
53649 460
53770 448
53892 464
54013 453
54135 454
54259 472
54381 472
54502 460
54624 465
54848 471
54970 473
55091 480
55212 467
55334 458
55455 463
55577 458
55698 452
55820 449
55941 461
56066 487
56187 492
56319 485
56441 495
56562 473
56684 457
56918 469
57040 485
57161 493
57282 476
57404 476
57525 478
57647 472
57768 470
57890 472
58014 461
58419 440
58841 430
59246 429
59659 433
60070 449
60472 474
60721 480
60842 497
60964 469
61085 465
61207 473
61328 514
61450 505
61574 491
61696 498
61817 423
61939 416
62060 415
62181 423
62303 474
62424 484
62546 488
62801 492
62922 467
63044 474
63165 475
63286 475
63430 478
63551 477
63673 490
63794 477
63915 471
64037 449
64169 462
64291 479
64410 480
64542 462
64663 455
64857 448
64978 453
65100 450
65225 458
65346 453
65467 455
65589 461
65710 465
65832 463
65953 459
66075 464
66196 467
66317 461
66439 460
66560 465
66682 466
67167 457
67292 458
67413 461
67535 455
67656 457
67778 468
67899 469
68021 456
68142 459
68263 470
68395 466
68517 446
68638 444
68760 463
68881 467
69003 461
69170 461
69291 471
69413 481
69534 470
69656 462
69777 467
69898 469
70020 461
70141 460
70263 465
70384 465
70505 459
70627 464
70748 468
70883 464
71004 451
71188 460
71310 472
71431 481
71552 461
71674 457
71795 462
71916 466
72038 462
72159 459
72280 470
72401 467
72523 460
72713 471
72834 472
72956 473
73077 466
73281 471
73403 464
73524 454
73645 459
73767 468
73899 466
74020 460
Magician:
Have you checked your data if there is an interference between channels? Simple ground one input at the time and see a data log, if there is "0" leaking in the neighboring channel.
Looking at the diagram, my understanding that green line represents an envelope of the signal. You can't get envelope using LPF, as the nature of your input a noise similar, or AC signal. First of all, you need subtract DC offset from your data ( offset is a value w/o a signal), than you may run averaging or similar LPF filtering using squared up values ( x^2).
Magician I don't seem to have any leaking 0s if you look at the csv attached in the earlier post. You can see the values.
Thank you for pointing out the right terminology of what I'm trying to do.
Since I don't get internet sarcasm I'm going to go that means yes.
That was indeed an attempt at humor.
If you know what a diamond pushup is then you would get it.
If you could do one diamond pushup (correctly) then you would really get it.
This internet tutorial diamond pushups was obviosly not written by a US MARINE.
The Marine diamond pushup centers the diamond directly below your FACE and you touch your nose to the floor (or as least get within 1" of the floor) DIRECTLY IN THE CENTER OF THE DIAMOND. One of these is equal to at least five or six of the easy diamond pushups seen on the internet where the diamond is centered directly below the solar plexus of the chest. I saw a guy who do the easy diamond pushups try to do the Marine diamond pushups and he stopped after 3 or 4. Note: the spine must be kept straight as a board ( no sticking your butt up in the air to make it easy)
Magician I don't seem to have any leaking 0s if you look at the csv attached in the earlier post.
You don't understand. I have seen repeating data in channels, like 468, 468, 487 - there is no way you can be sure, that data from channel 1 is not jumping to channel 2.
That sounds like something intended to make me fall on my face 
Magician:
Magician I don't seem to have any leaking 0s if you look at the csv attached in the earlier post.
You don't understand. I have seen repeating data in channels, like 468, 468, 487 - there is no way you can be sure, that data from channel 1 is not jumping to channel 2.
Ok, I see let me double check. I forgot to mention, that from the 3 EMG shields I'm currently only using 1 to test the data and the other are just floating.