Hi I am trying to get a continuous servo motor and buzzer to run for 2 seconds after the LDR detects a low value, however they are triggered and start running when the LDR detects something but it does not stop after 2 seconds and just keeps on running. I have attached the wiring diagram and code, please help.
edit: i realise the LDR is wired incorrectly in the diagram, i have wired it with a resistor in my project
#include <Servo.h> // Library for the servo
Servo myservo; // Create a servo object to control the servo
#define buttonPin 2
#define LDR A0
#define LED 1
#define buzzer 3
unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 2000; // 2 seconds
int buttonState;
bool isRunning = false;
void setup() {
myservo.attach(9); // Attach the servo to pin 9
pinMode(buttonPin, INPUT_PULLUP); // Set button pin as input with internal pull-up
pinMode(LDR, INPUT); // Set LDR pin as input
pinMode(LED, OUTPUT); // Set LED pin as output
pinMode(buzzer, OUTPUT); // Set buzzer pin as output
Serial.begin(9600); // Start serial communication at 9600 baud
}
void loop() {
int ldrValue = analogRead(LDR); // Read the LDR value
Serial.println(ldrValue); // Print the LDR value to the serial monitor
// Check if the light level is low (LDR value below threshold) and system is not already running
if (ldrValue < 300 && !isRunning) {
isRunning = true; // Set running flag to true
startMillis = millis(); // Record the start time
myservo.write(45); // Servo spins in clockwise direction
digitalWrite(LED, HIGH); // Turn on the LED
playBuzzer(); // Play buzzer sound
}
// If the system is running, check the elapsed time
if (isRunning) {
currentMillis = millis();
// If the elapsed time is greater than or equal to the period, stop everything
if (currentMillis - startMillis >= period) {
myservo.write(90); // Stop the servo
digitalWrite(LED, LOW); // Turn off the LED
noTone(buzzer); // Stop the buzzer sound
isRunning = false; // Reset the running flag
}
}
// Check if the button is pressed
buttonState = digitalRead(buttonPin);
if (buttonState == LOW) {
myservo.write(135); // Servo spins in counter-clockwise direction
delay(2000); // Wait for 2 seconds
myservo.write(90); // Stop the servo
}
}
void playBuzzer() {
tone(buzzer, 1000); // Play 1000 Hz tone
delay(100); // Wait for 100 ms
tone(buzzer, 500); // Play 500 Hz tone
delay(100); // Wait for 100 ms
noTone(buzzer); // Stop any sound from the buzzer
}
void playBuzzer() {
// Control buzzer frequency for siren effect
if (increasing) {
buzzerFrequency += frequencyStep;
if (buzzerFrequency >= 1000) {
increasing = false; // Start decreasing frequency
}
} else {
buzzerFrequency -= frequencyStep;
if (buzzerFrequency <= 500) {
increasing = true; // Start increasing frequency
}
}
tone(buzzer, buzzerFrequency); // Set the buzzer to the current frequency
}
your LDR is wired as heater, A0 will be always 1023. LED showed on wrong pin.
for buzzer better to use a driver.
#include <Servo.h> // Library for the servo
Servo myservo; // Create a servo object to control the servo
#define buttonPin 2
#define LDR A0
#define LED 4
#define buzzer 3
unsigned long startMillis;
unsigned long currentMillis;
const unsigned long period = 2000; // 2 seconds
int buttonState;
bool isRunning = false;
int buzzerFrequency = 500; // Start frequency for the siren sound
int frequencyStep = 10; // Step size for frequency change
bool increasing = true; // Flag for increasing or decreasing frequency
void setup() {
myservo.attach(9); // Attach the servo to pin 9
pinMode(buttonPin, INPUT_PULLUP); // Set button pin as input with internal pull-up
pinMode(LDR, INPUT); // Set LDR pin as input
pinMode(LED, OUTPUT); // Set LED pin as output
pinMode(buzzer, OUTPUT); // Set buzzer pin as output
Serial.begin(9600); // Start serial communication at 9600 baud
}
void loop() {
int ldrValue = analogRead(LDR); // Read the LDR value
Serial.println(ldrValue); // Print the LDR value to the serial monitor
// Check if the light level is low (LDR value below threshold) and system is not already running
if (ldrValue < 80 && !isRunning) {
isRunning = true; // Set running flag to true
startMillis = millis(); // Record the start time
myservo.write(45); // Servo spins in clockwise direction
digitalWrite(LED, HIGH); // Turn on the LED
}
// If the system is running, manage all components
if (isRunning) {
playBuzzer(); // Call playBuzzer to control the siren sound
// If the elapsed time is greater than or equal to the period, stop everything
if (millis() - startMillis >= period) {
myservo.write(90); // Stop the servo
digitalWrite(LED, LOW); // Turn off the LED
noTone(buzzer); // Stop the buzzer sound
isRunning = false; // Reset the running flag
}
}
// Check if the button is pressed
if (digitalRead(buttonPin) == LOW) {
myservo.write(135); // Servo spins in counter-clockwise direction
delay(2000); // Wait for 2 seconds
myservo.write(90); // Stop the servo
}
delay(10);
}
void playBuzzer() {
// Control buzzer frequency for siren effect
if (increasing) {
buzzerFrequency += frequencyStep;
if (buzzerFrequency >= 1000)increasing = false; // Start decreasing frequency
} else {
buzzerFrequency -= frequencyStep;
if (buzzerFrequency <= 500)increasing = true; // Start increasing frequency
}
tone(buzzer, buzzerFrequency); // Set the buzzer to the current frequency
}
/* a global variable to remember the last time (and the first time)
we did the thing and will repeat the event every 3 seconds by
comparing it to a timer variable, in this case, threeSecondTimer.
In a more complex sketch, it may be helpful to declare these
variables locally to some function, but we'll keep it simple for
this example. */
unsigned long lastTime = 0;
unsigned long threeSecondTimer = 3000;
void setup() {
Serial.begin(115200);
Serial.println("millisTimerRepeatingEvent");
Serial.println();
}
void loop() {
/* now that currentmillis equals millis(),
it will count up until 4,294,967,295 before starting over at 0 */
unsigned long currentMillis = millis();
if (currentMillis - lastTime > threeSecondTimer) {
Serial.println("this gets printed every 3 seconds, or 3000 milliseconds");
// and anything you put in this block will also run only every 3000 milliseconds
// as long as it's non-blocking (so while() or delay() will break the precision of the
// timer)
lastTime = currentMillis;
}
}
Yes/somewhat. A relative "zero"... the millis() counter is always increasing. Your code assigns millis() to currentMillis so you can compare the "now" time. When your period elapses, you will want to to set your new "zero" time to startMillis... so your assignment should look like this (opposite of your post):
startMillis = currentMillis // startMillis is assigned the value held by currentMillis