1

I'm trying to code the pan and tilt bracket to turn based on where I speak, I know how to move the servo motors, but I really need help with the sound sensing. This is the code I've got currently:

#include <Servo.h> 
Servo myservo;  // create servo object to control a servo
     Servo myservo2;           // a maximum of eight servo objects can be created
int sound1;
int sound2;
int pos = 0;    // variable to store the servo position

void setup()
{
  Serial.begin(9600);
  myservo.attach(5);  // attaches the servo on pin 9 to the servo object
  myservo2.attach(6);
}


void loop()
{
  sound1 = analogRead(A0); 
  sound2 = digitalRead(7); 


  if (sound1 > 50)
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
  {                               
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }

   if (sound2 > 50)
   for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees
  {                                  // in steps of 1 degree
    myservo2.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees
  {                               
    myservo2.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

I've been working on this for some time, but for some reason, whenever I try to code the sound sensor, it always ends up being ignored, so for example, If my code says, if sound sensor number 1 detects sound, move 90 degrees vertically or horizontally, it always ignores that if statement and just continuously moves 90 degrees to wherever. I need it to follow my voice, or if that's too advanced, it's fine if it just follows any sound. So if I more 30 degree to the right on the pan and tilt bracket, and speak, I need it to turn and face me. Also, the kind of sound sensor I'm using is KY-037, the red variation with 4 pins. Any advice would be really helpful, thanks.

1
  • 1
    Why do you use digitalRead() for sound2? It will return only 0 or 1. So if(sound2 > 50) will never be true. Also currently your code tells the servo to move 180 degrees back and forth. Nothing with 90° or following you. What sound sensors do you have? I don't quite understand what you want to achieve. Do you want the servos to follow you linearily (so for example moving to 30° when you talk from 30°)? Or do you want it to change between 2 positions? What should happen if both sensors detect a loud enough sound?
    – chrisl
    Mar 19, 2022 at 11:40

1 Answer 1

4

What you are trying to achieve is not easy. Expect to spend a lot of time developing, testing and tuning it.

The first step would be to work the acoustics of your device. The sound sensors are not sensitive to the direction of the incoming sound, so you will to have to use two of them facing different directions, like the ears on your head face different sides. It would help to have the polar plot of your microphones: if they are not directional enough, you may have to build some kind of sound obstacle between them (the “head” between the ears, or maybe even a pair of “auricles”) to improve the angular selectivity. With cardioid microphones, you may get away with just facing them 180° apart.

Getting this right can take significant effort. A two-channel oscilloscope and a sinusoidal sound source would help a lot: watch the signals coming out of both mikes, and see how their amplitudes change as you turn the head. You want them to be sensitive enough to that orientation. Then, adjust the potentiometers within the sound modules in order to have the same amplitudes when the head is facing the sound source.

Next you will have to sample these signals with your Arduino. The default Arduino sampling rate (analogRead() in a tight loop) is about 8.93 kHz for a single channel, or 4.46 kHz per channel if alternating between two channels. This may be enough for getting a rough estimate of the intensity of voice, but it is kind of borderline too low. You may want to increase the sampling rate: the way to do so has been discussed here, and is only a search away.

With analogRead(), the sampling rate is also inconsistent and dependent on what the sketch is doing: the more the CPU works, the slower the sampling rate. I would strongly recommend letting the ADC work in free running mode, and retrieve the samples from an interrupt service routine. For this, you will have to first read and understand the chapter on the ADC from the datasheet of the microcontroller.

Next, you have to estimate the intensities from the samples you read. In principle, this means low-pass filtering the square of the AC part of the signal. If that is too much work, you may get away with a simple peak-detection.

You may want to take a look at this sound-meter sketch for inspiration. It uses the free-running ADC technique and estimates a sound amplitude using the proper “low-pass filtering the square of the AC part of the signal”. It is single channel though, and you will have to adapt it for tracking two channels. This would involve changing the multiplexer setting within the ISR.

Lastly, you will have to make the pan servo respond to the difference in intensities between the two ears. That is the easy part, it could roughly go like this:

void loop() {
    float intensity_right = get_sound_intensity(RIGHT_MIKE);
    float intensity_left = get_sound_intensity(LEFT_MIKE);

    // Only move the head if we actually hear sound.
    if (intensity_right >= intensity_threshold
            || intensity_left >= intensity_threshold) {

        float difference = intensity_right - intensity_left;

        // Only move the head if the intensity difference is
        // significant.
        if (fabs(difference) >= difference_threshold) {
            if (difference > 0 && servo_position < 180) {
                servo_position += 1;
                servo.move(servo_position);
            } else if (difference < 0 && servo_position > 0) {
                servo_position -= 1;
                servo.move(servo_position);
            }
        }
    }
}
7
  • I'm trying to run this code, and "get_sound_intensity" has an error, it says it's not declared in this scope, how to define this? Also, do you have a private email? I want to send you more details about what I'm doing. I need to finish this before 9th April, and I really need an experts help right now
    – Kevin Zefi
    Mar 20, 2022 at 16:42
  • @KevinZefi: Re “how to define [get_sound_intensity]”: most of my answer is about how to define it. Did you go through it? I would rather not give my private e-mail. Mar 20, 2022 at 16:49
  • Ok, the thing with the oscilloscopes, I can't actually use them for the project, my project is a voice tracking camera system, the main objectives of this project is to code the servo motors and to track my voice AND my face, I managed to complete the face tracking. If what I asked for is too advanced then I can just get a simpler code, I need the code to have this kind of logic: If sound reaches sensor 1 first, turn 90 degrees, something like that. I need the project to be portable if that makes sense, I will need to present this to my professors, and I can't hook it up to an O scope.
    – Kevin Zefi
    Mar 20, 2022 at 17:35
  • The end result will be, to create one box which contains everything inside, so I can't have the project depend on hooking it up with oscilloscopes whenever I turn it on. "I would rather not give my private e-mail" Ok, I'm sorry I asked, is there any other way I can send you details of my project?
    – Kevin Zefi
    Mar 20, 2022 at 17:37
  • Also, with the face tracking, I managed to code the servos spin based on where my face is, this was just a hunch, but can I just add the sound sensing variation on to that code?
    – Kevin Zefi
    Mar 20, 2022 at 17:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.