I'm new to electronics and after following a couple tutorials I have run into a problem. My code (I assume) is causing an unintended outcome with my Piezo Buzzer. I thought I have it so depending on the distance the HC-SR04 ultrasonic sensor detects, the Buzzer should change tone. Instead, from my Buzzer I get one loud annoying scream constantly no matte what the sensor is pointing at or how far away it is. I don't know enough to know what the problem is, can anybody help me figure it out?
Here is the setup:
Arduino Uno R3
Supplying 5V to breadboard power rail via 5v out pin, and ground pin(14?) to ground rail on the breadboard.
HC-SR04 Sensor is plugged into breadboard. Power from power rail, ground to ground rail. Trigger pin to pin12 on Uno, and echo pin to pin13 on Uno.
Piezo Buzzer black wire to ground on breadboard, and red wire to a row where a jumper connects it to pin 4 on the Uno.
External power supply is a 9v, 280 maH rechargeable battery plugged into barrel jack on Uno.
It means the piezo has a built in oscillator and will sound whenever it sees DC.
Tone is not needed just a DC level.
The buzzer will not change tone, it will always be the same tone.
This speaker will only output one tone, 3300Hz, see data sheet, and will produce this whenever it sees DC.
int thisPitch = map(distance, 0, 200, 2093, 22);
will not change the frequency.
Oh I see now. Okay, so I can't change the tone, but then could I change the code so the buzzer changes how long it beeps that tone for to indicate a change in distance? Instead of changing tone can I turn the tone on and off at different intervals somehow? Thanks by the way for answering my questions earlier.
I'm new to C/C++ so I'm a bit confused. Can someone give a suggestion on how to compare the distance number (range of the HC-SR04 is 2-400 CM) to the tone delay interval number for the Buzzer so one will influence the other?
I did not have a sensor so I used a POT.
Add/delete/change lines as needed.
You should be able to modify the code to your ultrasonic application.
Change hysteresis as needed.
int duration;
int 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);
buzzState = false;
pinMode(4,OUTPUT);
}
void loop()
{
duration = analogRead(A0);
distance = (duration);
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
}
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()
This is what I came up with. According to the serial monitor the sensor is working just fine, but the buzzer is not buzzing, ever. Where did I go wrong editing the code? Thank you, I do appreciate your time.
/*
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
void setup() {
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(4,OUTPUT);
}
void loop() {
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
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
}
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()
Move these under the #defines area, the report back.
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
back at the bottom and the buzzer now works, but it is a constant buzz instead of being interrupted no matter what I point the sensor at.
EDIT: ignore this post, pretty sure on this specific test I put the wire in the power rail instead of the signal rail. But all other tests I double and triple checked my wires were correct.
I tried all combinations of inside the loop and outside the loop, with the delay statement and without, none work, all have silent buzzer. Yes, sensor is working according to serial monitor.
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
/*
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
}
}
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.
Well that figures, the old code works now too, even better than the new code haha
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.
/*
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.