Go Down

Topic: Detection of a vibration peak (Read 163 times) previous topic - next topic

berlad180

Hi everyone,
I have been developing using arduino for about a year now, in several different niches.
I am having a real hard time on trying to detect a duble tap on a surface.
The system made of: arduino uno, mems piezoelectric horizontal beam, parller with 1 mgh rsistor conected to the anlog read pin a0.
 
Can someone please offer me a good algorithm ti isolte the knock?
The main problem is that the first knock leavs noise for about 10ms during the time i need to measure the second tap..
Hance i cant really isolate the first and second tap.

I would be very grateful for any enlightenment in knocking/ tapping detection algorithm.
Thank u very much for any comment and good luck all! 

allanhurst

#1
Dec 07, 2016, 12:16 am Last Edit: Dec 07, 2016, 12:17 am by allanhurst
It sounds as if your transducer it not suitable for the job.

But..., could you post an oscilloscope picture of the signal you see?


regards

Allan

berlad180

Hi thank you very much for replying.
The piezo beam I am using is - https://www.sparkfun.com/datasheets/Sensors/Flex/MiniSense_100.pdf

I have add 2 scope pic of the signal peak hope u can see it.
And after countless attempts now I got to this code:



void setup() {
  Serial.begin(9600);

}

void loop() {
  vibe = analogRead(knockSensor);

  if (vibe > 12 && vibe < 30) {
    xEvg();
    getData();

    for (int k = 7, zeroSum = 0 ; k < 13; k++) {
      zeroSum += amp[k];
    }
    if (zeroSum <= 2)
      zeroCheck = 1;
    else
      zeroCheck = 0;

    if (((evgAmp[1] - evgAmp[2]) > 10) && (amp[6] == 0 && amp[7] == 0) && (evgAmp[0] < 22) && (zeroCheck == 1)) { // checking trash hold conditions
      zeroCheck = 0;
      knock = 1;
    }

    else
      knock = 0;


    if (knock == 0) {
      for (int k = 0 ; k < 8; k++)
        evgAmp[k] = 0;

      for (int k = 0 ; k < 16; k++)
        amp[k] = 0;

    }

    if (knock == 1) {
      Serial.print("detection: ");
      Serial.println(knock , DEC);
      Serial.println("the knock Data: 8bit ,16 bit ");
      for (int k = 0 ; k < 8; k++) {
        Serial.print(evgAmp[k], DEC);
        Serial.print(", ");
      }
      Serial.print("\n");
      for (int k = 0 ; k < 16; k++) {
        Serial.print(amp[k], DEC);
        Serial.print(", ");
      }
      Serial.print("\n\n");
      delay(70);
      Amplitude = (xEvg1 + xEvg2) / 2 - (xEvg3 + xEvg4) / 2;
      knock = 0;
      for (int k = 0 ; k < 8; k++)
        evgAmp[k] = 0;
      for (int k = 0 ; k < 16; k++)
        amp[k] = 0;

      signalMax = 0;
      signalMin = 254;
      ampCount = 0;
    }

    delay(1);
  }

}


void xEvg() {

  for (int k = 0 ; k < 4; k++)
    xEvg1 += amp[k];

  xEvg1 /= 4 ;

  for (int k = 4 ; k < 8; k++)
    xEvg2 += amp[k];

  xEvg2 /= 4;

  for (int k = 8 ; k < 12; k++)
    xEvg3 += amp[k];

  xEvg3 /= 4;

  for (int k = 12 ; k < 16; k++)
    xEvg4 += amp[k];

  xEvg4 /= 4;

  Evg[0] = xEvg1;
  Evg[1] = xEvg2;
  Evg[2] = xEvg3;
  Evg[3] = xEvg4;
  return;
}

void getData() {
  for (int k = 0, ampCount = 0 ; k < 16; k++) { //measure the max and min signal in one knocking time

    for (int i = millis(), j = millis() ; i < (j + tapTime); i = millis()) { //measure the max and min signal in one knocking time
      vibe = analogRead(knockSensor);
      if (vibe > signalMax) {
        signalMax = vibe;
      }
      else if (vibe < signalMin) {
        signalMin = vibe;
      }
    }
    amp[ampCount] = signalMax;
    signalMax = 0;
    signalMin = 254;
    ampCount++;
  }

  for (int k = 0, i = 0 ; k < 8; k++, i += 2) {

    evgAmp[k] = (amp + amp[i + 1]) / 2;
  }

  return;
}


I will be glad to get any comments for improving the algorithm so I can really Isolate the knock peak from others noises.

jremington

#3
Dec 07, 2016, 07:46 pm Last Edit: Dec 07, 2016, 07:47 pm by jremington
Why reinvent the wheel? This is a very common problem that has been solved many times.

Google "peak detection algorithms" for general approaches.

Please use code tags when posting.

berlad180

Hi jremington,
I have tried to look up for peak detection algorithm most of the results were just pseudo code or code in languages I am not familier with.( not C);
It would be great if you could send me a link or an example for a good peak detection you may know.
thanks,
Berry

jremington

#5
Dec 08, 2016, 06:49 pm Last Edit: Dec 08, 2016, 06:52 pm by jremington
What is wrong with pseudo code?  It is easy to write C based on it (much easier than spending a year flailing around by yourself).

Try the smoothed z-score algorithm or one of the simpler algorithms in that thread, and let us know how you get on.

Wawa

#6
Today at 05:12 am Last Edit: Today at 05:15 am by Wawa
The sensor (with weight) seems to be made for low frequencies (<75Hz).

Is this for human knocking.
A common bare 1" piezo disc works fine for that.
Leo..

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy