Piezo Vibration sensor as blow sensor to run DC motor

Hello,

For my project, I am trying to run a small DC motor when you blow over the piezo sensor.

I referred the circuit and the code from
http://www.dtic.upf.edu/~jlozano/interfaces/blow_sensor.html

I used the exact circuit as posted in the site. But when I try to run the code given in the site, my circle in the processing keeps growing by itself, without even me blowing. Basically the sensorReading keeps reading some values, without even me blowing.

Can anyone tell me where i could have gone wrong?

My first suggestion is to say I usually get an average from several sensor readings instead of just one reading. Something like:

for (int i=0; i <= 9; i++)
{
      value = value +analogRead(sensorPin); 
} 
value=value;10

My second thought is something is off in your setup, like the wrong value for a resistor.
Do you have picture of how this is wired up?

Hi!..thank you!..i figured out the problem, it was because of wrong resistor value.. :stuck_out_tongue:

But I am encountering another problem.

This is my code:

const int motorPin = 3;
const int piezo = A0;  // the piezo is connected to analog pin 0


int sensorReading = 0;      // variable to store the value read from the sensor pin
int sensorMax = 0;
int sensorMin = 1023;
int threshold;


void setup()
{

 pinMode(motorPin, OUTPUT);
  Serial.begin(57600);       // use the serial port

//CALIBRATION
  digitalWrite(3, HIGH);
  while (millis() < 3000)
  {
    threshold = analogRead(piezo);

    // record the maximum sensor value
    if (threshold > sensorMax)
    {  
      sensorMax = threshold;
    }
    if (threshold < sensorMin)
    {
      sensorMin = threshold;
    }

  }

  // signal the end of the calibration period
  digitalWrite(3, LOW);
  threshold = sensorMax;
}


void loop()
{
  // read the sensor and store it in the variable sensorReading:
  sensorReading = analogRead(piezo);    

  

  //if within range..run motor
  if ((sensorReading >= threshold) || (sensorReading <= sensorMin))
  {
    Serial.println(sensorReading);
    digitalWrite (motorPin,HIGH);
    delay (1000);
    digitalWrite (motorPin, LOW);
  }

  delay(2000);
}

In this, the motor runs whenever the sensor is within the range specified. But me blowing the sensor and the motor running is not in synced. I am new to coding and stuffs, and I am not able to comprehend what modification needs to be done.

The loop code needs an if else statement;

if ((sensorReading < threshold) && (sensorReading > sensorMin))
  {
    Serial.print("blowing ");
    Serial.println(sensorReading);
    digitalWrite (motorPin,HIGH);
  }
else
  {
    Serial.print("Not blowing ");
     Serial.println(sensorReading);
     digitalWrite (motorPin, LOW);
  }

That way the motor is on when the sensor is in range and off when its not. No delays

Cool!..Thank You!..:slight_smile:

Ok. This is my final code:

const int motor1 = 3;
const int motor2 = 4;
const int piezo = 0;  // the piezo is connected to analog pin 0


// these variables will change:
int sensorReading = 0;      // variable to store the value read from the sensor pin
int sensorMax = 0;
int sensorMin = 1023;
int threshold;


void setup() {
  pinMode(13, OUTPUT);
  pinMode(motor1, OUTPUT);
  pinMode(motor2, OUTPUT); 
  Serial.begin(57600);       // use the serial port

  
  //CALIBRATION:
  digitalWrite(13, HIGH);

  while (millis() < 3000)
  {
    threshold = analogRead(piezo);

    // record the maximum sensor value
    if (threshold > sensorMax) {
      sensorMax = threshold;
    }
    if (threshold < sensorMin) {
      sensorMin = threshold;
    }
  }

  // signal the end of the calibration period
  digitalWrite(13, LOW);
  digitalWrite(motor1, LOW);
  digitalWrite(motor2, LOW);
  threshold = sensorMax;

  Serial.println (sensorMax);
  Serial.println (sensorMin);
}


void loop()
{
  // read the sensor and store it in the variable sensorReading:
  sensorReading = analogRead(piezo);    
  Serial.println(sensorReading);

  //I say..if <= sensorMin run one motor; if >= threshold run all
  if ((sensorReading >= 350) && (sensorReading <= 500))
  {
    
    Serial.println ("Blow");
    Serial.println (threshold);
    digitalWrite (motor1,HIGH);
    delay (1000);
    digitalWrite (motor1, LOW);
  }
  else
  {
    if (sensorReading > 550)
    {
      Serial.println ("Spin");
      Serial.println(sensorMin);
      digitalWrite (motor1,HIGH);
      digitalWrite (motor2,HIGH);
      delay (1000);
      digitalWrite (motor1, LOW);
      digitalWrite (motor2, LOW);
    }
  }

  delay(300); 
}

In the code, I am defining 2 'if' conditions - One to run one motor, and another to run two motors together. Well, when the code is uploaded, though the whole setup kind of works the way I want it to, the action (blowing on to the sensor) and the reaction (the motor(s) running) do not accurately sync. My question is, playing with numbers (of the sensorReading) in the boundary conditions is the only possible way to make the if conditionals work, or is there any other accurate way to sync the action and reaction?

I would dump the delays and have something like;

<before setup>
  int inertia1 = 0;  // the inertia countdown motor 1
  int inertia2 = 0;  // the inertia countdown motor 2

.....

  //I say..if <= sensorMin run one motor; if >= threshold run all

  if (sensorReading < 350)   { 
     if (inertia1  > 0)      { 
         inertia1 --;
     }
     else {
         digitalWrite (motor1, LOW);
     }
     if (inertia2  > 0) { 
         inertia2 --;
     }
     else     {
        digitalWrite (motor2, LOW);
     }
  }  // end below 350 if

  if (sensorReading > 350)   {
    inertia1 = 100;                 // reset motor1 spin inertia
    Serial.println ("Blow");
    Serial.println (threshold);
    digitalWrite (motor1,HIGH);
  }  // end if 350

 if (sensorReading > 550)    {
      inertia2 = 80;                  // reset motor2 spin inertia
      Serial.println ("Spin");
      Serial.println(sensorMin);
  //    digitalWrite (motor1,HIGH);  // should be running already from the last if
      digitalWrite (motor2,HIGH);
 }  // end if 550

delay(100);   // this * the inertia values is for the extra spin

:slight_smile: Thank You..