Friday, November 7, 2014

How to Avoid False Positives with a High Sensitivity Piezo Vibration Sensor

Thanks for all the interest and comments in my previous blog on the High Sensitivity Vibration Sensor. In this previous project I described how to use a piezo element, an op amp and comparator to create a high sensitivity vibration sensor. Based on the great level of interest in this project I have created an advanced vibration sensor that uses the same design and builds upon it. One of the challenges with vibration sensors is screening out spurious events such as bumps that can lead to false positives. In this project the sketch running on the Arduino Uno watches for vibration events but only triggers if it sees 5 vibration events within a 5 second period. So if it gets 3 events and then none for a while it will forget those 3 events. Only if it gets 5 or more within 5 seconds will the alarm trigger. This effectively screens out spurious bumps and fires on persistent vibration events. This can be useful for a variety of applications where was is sought is the ability to detect vibration rather than a single bump. The values for the number of events (5 in my sketch) and period of time (5 seconds) are configurable by changing the values at the top of the sketch for your project.

You can find the sketch I used on the Arduino Uno below:

#define VIBRATION_SENSOR_DIGITAL_INPUT_PIN 10
#define VIBRATION_SENSOR_DIGITAL_OUTPUT_PIN 8

#define VIBRATION_SAMPLE_ARRAY_SIZE 100

// if we 5 or more vibration events over a five second period then a vibration alarm is triggered
#define VIBRATION_EVENTS_ALARM_THRESHOLD_COUNT 5
#define VIBRATION_EVENTS_ALARM_THRESHOLD_PERIOD_MILLIS 5000

long vibrationEvents[VIBRATION_SAMPLE_ARRAY_SIZE];
int vibrationEventIndex;

void setup(){
  Serial.begin(19200);
  
  pinMode(VIBRATION_SENSOR_DIGITAL_INPUT_PIN, INPUT);
  pinMode(VIBRATION_SENSOR_DIGITAL_OUTPUT_PIN, OUTPUT);
  
  vibrationEventIndex = 0;
  clearVibrationEvents();
}

void loop(){
  if(digitalRead(VIBRATION_SENSOR_DIGITAL_INPUT_PIN) == HIGH){
    long currentMillis = millis();
    addVibrationSample(currentMillis);
    if(isVibrationAlarmTiggered()){
      triggerAlarm();
      Serial.println(String(millis()) + "\t ALARM");
    }
    delay(100); // wait for current vibration shock to subside
  }
}

void addVibrationSample(long vibrationMillis){
   vibrationEvents[vibrationEventIndex++] = vibrationMillis;
   if(vibrationEventIndex >= VIBRATION_SAMPLE_ARRAY_SIZE){
     vibrationEventIndex = 0; // wrap vibration sample index around when we get to end of sample array
   }
}

boolean triggerAlarm(){
  digitalWrite(VIBRATION_SENSOR_DIGITAL_OUTPUT_PIN, HIGH);
  delay(1000);
  digitalWrite(VIBRATION_SENSOR_DIGITAL_OUTPUT_PIN, LOW);
  clearVibrationEvents();
}

void clearVibrationEvents(){
  for(int i = 0; i < VIBRATION_SAMPLE_ARRAY_SIZE ; ++i){
    vibrationEvents[i] = -1;
  }
}

boolean isVibrationAlarmTiggered(){
  long thresholdMillis = millis() - VIBRATION_EVENTS_ALARM_THRESHOLD_PERIOD_MILLIS;
  if(thresholdMillis < 0) thresholdMillis = 0;
  int numVibrationsSinceThreshold = 0;
  for(int i = 0; i < VIBRATION_SAMPLE_ARRAY_SIZE ; ++i){
    if(vibrationEvents[i] >= thresholdMillis){
      ++numVibrationsSinceThreshold;
    }
  }
  
  Serial.println(String(millis()) + "\t# events: " + String(numVibrationsSinceThreshold));
  boolean alarmTriggered = false;
  if(numVibrationsSinceThreshold >= VIBRATION_EVENTS_ALARM_THRESHOLD_COUNT){
    alarmTriggered = true;
  }
  
  return alarmTriggered;
}



Below is an example of the output on the Arduino IDE console when the Arduino Uno is running off a USB cable:

9018 # events: 1
9703 # events: 2
10330 # events: 3
10935 # events: 4
11697 # events: 5
12698  ALARM
14902 # events: 1
15398 # events: 2
15925 # events: 3
27161 # events: 1

If you found this interesting you may also want to have a look at how to build a High Sensitivity Sound Level Detector. You may also want to look at my subsequent blog on how to use these in an open door or tailgate down sensor which also uses a Reed switch.

If you are interested in how this type of sensor can be integrated into a broader solution that includes notification of detected vibration on a users Android phone see Detect Intrusion with Passive Infrared, Sound, or Vibration

