I am running the following code to run the motor activated by sound. Need help with code to run the motor for 1 minute before stopping when the "digitalValue==LOW". Thanks
// Include the library
#include <Servo.h>
// Create the servo object
#define servoPin 9
Servo myservo;
// Create a variable to store the servo position:
int angle = 0;
int sensorDigitalPin = 3; // Select the Arduino input pin to accept the Sound Sensor's digital output
int digitalValue; // Define variable to store the digital value coming from the Sound Sensor
int Led13 = 13; // Define LED port; this is the LED built in to the Arduino (labled L)
void setup()
{
pinMode(sensorDigitalPin,INPUT); // Define pin 3 as an input port, to accept digital input
pinMode(Led13,OUTPUT); // Define LED13 as an output port, to indicate digital trigger reached
myservo.attach(servoPin); // attach the servo to our servo object
myservo.write(0);
}
void loop(){
digitalValue=digitalRead(sensorDigitalPin); // Read the value of the digital interface 3 assigned to digitalValue
if(digitalValue==HIGH) // When the Sound Sensor sends signal, via voltage present, light LED13 (L)
{
// scan from 0 to 180 degrees
for(angle = 0; angle < 180; angle++)
{
myservo.write(angle);
delay(15);
}
// now scan back from 180 to 0 degrees
for(angle = 180; angle > 0; angle--)
{
myservo.write(angle);
delay(15);
}
}
else
{
myservo.write(0); // stop the motor
}
}
For timing events, use the millis() function. Have a look at this excellent Blink Without Delay tutorial: https://www.baldengineer.com/blink-without-delay-explained.html
Hi,
Welcome to the forum. Thanks for posting your code in code tags.
I am confused about the question. What are you seeing now? Does your servo do a sweep when digitalValue is HIGH?
Are you wanting the servo to do this when digitalValue is LOW?
Or do you want to have the servo keep doing a sweep back and forth for one minute when digitalValue is LOW?
Yes , the servo sweeps 0-180 when it is high, but stops as soon as the sound is gone.
I am trying to use this on a swing cradle for a baby to swing when crying is detected., and would like it to sweep for a little while after baby stops crying.
Thanks for the tip. I will look into it.
I have used millisTimer with another project.
if (digitalValue == HIGH) // When the Sound Sensor sends signal, via voltage present, light LED13 (L)
{
unsigned long startTime = millis();
while (millis() - startTime < 60000ul)
{
Ok, that should be easy enough to fix.
What you would want to do is to have a variable which stores the current time as long as the sensor is HIGH. Then set a 1 minute timer without delay, as per jremington above.
Lets assume everything after the if(digitalValue==HIGH) above is a function called sweepServo().
Pseudo-code could be like this (not tested):
long timeOfLastSweep = 0;
long extraTime = 1000*60*1; // millisec in second * sec in min * minutes of extra sweep
if(digitalValue==HIGH) {
timeOfLastSweep = millis();
sweepServo();
}
if (digitalValue == LOW) {
if (millis() - timeOfLastSweep < extraTime) {
sweepServo()'
}
}
Thanks for your prompt reply and advise. Worked perfectly.`// Include the library
#include <Servo.h>
// Create the servo object
#define servoPin 9
Servo myservo;
// Create a variable to store the servo position:
int angle = 0;
int sensorDigitalPin = 3; // Select the Arduino input pin to accept the Sound Sensor's digital output
int digitalValue; // Define variable to store the digital value coming from the Sound Sensor
int Led13 = 13; // Define LED port; this is the LED built in to the Arduino (labled L)
void setup()
{
pinMode(sensorDigitalPin, INPUT); // Define pin 3 as an input port, to accept digital input
pinMode(Led13, OUTPUT); // Define LED13 as an output port, to indicate digital trigger reached
myservo.attach(servoPin); // attach the servo to our servo object
myservo.write(0);
}
void loop() {
digitalValue = digitalRead(sensorDigitalPin); // Read the value of the digital interface 3 assigned to digitalValue
if (digitalValue == HIGH) // When the Sound Sensor sends signal, via voltage present, light LED13 (L)
{
unsigned long startTime = millis();
while (millis() - startTime < 80000ul)
{
// scan from 0 to 180 degrees
for (angle = 0; angle < 180; angle++)
{
myservo.write(angle);
delay(15);
}
// now scan back from 180 to 0 degrees
for (angle = 180; angle > 0; angle--)
{
myservo.write(angle);
delay(15);
}
}
}
else
{
myservo.write(0); // stop the motor
}
}`
Thanks for your quick reply and advise. I tried your solution, but could not get the servo to stop. I would appreciate if you can take a look at the code and let me know what I did wrong as I am very new at this.
// Include the library
#include <Servo.h>
// Create the servo object
#define servoPin 9
Servo myservo;
// Create a variable to store the servo position:
int angle = 0;
int sensorDigitalPin = 3; // Select the Arduino input pin to accept the Sound Sensor's digital output
int digitalValue; // Define variable to store the digital value coming from the Sound Sensor
int Led13 = 13; // Define LED port; this is the LED built in to the Arduino (labled L)
long timeOfLastSweep = 0;
long extraTime = 1000 * 60 * 1; // millisec in second * sec in min * minutes of extra sweep
void setup()
{
pinMode(sensorDigitalPin, INPUT); // Define pin 3 as an input port, to accept digital input
pinMode(Led13, OUTPUT); // Define LED13 as an output port, to indicate digital trigger reached
myservo.attach(servoPin); // attach the servo to our servo object
myservo.write(0);
}
void loop() {
digitalValue = digitalRead(sensorDigitalPin); // Read the value of the digital interface 3 assigned to digitalValue
if (digitalValue == HIGH) // When the Sound Sensor sends signal, via voltage present, light LED13 (L)
{
timeOfLastSweep = millis();
{
// scan from 0 to 180 degrees
for (angle = 0; angle < 180; angle++)
{
myservo.write(angle);
delay(15);
}
// now scan back from 180 to 0 degrees
for (angle = 180; angle > 0; angle--)
{
myservo.write(angle);
delay(15);
}
}
}
if (digitalValue == LOW) {
if (millis() - timeOfLastSweep < extraTime)
{
// scan from 0 to 180 degrees
for (angle = 0; angle < 180; angle++)
{
myservo.write(angle);
delay(15);
}
// now scan back from 180 to 0 degrees
for (angle = 180; angle > 0; angle--)
{
myservo.write(angle);
delay(15);
}
}
else
{
myservo.write(0); // stop the motor
}
}
}
Hi,
sorry about not getting back to you sooner. Was out of town.
I looked at your code and reviewed why the servo was not stopping: the extra sweep time had to be folded into the part where the servo is first checked and activated.
I also created a simple function called servoSweep. Please look at it first: you will find that it is simply your code for sweeping back and forth once only. It is declared at the beginning and the definition is at the end. The Arduino IDE does not require the declaration but I find it a good C++ habit to get into. Other IDEs will not allow a function to be used before declaration.
I also don't have access to the sensor you are using, so I did INPUT_PULLUP for the sensor pin and used a push button for testing purposes, which of course means that HIGH and LOW had to be swapped.
I also threw in a bunch of print statements.
Something I have not fixed is that only when the program first starts, the sweep for 1 minute activates even if the push-button is not pressed. I will leave that up to you to see if you can fix that, if needed.
Hope this helps. Please let us know.
// Include the library
#include <Servo.h>
#define servoPin 9
Servo myservo; // Create the servo object
int angle = 0; // Create a variable to store the servo position:
int sensorDigitalPin = 3; // Select the Arduino input pin to accept the Sound Sensor's digital output
int digitalValue; // Define variable to store the digital value coming from the Sound Sensor
int Led13 = 13; // Define LED port; this is the LED built in to the Arduino (labled L)
long timeOfLastSweep = 0;
long extraTime = 1000 * 60 * 1; // millisec in second * sec in min * minutes of extra sweep
void servoSweep(); // declare the servoSweep function
void setup() {
pinMode(sensorDigitalPin, INPUT_PULLUP); // Define pin 3 as an input port, to accept digital input
pinMode(Led13, OUTPUT); // Define LED13 as an output port, to indicate digital trigger reached
myservo.attach(servoPin); // attach the servo to our servo object
myservo.write(0);
Serial.begin(115200);
}
void loop() {
digitalValue = digitalRead(sensorDigitalPin); // Read the value of the digital interface 3 assigned to digitalValue
Serial.print("digitalValue in low: ");
Serial.println(digitalValue);
if (digitalValue == LOW) // When the Sound Sensor sends signal, via voltage present, light LED13 (L)
{
Serial.print("Time of Last Sweep in low: ");
Serial.println(timeOfLastSweep);
servoSweep();
timeOfLastSweep = millis();
}
if (digitalValue == HIGH) {
Serial.print("Time of Last Sweep in high: ");
Serial.println(timeOfLastSweep);
if (millis() - timeOfLastSweep < extraTime) {
Serial.print("Difference betwenn millis and last sweep time: ");
Serial.println(millis()-timeOfLastSweep);
Serial.println();
servoSweep();
}
else {
myservo.write(0); // stop the motor
}
}
}
void servoSweep(){
for (angle = 0; angle < 180; angle++) {
myservo.write(angle);
delay(15);
}
for (angle = 180; angle > 0; angle--) { // now scan back from 180 to 0 degrees
myservo.write(angle);
delay(15);
}
}
Thanks for taking time to evaluate my code. It is greatly appreciated.
I have run your code with sound sensor. Servo start moving as soon as the code is uploaded and do not stop. Also, it never triggers the (digitalValue == HIGH) even when the LED is active.
If I take the servoSweep(); command out of the following section, servo do not start at the beginning and reacts to sound. However, it stops after one sweep and sweep one time again when sound is detected
if (digitalValue == LOW) // When the Sound Sensor sends signal, via voltage present, light LED13 (L)
{
Serial.print("Time of Last Sweep in low: ");
Serial.println(timeOfLastSweep);
servoSweep();
serial monitor:
17:33:02.532 -> digitalValue in low: 0
17:33:02.532 -> Time of Last Sweep in low: 0
17:33:07.961 -> digitalValue in low: 0
17:33:07.961 -> Time of Last Sweep in low: 5421
17:33:13.420 -> digitalValue in low: 0
17:33:13.420 -> Time of Last Sweep in low: 10842
17:33:18.844 -> digitalValue in low: 0
17:33:18.844 -> Time of Last Sweep in low: 16264
17:33:24.247 -> digitalValue in low: 0
17:33:24.247 -> Time of Last Sweep in low: 21685
17:33:29.685 -> digitalValue in low: 0
17:33:29.685 -> Time of Last Sweep in low: 27107
17:33:35.109 -> digitalValue in low: 0
17:33:35.109 -> Time of Last Sweep in low: 32528
17:33:40.530 -> digitalValue in low: 0
17:33:40.530 -> Time of Last Sweep in low: 37950
17:33:45.978 -> digitalValue in low: 0
17:33:45.978 -> Time of Last Sweep in low: 43371
17:33:51.376 -> digitalValue in low: 0
17:33:51.376 -> Time of Last Sweep in low: 48793
17:33:56.796 -> digitalValue in low: 0
17:33:56.796 -> Time of Last Sweep in low: 54214
17:34:02.236 -> digitalValue in low: 0
17:34:02.236 -> Time of Last Sweep in low: 59636
17:34:07.658 -> digitalValue in low: 0
17:34:07.658 -> Time of Last Sweep in low: 65057
17:34:13.072 -> digitalValue in low: 0
17:34:13.072 -> Time of Last Sweep in low: 70478
Here is a suggestion for keeping the servo from doing a sweep at the start:
long extraTime = 1000 * 60 * 1; // millisec in second * sec in min * minutes of extra sweep
long timeOfLastSweep = extraTime;
I just ran the code again and it seems to work.
Remember, I am using a pull-up resistor and a button.
So, my logic is opposite. Is your sensor HIGH when active? If so, please reverse the logic in my code.