I'm trying to control a servo based on the analog values from a sound sensor. The idea is that when the sound sensor senses a spike in volume (i.e. the analag values jump), then the servo will move to a position. The problem is that when the servo is energized the sensor values go crazy. I'm using an arduino nano with a Tower Pro SG90 micro servo. The servo is being powered by the arduino 5V pin. My guess is that when the servo draws power from the arduino the voltage to the sound sensor changes. I know this can be fixed by providing a seperate voltage source to the servo, however for my design I need the arduino to power both the servo and the sensor. Has anyone ran into an issue like this before? I'm thinking I can fix the issue by interrupting the analogread() from the sensor when the servo is called to run, but I'm not sure how to do this.
It is never a good idea to power a servo from an Arduino. If it works, fine, but it often does not work.
Also, the sensor may "hear" the servo.
You may be able to sort some of this out by temporarily using another power source for the servo. Of course, connect the ground of the power source to the ground of the Arduino.
Also, do not "listen" if the servo is moving. Your code causes the servo to move so your code "knows" when to stop "listening". Your code may start "listening" again after some time (millis()) has passed.
Thank you for the reply. The sound of the srvo is not affecting the sensor. I'm calculating a range of the analog values based on the previous reading and the current reading. I'm setting a limit for when to do something based on the range, the sound of the servo is well under the range limit
Do you have an idea of how to stop reading in the values from the sensor? My first idea was to put the analogread() function inside a while loop with the condition being that the analog levels are under the range, however I don't think that is the best way of doing it.
Here is an untested solution. It assumes that you have some coding experience.
Declare a flag as boolean ahead of setup() and loop(), and ensure that setup() initializes the flag to false. Perhaps the flag is called skipSoundSensor.
In this same place, put the following:
unsigned long startMillis; //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 1000; //the value is a number of milliseconds
//
// The value of period (in milliseconds) needs to be longer than the time that the servo takes
// to make its longest move, but not so long that it prevents for too long the listening for sounds.
//
In loop(), do not read the sound sensor or do anything dependent upon the sound sensor unless the flag is false. This will need an "if" statement with squiggly brackets "{" and "}".
If you detect a loud enough sound, set the flag to true and get the time:
skipSoundSensor = true ;
startMillis = millis() ; //IMPORTANT to save the start time of the current loud sound.
In loop(), ensure that you have this:
currentMillis = millis(); //get the current "time" (actually the number of milliseconds since the program started)
if (currentMillis - startMillis >= period) //test whether the period has elapsed so it is time to pay attention to the sensor again.
{
skipSoundSensor = false ;
}
scottyaguas:
Thank you for the reply. The sound of the srvo is not affecting the sensor. I'm calculating a range of the analog values based on the previous reading and the current reading. I'm setting a limit for when to do something based on the range, the sound of the servo is well under the range limit
Do you have an idea of how to stop reading in the values from the sensor? My first idea was to put the analogread() function inside a while loop with the condition being that the analog levels are under the range, however I don't think that is the best way of doing it.
Sound levels may add, so take the servo noise into consideration.
scottyaguas:
My guess is that when the servo draws power from the arduino the voltage to the sound sensor changes. I know this can be fixed by providing a seperate voltage source to the servo
I think I'd first try running the servo off a separate power supply (common Ground with Arduino) just to test this theory.