9 comments:

  1. Hello my i have your email account. I have a project that i am working on and need some help. i cant explain it fully over here so i wanted to send an email to you about it. Thank you in advance!

    ReplyDelete
  2. Dear David,
    I need your help (urgent) to figure out a customised version of your code. I am working on vehicle security alarm project where vibration sensor will trigger both the siren and start a dialer (phone) which will place call to vehicle owner then vehicle owner will press buttons to cutt off engine etc. For automatic dialer I m using this youtube tutorial https://www.youtube.com/watch?v=6fwM_oTjqG0 and for vibration sensor & alarm I am using your one. But facing difficulty in combining both the codes. When I combine them, it gives error like "clearVibrationEvents' was not declared in this scope", etc.

    I am sharing the code here for auto dialer:
    //Constants That Won't Change
    const int call = 11; //Call Button Output
    const int back = 10; //Back Button Output
    const int keypad7 = 9; //No:7 Button Output
    const int alarm_active_led = 8; //Alarm Triggered LED Indicator
    const int power_led = 7; //Power OK LED Indicator
    const int trigger_input = 6; //Alarm Trigger Input
    int repeat =0;

    //Variables That Will Change
    int trigger_state = 0; //trigger_state = Trigger Input (pin7)

    //Setup Routine Runs Once When Reset Is Pressed
    void setup() {

    //Initialize The Digital Pins As Inputs/ Outputs
    pinMode(call, OUTPUT); //Define "Call" pinMode as Output
    pinMode(back, OUTPUT); //Define "Back" pinMode as Output
    pinMode(keypad7, OUTPUT); //Define "keypad7" pinMode as Output
    pinMode(alarm_active_led, OUTPUT); //Define "Alarm LED" pinMode as Output
    pinMode(power_led, OUTPUT); //Define "Power LED" pinMode as Output
    pinMode(trigger_input, INPUT); //Define "Cancel" pinMode as Input
    }

    //Loop Runs Indefinately
    void loop() {
    trigger_state = digitalRead(trigger_input);//Read Trigger Input State

    digitalWrite(power_led, HIGH); //Turn Power LED On
    digitalWrite(alarm_active_led, LOW); //Turn Alarm LED Off

    if (trigger_state == HIGH) { //If Trigger Input HIGH,
    //Run Sequence Below
    digitalWrite(alarm_active_led, HIGH);

    digitalWrite(back, HIGH); //Press Back Button
    delay(100); //Wait 100mS
    digitalWrite(back, LOW); //Depress Back Button

    delay(100); //Wait 100mS
    digitalWrite(back, HIGH); //Press Back Button
    delay(100); //Wait 100mS
    digitalWrite(back, LOW); //Depress Back Button

    delay(100); //Wait 100mS
    digitalWrite(keypad7, HIGH); //Press keypad7 Button
    delay(100); //Wait 100mS
    digitalWrite(keypad7, LOW); //Depress keypad Button

    delay(100); //Wait 100mS
    digitalWrite(call, HIGH); //Press call Button
    delay(100); //Wait 100mS
    digitalWrite(call, LOW); //Depress call Button

    delay(20000); //Wait 20S
    digitalWrite(back, HIGH); //Press back Button
    delay(200); //Wait 100mS
    digitalWrite(back, LOW); //Depress back Button

    digitalWrite(alarm_active_led, HIGH); //Flash Alarm LED
    delay(100); //Flash Alarm LED
    digitalWrite(alarm_active_led, LOW); //Flash Alarm LED
    delay(100); //Flash Alarm LED

    while(trigger_state == HIGH){ //If Trigger Input HIGH
    trigger_state = digitalRead(trigger_input);//Read Trigger Input State
    //Loop Sequence Below
    digitalWrite(alarm_active_led, HIGH); //Flash Alarm LED
    delay(100); //Flash Alarm LED
    digitalWrite(alarm_active_led, LOW); //Flash Alarm LED
    delay(100); //Flash Alarm LED
    if (trigger_state == LOW) { //If Trigger Input Low
    break; //Break
    }
    digitalWrite(alarm_active_led, HIGH); //Turn Alarm LED On
    }
    }
    }

    ReplyDelete
  3. I think this is ideal to make an alarm for a clothes dryer that did not come with a beep sounder when dryer stops. All I would do is invert the led polarity or change the code to fire led when not no vibration? Right?

    ReplyDelete
  4. Hi. What do you think about Iot from microsoft partner - Anegis? The number of IoT devices increased 31% year-over-year to 8.4 billion in the year 2017 and it is estimated that there will be 30 billion devices by 2020, so I think that this topic is becoming more and more common. That's great, don't you think?

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. Liquid Level Sensor can be used to identify the level of substances that can flow. There are various types of liquid level sensor used to detect the point level of a liquid. Some types use a magnetic float, which rise and fall with the liquid in the container.
    Liquid Level Sensor

    ReplyDelete
  7. We offer different type of telemetry devices which are used in order to track the level of fluids or gases in a particular tank system. Whether you are going to go for monitoring any liquid, the sensor is a mandatory part which is included in all metric devices. This is actually the component which is going to be detecting the level of any chemical and providing you the data. With this in mind, there are quite a few different types of Telemetry Chemical Level Sensor and yet these sensors are among the most popular ones.

    ReplyDelete
  8. hi.could you please send me the circuit diagram of this?My mail address; kerem.sbr73@gmail.com

    ReplyDelete
  9. How Mr Benjamin Lee service  grant me a loan!!!

    Hello everyone, I'm Lea Paige Matteo from Zurich Switzerland and want to use this medium to express gratitude to Mr Benjamin service for fulfilling his promise by granting me a loan, I was stuck in a financial situation and needed to refinance and pay my bills as well as start up a Business. I tried seeking for loans from various loan firms both private and corporate organisations but never succeeded and most banks declined my credit request. But as God would have it, I was introduced by a friend named Lisa Rice to this funding service and undergone the due process of obtaining a loan from the company, to my greatest surprise within 5 working days just like my friend Lisa, I was also granted a loan of $216,000.00 So my advise to everyone who desires a loan, "if you must contact any firm with reference to securing a loan online with low interest rate of 1.9% rate and better repayment plans/schedule, please contact this funding service. Besides, he doesn't know that am doing this but due to the joy in me, I'm so happy and wish to let people know more about this great company whom truly give out loans, it is my prayer that GOD should bless them more as they put smiles on peoples faces. You can contact them via email on { lfdsloans@outlook.com} or Text through Whatsapp +1-989 394 3740.

    ReplyDelete