Pages: 1 [2]   Go Down
Author Topic: Need Help with Piezo Buzzer and Ultrasonic Sensor code  (Read 990 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Faraday Member
**
Karma: 68
Posts: 2787
The last thing you did is where you should start looking.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What is printed on the serial monitor?
Logged

The way you have it in your schematic isn't the same as how you have it wired up! That goes for me too.

Offline Offline
Faraday Member
**
Karma: 68
Posts: 2787
The last thing you did is where you should start looking.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This works, here, with a DC-SR04 ultra sonic transducer and a piezo speaker like yours.

EDIT: Added code to run the task every 1/2 second to slow things down and let the speaker/buzzer time out
Code:
/*
 HC-SR04 Ping distance sensor]
 VCC to arduino 5v GND to arduino GND
 Echo to Arduino pin 13 Trig to Arduino pin 12
 More info at: http://goo.gl/kJ8Gl
 *** edited by LarryD and KalELonRedKryptonite  ***
 */

#define trigPin 12
#define echoPin 13

unsigned long duration, distance;
int hysteresis = 2;       // minimum acceptable change
boolean buzzState = false;  // false = buzzer is off
unsigned long buzzDelay;  //Time the buzzer will be On
unsigned long buzzMilli;  //Time the buzzer went On
int lastDistance;  // = the last read distance value

const unsigned long TaskAtime  = 500UL;  //Runs TaskA every 1/2 second
unsigned long TimeA;                     //Times up, Task A time

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(4,OUTPUT);
}

void loop()
{
  unsigned long millisNow = millis();
 
 if (millisNow - TimeA >= TaskAtime) //Is it time to run Task A?
  {
    TimeA = millis();      //Re-initialize
    TaskA();                    // go and execute this code
  }

// Check to see if its time to turn off the buzzer, IF, it's on
  if (buzzState == true && (millis() - buzzMilli >= buzzDelay))    //is time left and is the buzzer ON?
  {
    digitalWrite(4,LOW); //turn off the buzzer
    buzzState = false;  //indicate the buzzer is now off
  }
}   
// END of loop()

// FUNCTIONS
//==========================================================
void TaskA()
{
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(1000);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;

//Don't accept too large/small of a range 
 if (distance >= 200 || distance <= 0)
  {
    Serial.println("Out of range");
    return;  // invalid distance, go back
  }
  else
  {
    Serial.print(distance);
    Serial.println(" cm");
  }

// Has the distance changed significantly?
  if ((lastDistance + hysteresis) < distance || (lastDistance - hysteresis) > distance)
  {
    lastDistance = distance;   // update to the current distance
    buzzDelay = distance;      // time in milliseconds the buzzer will be on
    buzzMilli = millis();           // the time the buzzer was turned on
    buzzState = true;              // indicate the buzzer is now on
    digitalWrite(4,HIGH);        //turn on the buzzer
  }
}
« Last Edit: March 30, 2014, 01:05:16 am by LarryD » Logged

The way you have it in your schematic isn't the same as how you have it wired up! That goes for me too.

Offline Offline
Faraday Member
**
Karma: 68
Posts: 2787
The last thing you did is where you should start looking.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Try replacing the speaker with a LED + 220 ohm resistor.
what happens with the LED?
Logged

The way you have it in your schematic isn't the same as how you have it wired up! That goes for me too.

Seattle, WA - USA
Offline Offline
Newbie
*
Karma: 1
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay it's working, both the LED and buzzer with the new code.

It only beeps once in awhile though, so I think some tweaking of the numbers is in order.

I'm going to try the older version of the code and see if it works now too. I tore it down and rebuilt it so maybe I had something wrong yesterday that I kept missing, I'll post back here shortly and let you know.
Logged

Seattle, WA - USA
Offline Offline
Newbie
*
Karma: 1
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well that figures, the old code works now too, even better than the new code haha  smiley-red

Clearly I had something wrong yesterday and repeatedly missed it.


EDIT:
This code works, mostly, and buzzes AND flashes an LED though it could be tweaked to be more accurate I think.

Code:
/*
 HC-SR04 Ping distance sensor]
 VCC to arduino 5v GND to arduino GND
 Echo to Arduino pin 13 Trig to Arduino pin 12
 More info at: http://goo.gl/kJ8Gl
***  edited by LarryD and KalELonRedKryptonite ***
 */


#define trigPin 12
#define echoPin 13

  int duration, distance;
  int hysteresis = 5;       // minimum acceptable change
  boolean buzzState = false;  // false = buzzer is off
  unsigned long buzzDelay;  //Time the buzzer will be On
  unsigned long buzzMilli;  //Time the buzzer went On
  int lastDistance;  // = the last read distance value


void setup() {

  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(4,OUTPUT);
  pinMode(6,OUTPUT);
 
}

