Use a KY-037 4pin Voice Sound Detection Sensor Module to control a servo ?

Hello,

Is it possible to use a sound detection module to control one or multiple
SG90 servo angles ?

If yes, please give some solutions.

Thanks.

The answer is yes. What have you tried ?

Sorry for my late reply due to flu.

I've tried the following code :

#include <Servo.h> 
Servo servo1;
Servo servo2;
int grado;
int sensorValue; 
// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  servo1.attach(2);
  servo2.attach(3);
  
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  sensorValue = analogRead(A0); 
  // print out the value you read:
  grado = sensorValue/5,68;
  Serial.println(sensorValue);
  if(sensorValue > 100){
    servo1.write(grado+100);
    servo2.write(grado+100);
    delay(3);
    
  }
 
  if(5 < sensorValue < 100){
    servo1.write(grado+10);
    servo2.write(grado+10);
    delay(3);
    
  }
  
}

But my servo just moves REAL fast to arbitrary positions even if there is is NO sound.

I tried serial writing of " sensorValue " (pin A0) in the void setup , just to test, but every time I get a random value with same conditions i.e. No sound.

I tried a new sketch as follows while powering the servo from a different power source and not Arduino
after adjusting the sensor to the right threshold (led blinks correctly with sound)

#include <Servo.h>
Servo MyServo;
int ServoPin = 9;
void setup() {
Serial.begin(115200);
MyServo.attach(ServoPin);
}
void loop() {
int sensorValue = analogRead(0);
Serial.println(sensorValue);
sensorValue = map(sensorValue,0,1023,0,180);
analogWrite(9, sensorValue);   
}

But no servo movement, just a little jitter

Appreciate your help.

What do you see when printing sensorValue in the second program ?

I see [000[000[000. ........ running across .

where am I goofing up ?

How is the pot wired ?
Check it then check it again.

Do you really get [ in the output ?
Print a text label and a delimiter before and after sensorValue.

Serial.print("sensorValue >");
Serial.print(sensorValue);
Serial.println("<");

Do you see the label in the output ?
Are you sure that the Serial monitor is set to 115200 baud ?

Thank you.

ok I really goofed up ! Sorry, my bad.

Serial monitor was NOT set to 115200 baud. I change that and now I see numbers, not junk.

But all the numbers are in the range of 500's (about 527 - 535) .
Changing the music volume effects the led on the module but has little effect on the numbers,
and the servo just jitters.

all the numbers are in the range of 500's (about 527 - 535) .

Then you map() a range of 0 to 1023 to a range of 0 to 180 so after the map() the value will vary very little. Try printing it to see what is being written to the servo. If anything you need to expand the value rather than compress it but if you are receiving only about 10 different values then the best you could achieve is an output of one of 10 positions

" Then you map() a range of 0 to 1023 to a range of 0 to 180 ..." ?? Sorry Bob, I'm lost. Pls explain.

If I print the values after the servo.write I get 88-94.

" Then you map() a range of 0 to 1023 to a range of 0 to 180 ..." ?? Sorry Bob, I'm lost. Pls explain.

sensorValue = map(sensorValue,0,1023,0,180);

This says "expect a value between 0 and 1023 and turn it proportionally into a value between 0 and 180" So, if you get a value of say 512 it will output a value of 90. As it is you get an input value of between 527 and 535 so the output will be proportional to that. An input of 527 will cause this calculation 527/1023 * 180 and 535, 535/1023 * 180

If I print the values after the servo.write I get 88-94.

Very close to the results of the calculations above. So the most that the servo will move is about 6 degrees

Thanks agin. Well explained.

Can I find a remedy to 6 degrees ? Anyway to go more degrees ?
Multiply the degree by a number ? Stupid question ?

I've tried to look around in the Internet but can't find anything.

If the analogue input only varies by say 10 from lowest to highest then you can only ever discriminate between 10 servo positions. No amount of manipulation of the value is going to alter that. Would 10 different servo positions be acceptable ? If so, then there is a neat way to turn the 10 values into corresponding servo angles between 0 and 180 degrees using an array but how fast does the value change ?

Bob,

The values change real fast.

Following your suggestion, I inserted 2 arrays in my code.
"Rcvd" with the values I receive after mapping and "Pos" with corresponding degrees.

It works as long as the serial print is concerned i.e. it prints 30,90,0, 120 etc. but
servo just jitters.

I've tripled checked my wiring and looks ok.

#include <Servo.h>

Servo MyServo;

int ServoPin = 9;
int sensorValue;
int Rcvd[] = {88, 89, 90, 91, 92, 93, 94};
int Pos[] = {0, 30, 60, 90, 120, 150, 180};
int n;

void setup() {
  Serial.begin(115200);
  MyServo.attach(ServoPin);

}
void loop() {

  sensorValue = analogRead(0);
  sensorValue = map(sensorValue, 0, 1023, 0, 180);

  for (n = 0; n < 7; n++) {

    if (sensorValue = Rcvd[n]) {
     MyServo.write(Pos[n]);
    
      Serial.println(Pos[n]);
    }

  }

}

I'd be happy with these 7 positions if it works.

The values change real fast.

servo just jitters.

No surprise there. If the values change fast then the servo position will change fast but it will not have time to get to its target position before getting a new, different position to move to. and so on

What were you hoping would happen ? Louder noise equals larger servo movement perhaps ?
Is the output of the sound module ever stable or is it constantly changing ?

You could read the input over a period of time, determine the highest value received in that period, use the value to move the servo then ignore the input for a while before repeating the process

Bob, Thanks again for bearing with me.

Ok, I understand that my servo " will not have time to get to its target position before getting a new, different position to move to..../i].
" What were you hoping would happen ? Louder noise equals larger servo movement perhaps ?/i]
that would at least be a start, since I don't know how to or if it's possible to make sound analysis with Arduino.
To test my code better, I tried slowing down the serial print and the serial read with a delay.
I think there's a flaw in my following code.
i.e. if sensorValue is = 93 (index position n = 5 in array Rcvd then arrayPos[5] should be 150.
Instead for any sensor value it keeps printing 0,30,60,90,120,150,180 and not just the value corresponding to the index.
Why ?
```
*#include <Servo.h>

Servo MyServo;

int ServoPin = 9;
int sensorValue;
int Rcvd[] = {88, 89, 90, 91, 92, 93, 94};
int Pos[] = {0, 30, 60, 90, 120, 150, 180};
int n;

void setup() {
  Serial.begin(115200);
  MyServo.attach(ServoPin);

}
void loop() {

sensorValue = analogRead(0);
  sensorValue = map(sensorValue, 0, 1023, 0, 180);

Serial.println(String("sensorValue = ") + sensorValue);

for (n = 0; n < 7; n++) {

if (sensorValue = Rcvd[n]) {
      MyServo.write(Pos[n]);

Serial.println(String("Pos = ") + Pos[n]);

delay(1000);
    }

}

}
_
```*_

Why ?

    if (sensorValue = Rcvd[n])

That's why
= for assignment
== for comparison

"And yet it moves" Galileo Galilei.

Thanks Bob, my bad again.

Now with a delay of 50 works ok with music.
The only problem is that it keeps
moving even if the music is turned off.
Picking up some noise from A0 ?

I've got to find a way to stop the servo when there's no music
maybe by finding the right threshold.

What values do you see for the raw sensorValue when no music is playing ?

When no music, values after mapping, are 82 to 92.
And that's no good if those are assigned to music play.

Don't understand where those values come from when there's silence.