SW420 vibration sensor: Help with code

Hi, newbie here in search of some advice. I'm using an arduino uno, Sw420 vibration sensor, buzzer, and a relay for my project. The code I have below works, but not how I'd like it to. Every time I shake the sensor it triggers the relay and buzzer momentarily (only when shaking the sensor).

What I would like is for the arduino to sense that the sensor is being shaken for 3 seconds or so, then trigger the relay and buzzer for 5 seconds or so. Below is the section of code I'm using to measure the vibration sensor, but am unsure of how to get it to sense that the measurement is > than 50 for 3 seconds, then to trigger the relay and buzzer for 5 seconds. I explored some Delay and Millis tutorials, but am unsure if that is what is needed to get this working the way I want.

  if ( measurement > 50){

Below is the full code, any help would be much appreciated.

int relay = 8; // Relay
int vs =7; // vibration sensor
int buzz = 6; //Buzzer


void setup(){
  pinMode(relay, OUTPUT);
  pinMode(vs, INPUT); 
  pinMode (buzz, OUTPUT); 
  Serial.begin(9600);

   digitalWrite(buzz, HIGH);
  delay(15);
  
  digitalWrite(buzz, LOW);
  delay (15); 

}
void loop(){
  
  
  long measurement =vibration();
  delay(50);
  Serial.println(measurement);
  if ( measurement > 50){
    
    digitalWrite(relay, HIGH);
  }
  else{
    digitalWrite(relay, LOW); 
  }
}

long vibration(){
  long measurement=pulseIn (vs, HIGH,5000);  //wait for the pin to get HIGH and returns measurement
  return measurement;
}

How is the vibration sensor connected to the Arduino?

If you have not studied the tutorials on reading switches, you may find them helpful.

1 Like

A couple of questions, mainly because I don't know what vibration sensor you are using:

  1. Why do you have a delay(50)?
  2. What is your vibration sensor and why did you choose 50us pulse length as the threshold?

Apart from these questions your logic should record millis() when you detect that you previously detected no vibration and now you detect vibration (this is a "state change"). As long as you detect vibration check to see if 3000ms have passed. If 3000ms have passed then turn the buzzer/relay on and save millis() to use for a buzzer/relay timer. When 5000ms have passed then turn the buzzer/relay off.

If you previously had vibration and then have no vibration before 3000ms have passed then start over without turning on the buzzer/relay.

One question you have to answer is that if vibration continues past the 5 second buzzer/relay period do you continue buzzing or do you stop the buzzer and wait for vibration to stop and then begin again.

Do you have the naked SW-420 shake switch, or the SW-420 module?

Thanks for the reply!

  1. The delay was there because I got the code from a tutorial video on youtube and used most of their code and added some of my own. I kept the delay in there but it's likely not needed.
    Arduino Project: Vibration sensor tutorial, Vibration measurement, vibration detector “SW 420” - YouTube

2.The sensor I'm using is linked below. 50us is what the tutorial I linked was using. My goal was to get the code working the way I wanted, then change that value to a different value.

So if I understand you correctly; Use the millis() function to start recording when the system is turned on (arduino is powered on), and when there's a state change, if it's longer than 3 seconds to drive the relay/buzzer high for 5 seconds?

If the vibration continues I want the relay and buzzer to continue buzzing until no vibration is sensed, so I guess that's different than what I previously stated.

Thank you for the reply, you really got me thinking and have given me more homework.

Thanks for the reply!
What I'm using is similar to the module you posted. I linked it below. I'm also using a V2 base shield to connect everything to the board.

Sensor: Grove - Vibration Sensor(SW-420) - Seeed Wiki
Base shield: Base Shield V2 - Seeed Wiki

Here is the way I would code it. In this version if the vibration lasts more than 3 seconds the relay will close and the buzzer will buzz. They will remain closed/buzzing until 5 seconds after the vibration stops. I didn't have time to test it but I commented it and added print statements for debugging.

const int relayPin = 8;  // Relay pin
const int vsPin =7;      // Vibration sensor pin
const int buzzPin = 6;   // Buzzer pin
unsigned long vibStartMillis;    // time when vibration started
unsigned long relayStartMillis;  // time when relay closed

void setup()
{
  Serial.begin(9600);
  pinMode(vsPin, INPUT); 
  pinMode(buzzPin, OUTPUT); 
  pinMode(relayPin, OUTPUT);
  digitalWrite(buzzPin, LOW);
  digitalWrite(relayPin, LOW);
}

void loop()
{
  static unsigned long lastMeasurement = 0; // measurement value from last reading
  unsigned long measurement = vibration();  // current measurement
  unsigned long currMillis = millis();      // current millis since start
  
  Serial.println(measurement);

  // Check for vibration
  if (measurement >= 50)
  {
    // Vibration present
    if (lastMeasurement < 50)
    {
      // Went from "no vibration" to "vibration"
      Serial.println("Vibration Started");
      vibStartMillis = millis(); // record millis when vibration started
    }
    else
    {
      // Vibration continues so check to see if it exceeds 3 secs
      if (currMillis - vibStartMillis > 3000)
      {
        // Vibration exceeds 3 seconds so close relay and turn on buzzer
        Serial.println("Close relay");
        digitalWrite(relayPin, HIGH);
        digitalWrite(buzzPin, HIGH);
        relayStartMillis = currMillis;
      }
    }
  }
  else // measurement must be < 50
  {
     if (lastMeasurement >= 50)
     {
      // Went from "vibration" to "no vibration"
      Serial.println("Vibration Stopped");
     }
  }
  
  // If the relay is closed then check to see if it should be turned off
  if (digitalRead(relayPin) == HIGH && (currMillis - relayStartMillis > 5000))
  {
    // The relay was closed and has been closed for more than 5 seconds
    Serial.println("Open relay");
    digitalWrite(relayPin, LOW);  // Open relay
    digitalWrite(buzzPin, LOW);   // Turn off buzzer
  }
  
  lastMeasurement = measurement; // save measurement for next time
}

unsigned long vibration()
{
  return pulseIn (vsPin, HIGH,5000);
}

Thank you so much for writing the program Todd, that was very nice of you. It worked well and I'll continue to tweak it. Thank you for the notes as well, they helped me understand what the original code needed, and I'll continue to read up on the things I don't understand.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.