Asked — Edited

Sound Sensors

Hey Everyone!

I am currently stuck on how to code these 2 sound sensors (1 on left, 1 on the right)(picture below) on the head of my robot. I have a servo (D18) that goes up to 180 degrees and I want the head to turn towards the loudest noise level. I have looked at some examples and I still dont have any progress.

Any help would be appreciated

Thanks,

Cameron

User-inserted image


ARC Pro

Upgrade to ARC Pro

ARC Pro is more than a tool; it's a creative playground for robot enthusiasts, where you can turn your wildest ideas into reality.

#17  

Something else that I would do is break this into two scripts. The reason for this is that the first script would monitor sound and be able to loop more in its own thread. The second one would handle the head movement. I will give you an example shortly.

#18  

Here's a script that I've used and it works pretty good. I don't remember who originally posted it but it's not my work. Adjust the values to tune it into your sensors as well as the ADC ports to match yours.


$Direction=0
$L=0
$R=0

:loop

repeat($x,0,2,1)

# I multiplied the readings by 85 for both sensors

$Left=GetADC(adc1)*85    #adjust this value
$Left_T=$Left+$L
$L=$Left_T

$Right=GetADC(adc2)*85  #adjust this value
$Right_T=$Right+$R
$R=$Right_T

Sleep(1000)

endrepeat

$Direction=$Left_T-$Right_T

if($Direction>300)
SayEZB("left")
# put servo movement in here
Sleep(1800)
$Direction=0
$Left_T=0
$L=0

Elseif($Direction<-300) 
SayEZB("Right")
# put servo movement in here
Sleep(1800)
$Direction=0
$Right_T=0
$R=0

endif

$Left_T=0
$Right_T=0
$L=0
$R=0

Goto(loop)

#19  

It did move to the right. and I did add the Variable Watcher;.

#20  

In the second script, I would do something like this...


if($moveHead = "Right")
    Servo(D18,1)
    sleep(2000)
endif

if($moveHead = "Left")
    Servo(D18,180)
    sleep(2000)
endif

Servo(D18,90)
sleep(1000)

In the first script I would do something like


servo(D18,90)
:top
  #$LevelLeft = GetADC(adc0)
  #$LevelRight = GetADC(adc1)
  $LevelLeft = GetADC(adc0) * 100
  $LevelRight = GetADC(adc0) * 100
  $moveHead = "Center"


  if($LevelLeft > 500 or $LevelRight > 500)
    if($LevelLeft > $LevelRight)
      $moveHead = "Left"
    else
      $moveHead = "Right"
    endif
  endif

  ControlCommand("move head", ScriptStart)
  Sleep(3000)
goto(top)

#21  

uncomment out the 3rd and 4th line and then comment out the 5th and 6th line in the second script listed above.

What are the values that are being seen in the variable watcher when this runs?

#22  

Just saw a mistake in the script and fixed it. You might have to change the servo value for left and right in the first script, and then also adjust the values in the if($LevelLeft>500 or $LevelRight>500) to be lower, but you will have to test and see what values you are getting in the Variable Watcher.

#23  

I put those you posted in 2 seperate ones. And only one will last a few seconds. Is that right? Or shoupd they both stay on? Both values are over 12,000

#24  

1 will just run for 3 seconds to move the servo. The other one will run in the loop to read the sensor. The sensor one will stay running.

Now you just need to modify the multipliers and the 500's to be what works for you.

Why do I do it this way? I am glad you asked:)

This will let you test the motor movement by itself. Once you know the motors move like you want it to, you can quit messing with it and know it will work. You can also reuse this script for other sensors added later if you want to.

The sensor reading script can be tested without calling the servo script. Once that one works as you expect, you dont have to worry about it anymore and can reuse it if you want to.

I try to make my scripts do one thing only to eliminate extra stuff in a script that makes it difficult to change or modify in the future.