void loop() {
 
 
digitalWrite(trigPin, HIGH);
delayMicroseconds(1000);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;
 
 
 
  if (distance >= 200 || distance <= 0)
  {
    Serial.println("Out of range");
  }
  else
  {
    Serial.print(distance);
    Serial.println(" cm");
  }

  // Has the distance changed significantly?
  if ((lastDistance + hysteresis) < distance || (lastDistance - hysteresis) > distance)
  {
    lastDistance = distance;
    buzzDelay = distance;
    buzzMilli = millis();
    buzzState = true; // indicate the buzzer is now on
    digitalWrite(4,HIGH);  //turn on the buzzer
    digitalWrite(6,HIGH);  //turn on the LED
  }

  if (buzzState == true && (millis() - buzzMilli >= buzzDelay))    //is time left and is the buzzer ON?
  {
    digitalWrite(4,LOW); //turn off the buzzer
    digitalWrite(6,LOW); //turn off the LED
    buzzState = false;  //indicate the buzzer is now off
  }
 

}   
   // END of loop()


I haven't done functions yet, so I'm going to read up on them first before I attempt to do the same with the newer code.
« Last Edit: March 30, 2014, 09:24:22 pm by KalELonRedkryptonite » Logged

Offline Offline
Faraday Member
**
Karma: 68
Posts: 2787
The last thing you did is where you should start looking.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Test time.
What does hysteresis do in the code?
Logged

The way you have it in your schematic isn't the same as how you have it wired up! That goes for me too.

Seattle, WA - USA
Offline Offline
Newbie
*
Karma: 1
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I actually had to Google the word yesterday.

It's a relationship of two things changing and affecting each other, and I think in a proportional or ratio kind of way. As for what it does in the code, I'm not 100% sure, but it has to do with the relationship between distance and the buzzer/LED activating or not. I have to go soon so I don't have time to test it right now, but I'm going to raise and lower the number and see what happens.
Logged

Offline Offline
Faraday Member
**
Karma: 68
Posts: 2787
The last thing you did is where you should start looking.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

When you come to a understanding of it does, report back.

What happens when it is set to zero?
« Last Edit: March 30, 2014, 11:34:53 pm by LarryD » Logged

The way you have it in your schematic isn't the same as how you have it wired up! That goes for me too.

Seattle, WA - USA
Offline Offline
Newbie
*
Karma: 1
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nevermind about distance vs lastDistance, I was confusing myself because I realized on the very first reading lastDistance would have no value, but every reading after that it would be different or the same from the distance value.

The Hysteresis variable makes it so it only triggers the loop if the distance has changed 'x' amount. What's perplexing though, is values of 1 or 10 for hysteresis seem to do the same thing and maybe it's just a crap sensor but it doesn't seem to respond when it should and it goes crazy beeping and flashing unexpectedly.

The serial monitor works, here is an example with Hysteresis set at 10:

Quote
5 cm
7 cm
6 cm
6 cm
6 cm
6 cm
6 cm
6 cm
6 cm
6 cm
Out of range
6 cm
6 cm
Out of range
6 cm
« Last Edit: April 01, 2014, 08:37:17 pm by KalELonRedkryptonite » Logged

Offline Offline
Faraday Member
**
Karma: 68
Posts: 2787
The last thing you did is where you should start looking.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

distance is the value that is measured EACH time trough the loop() this can be update thousands of times in a second.
lastDistance is the value you measured in a PRIOR loop (in a past ).
lastDistance is only update to the new value if there has been SIGNIFICANT movement.

What you are doing is comparing the current distance to a previous distance and, only if, they are different are you going to turn on the speaker.  If they are the same (within a range+-) the speaker is quiet. 

So in essence, the speaker will only beep if, A SIGNIFICANT CHANGE HAS BEEN DETECTED.
hysteresis is the variable that defines HOW MUCH you have to move towards OR away from the sensor before this can be called significant.
Logged

The way you have it in your schematic isn't the same as how you have it wired up! That goes for me too.

Offline Offline
Faraday Member
**
Karma: 68
Posts: 2787
The last thing you did is where you should start looking.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Make hysteresis = 0, what happens?
Make hysteresis = 10, what happens?

This could be referred to as sensitivity.
Logged

The way you have it in your schematic isn't the same as how you have it wired up! That goes for me too.

Seattle, WA - USA
Offline Offline
Newbie
*
Karma: 1
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Haha, hysteresis set to zero is pretty funny, it goes off very often, rapidly at times. Now the hysteresis value is in CM correct? I guess it would have to be, since the rest is in CM, and it's just basic math.

If I wanted to mount this sensor to a servo and use it for obstacle detection for a robot, then in your opinion what type of sensitivity would I need so the robot has time to properly maneuver?
I guess that would depend on how fast or slow it is, but mine won't move that fast as it is just powered by dual Tamiya motors (#70168).

I have the chassis built and it will probably end up around 20x15x15 CM in area/dimension when it's all put together. I've been planning it and acquiring parts the last couple months but decided it would be best to learn how each component works by itself before I try to put it all together into one machine. That and learning a new programming language.
Logged

Offline Offline
Faraday Member
**
Karma: 68
Posts: 2787
The last thing you did is where you should start looking.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If I wanted to mount this sensor to a servo and use it for obstacle detection for a robot, then in your opinion what type of sensitivity would I need so the robot has time to properly maneuver?

Just have to experiment.

Good luck with your project.
Logged

The way you have it in your schematic isn't the same as how you have it wired up! That goes for me too.

Pages: 1 [2]   Go Up
Jump to: