Signal smoothing or simplification

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 :grin: 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

:roll_eyes: 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 :smiley:

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.