I'm trying to make an earthquake detector

Hi guys, i am trying to make an earthquake detector that activates the buzzer when it detects movement and if there is still movement after 5 seconds it will start the relay, if the movement stops before 5 seconds then the system will not start the relay.

I am still a newbie in programming and this is all the code i can come up with.
i am using ADXL 335 accelerometer sensor and arduino uno.

#define buzzer 12 // buzzer pin
#define led 13  //led pin
#define relay 11 // relay pin

#define x A0  // x_out pin of Accelerometer
#define y A1  // y_out pin of Accelerometer
#define z A2  // z_out pin of Accelerometer

/*variables*/
int xsample=0;
int ysample=0;
int zsample=0;
long start;
unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 5000; 
/*Macros*/

#define samples 50
#define maxVal 20   // max change limit
#define minVal -20    // min change limit

void setup() 

{
  pinMode(buzzer, OUTPUT);
  pinMode(led, OUTPUT);
  for(int i=0;i<samples;i++)      // taking samples for calibration

  {
    xsample+=analogRead(x);
    ysample+=analogRead(y);
    zsample+=analogRead(z);

  }
  xsample/=samples;   // taking avg for x
  ysample/=samples;     // taking avg for y
  zsample/=samples;   // taking avg for z
  delay(3000);

}
void loop() 
{
    currentMillis = millis();
    
    int value1=analogRead(x);   // reading x out
    int value2=analogRead(y);   //reading y out
    int value3=analogRead(z);   //reading z out

    int xValue = xsample-value1;    // finding change in x
    int yValue = ysample-value2;    // finding change in y
    int zValue = zsample-value3;    // finding change in z

  /* comparing change with predefined limits*/

    if(xValue < minVal || xValue > maxVal  || yValue < minVal || yValue > maxVal  || zValue < minVal || zValue > maxVal)

Welcome.

Could you edit your post to add the remainder of your sketch?

1 Like

Describe what your code does and how this differs from what you want it to do. Use serial print to make sure it is doing as expected.

Delays make your code stop and do nothing and are to be avoided. You have a large delay in setup. You can look at “blink without delay” for ideas if you really need to delay but remain responsive

Always post code that compiles

That's all the code that i can come up with. I've been trying to add the 5 second timer, buzzer and relay but i cant do it

Still, this can not be all. You only posted half of the loop() function.

The code is incomplete, in that it won't even compile... surely there is more... it's like it stops mid flight. It's like you wrote a sentence but didn't ....

Ok. If that is all you have then, like they said above, you have stopped mid flow.

Open a new sketch and it will automatically have code that compiles, so infinitely better than what you have now.

Now decide on 1 thing you want to code, not 3! Look at examples and code it. Use serial to show that it is doing as you intend. Once it is working then save that sketch with a name that describes it. Now open a new sketch and do the same for thing number 2. Now try to combine those sketches. Now you should have these sketches:
Thing 1 (I compile and do what I say)
Thing 2 (I compile and do what I say)
Thing 1+2 (I compile and do what I say)

In this way you will always have a working sketch and know exactly where your problems are. You can then ask for help and people will be able to see your code and understand it

If this is true:

... then I'd say this is not your code. If it was...

  • you would know how to close loop... that's some pretty basic stuff.
  • you wouldn't create currentMillis if you didn't have a plan of how you were going to use it.
  • you would know how to finish an if statement.
  • the use of comments does not align with your level of coding ability.

Think I'm out on this one.

Did you consider to use a different sensor? A metal mass suspended in a metal can with little distance all around. An earthquake will shake the can while the mass will (sufficiently) stand still and make contact.

Take a look at this Arduino seismometer project. Used properly it can detect reasonably large earthquakes anywhere in the world.

https://create.arduino.cc/projecthub/mircemk/extremely-sensitive-cheap-homemade-seismometer-175231

1 Like

my problem is the relay switchess when it detects movement and switch again after 5 seconds even though there is no movement. what i want is the relay only switch when there is movement after 5 seconds.

#define buzzer 12 // buzzer pin
#define led 13  //led pin
#define relay 11 // relay pin

#define x A0  // x_out pin of Accelerometer
#define y A1  // y_out pin of Accelerometer
#define z A2  // z_out pin of Accelerometer

/*variables*/
int xsample=0;
int ysample=0;
int zsample=0;
long start;

unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 5000; 
/*Macros*/

#define samples 50
#define maxVal 20   // max change limit
#define minVal -20    // min change limit
bool stationary = true;
void setup() 
{
  pinMode(buzzer, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(relay, OUTPUT);
  for(int i=0;i<samples;i++)      // taking samples for calibration
  {
    xsample+=analogRead(x);
    ysample+=analogRead(y);
    zsample+=analogRead(z);
  }
  xsample/=samples;   // taking avg for x
  ysample/=samples;     // taking avg for y
  zsample/=samples;   // taking avg for z
  delay(3000);
}
void loop() 
{
    unsigned char i, j ;
    currentMillis = millis();
    int value1=analogRead(x);   // reading x out
    int value2=analogRead(y);   //reading y out
    int value3=analogRead(z);   //reading z out
    int xValue = xsample - value1;    // finding change in x
    int yValue = ysample - value2;    // finding change in y
    int zValue = zsample - value3;    // finding change in z
    int lastx, lasty, lastz;
  /* comparing change with predefined limits*/
    if(xValue < minVal || xValue > maxVal  || yValue < minVal || yValue > maxVal  || zValue < minVal || zValue > maxVal)
    { 
      if(xValue > minVal || xValue < maxVal  || yValue > minVal || yValue < maxVal  || zValue > minVal || zValue < maxVal)
      startMillis = millis();   // timer start
      stationary = false;
      digitalWrite (buzzer, HIGH) ; //send tone
      delay (1);
      digitalWrite (buzzer, LOW) ; //no tone
      delay (1);
    }
    else {
      // not moving
      stationary = true;
 } 
    if (stationary  && currentMillis - startMillis >= period) {
    digitalWrite(relay, LOW);
  } else {
    digitalWrite(relay, HIGH);
  }
}

What is the purpose of the 2nd if statement?

If you are trying to determine when to start the timer why don't you use...

      if (stationary == true)
        startMillis = millis();   // timer start

      stationary = false;

i was trying to start the timer when it detects movement

Which is when stationary changes from true to false... much easier to use that.

I've tried this but still the relay switches when i move the sensor and it also switches after 5 seconds even though there is no movement

Post. Your. Code.

Pretty hard to help when we are blind to what you are changing.

#define buzzer 12 // buzzer pin
#define led 13  //led pin
#define relay 11 // relay pin

#define x A0  // x_out pin of Accelerometer
#define y A1  // y_out pin of Accelerometer
#define z A2  // z_out pin of Accelerometer

/*variables*/

int xsample=0;
int ysample=0;
int zsample=0;
long start;

unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 5000; 


/*Macros*/

#define samples 50
#define maxVal 20   // max change limit
#define minVal -20    // min change limit
bool stationary = true;
void setup() 
{

  pinMode(buzzer, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(relay, OUTPUT);
  for(int i=0;i<samples;i++)      // taking samples for calibration
  {

    xsample+=analogRead(x);
    ysample+=analogRead(y);
    zsample+=analogRead(z);

  }
  xsample/=samples;   // taking avg for x
  ysample/=samples;     // taking avg for y
  zsample/=samples;   // taking avg for z
  delay(3000);

}
void loop() 
{
  
    currentMillis = millis();
    int value1=analogRead(x);   // reading x out
    int value2=analogRead(y);   //reading y out
    int value3=analogRead(z);   //reading z out
    int xValue = xsample-value1;    // finding change in x
    int yValue = ysample-value2;    // finding change in y
    int zValue = zsample-value3;    // finding change in z

  /* comparing change with predefined limits*/

    if(xValue < minVal || xValue > maxVal  || yValue < minVal || yValue > maxVal  || zValue < minVal || zValue > maxVal)

    { 
      if(stationary == true)
      startMillis = millis();   // timer start
      stationary = false;
      
      digitalWrite (buzzer, HIGH) ; //send tone
      delay (1);
      digitalWrite (buzzer, LOW) ; //no tone
      delay (1);
     
    }
    else {
      // Still moving
      stationary = true;
 }   

    if (stationary  && currentMillis - startMillis >= period) {
  } else {
    digitalWrite(relay, HIGH);
  }
}

Where do you set the relay LOW ???

More obvious to see your missing code if you formatted it better

if (stationary  && currentMillis - startMillis >= period) 
{

}
else
{
  digitalWrite(relay, HIGH);
}

#define buzzer 12 // buzzer pin
#define led 13  //led pin
#define relay 11 // relay pin

#define x A0  // x_out pin of Accelerometer
#define y A1  // y_out pin of Accelerometer
#define z A2  // z_out pin of Accelerometer

/*variables*/

int xsample=0;
int ysample=0;
int zsample=0;
long start;

unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 5000; 


/*Macros*/

#define samples 50
#define maxVal 20   // max change limit
#define minVal -20    // min change limit
bool stationary = true;
void setup() 
{

  pinMode(buzzer, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(relay, OUTPUT);
  for(int i=0;i<samples;i++)      // taking samples for calibration
  {

    xsample+=analogRead(x);
    ysample+=analogRead(y);
    zsample+=analogRead(z);

  }
  xsample/=samples;   // taking avg for x
  ysample/=samples;     // taking avg for y
  zsample/=samples;   // taking avg for z
  delay(3000);

}
void loop() 
{
    unsigned char i, j ;
    currentMillis = millis();
    int value1=analogRead(x);   // reading x out
    int value2=analogRead(y);   //reading y out
    int value3=analogRead(z);   //reading z out
    int xValue = xsample-value1;    // finding change in x
    int yValue = ysample-value2;    // finding change in y
    int zValue = zsample-value3;    // finding change in z

  /* comparing change with predefined limits*/

    if(xValue < minVal || xValue > maxVal  || yValue < minVal || yValue > maxVal  || zValue < minVal || zValue > maxVal)

    { 
      if(stationary == true)
      startMillis = millis();   // timer start
      digitalWrite (buzzer, HIGH) ; //send tone
      delay (1);
      digitalWrite (buzzer, LOW) ; //no tone
      delay (1);
      stationary = false;
    }
    else {
      // Still moving
      stationary = true;
 }   

    if (stationary  && currentMillis - startMillis >= period) {
    digitalWrite(relay, LOW);
  } else {
    digitalWrite(relay, HIGH);
  }
}

and ?