This demo shows a hunting spider that moves up and down depending on the receiving sound pitch. The spider has pliers at the front which controlled by two servos to grab hunting target. There is a motor on the ceiling that rolls the spider up and down. A microphone receiver is on the ground to receive the sound signal. As the pitch goes up, the spider moves up slowly. The spider moves downward as the pitch goes down. When the spider drops to a certain low enough position, it enters hunting mode and tries to use the pliers to grab the target.

CAD: spider..SLDPRT

</pre>
#include "arduinoFFT.h"
#include <Servo.h>

#define SERVO_A 2
#define SERVO_B 3
Servo servoA;
Servo servoB;

//Motor control macro definitions
#define MOT_A1_PIN 5
#define MOT_A2_PIN 6
#define UP 255
#define DOWN -255
#define STOP 0

#define THRESHOLD 20
#define STEP 20

//Frequency sampling macro definitions
#define SAMPLES 128 //Must be a power of 2
#define SAMPLING_FREQUENCY 5000 //Hz, must be less than 10000 due to ADC

arduinoFFT FFT = arduinoFFT();

unsigned int sampling_period_us;
unsigned long microseconds;

double vReal[SAMPLES];
double vImag[SAMPLES];
int curr_pos = 0;

void setup(void)
{
Serial.begin(9600);

servoA.attach(SERVO_A);
servoB.attach(SERVO_B);

pinMode(MOT_A1_PIN, OUTPUT);
pinMode(MOT_A2_PIN, OUTPUT);

digitalWrite(MOT_A1_PIN, LOW);
digitalWrite(MOT_A2_PIN, LOW);

sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
}

void reel_in_dir(int dir)
{
if (dir < 0) { //reel down
analogWrite(MOT_A1_PIN, -dir);
digitalWrite(MOT_A2_PIN, LOW);
curr_pos -= STEP + 2;
}
else if (dir > 0) { //reel up
digitalWrite(MOT_A1_PIN, LOW);
analogWrite(MOT_A2_PIN, dir);
curr_pos +=STEP;
}
else { //stop
digitalWrite(MOT_A1_PIN, LOW);
digitalWrite(MOT_A2_PIN, LOW);
}
delay(5);
}

void loop(void)
{
int target_pos = (int)sample();
if (target_pos>200){

Serial.print(target_pos);
Serial.print(" | ");
Serial.println(curr_pos);

if (curr_pos < target_pos - THRESHOLD){
reel_in_dir(UP);
}
else if (curr_pos > target_pos + THRESHOLD){
reel_in_dir(DOWN);
}
else {
reel_in_dir(STOP);
}
}

else{
Serial.println(target_pos);
servoB.write(70);
delay(2000);
//for (int i = 0; i < 5; i++) reel_in_dir(UP);
reel_in_dir(STOP);
delay(1000);
servoB.write(0);
delay(2000);
servoB.write(170);
}

}

double sample(void){
for(int i=0; i<SAMPLES; i++)
{
microseconds = micros(); //Overflows after around 70 minutes!
vReal[i] = analogRead(0);
vImag[i] = 0;

while(micros() < (microseconds + sampling_period_us)){
}
}

FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);
return peak;
}
<pre>