Hey guys, I’m attempting to use an MAX9814 microphone, an arduino uno r3, a L293D motor driver and dc motor to detect a frequency and then start a motor for a given amount of time. With the image of the setup and following code below I’ve been able to pick up noise and implement the goertzel algorithm to isolate the desired frequency of the tuning fork I’ve been using. However I’ve found that this process is rather inconsistent in loud environments which I need it to operate in, upwards of 90dB. False positives where the magnitude threshold has been met by things other than the tuning fork have been happening frequently. Also it seems like the tuning fork gets drowned out sometimes. It also is affected by crashes around it so advice on how to mount it to reduce this would also be helpful.
Overall I’m looking for any suggestions on
Code improvements
Tuning fork amplification
Noise reduction of environment
Proper mounting of microphone
Possible use of resonance?
Anything else you think may be useful
Thanks!
#include <Arduino.h>
// Motor driver pins
#define ENA 5 // PWM speed control (L293D)
#define IN1 9 // Motor direction control
#define IN2 10 // Motor direction control
// Microphone input pin
#define MIC_PIN A0
// Frequency detection settings
const float targetFreq = 506.5; // Change this to your desired frequency (e.g., 293.66 Hz for D4)
const int sampleRate = 9000; // Sampling rate in Hz (must be at least 2x target frequency)
const int numSamples = 100; // Number of samples (adjust for accuracy)
const int motorRunTime = 3000; // Motor run time in milliseconds (2 seconds)
const int detectionThreshold = 3000; // Magnitude threshold for detection
// Noise Filtering Settings
const int noiseThreshold = 200; // Ignore low-magnitude signals
// Function to run Goertzel algorithm for frequency detection
float detectFrequency(float targetFrequency) {
float coeff, q0, q1, q2, magnitude;
float omega = (2.0 * PI * targetFrequency) / sampleRate;
coeff = 2.0 * cos(omega);
q1 = 0;
q2 = 0;
for (int i = 0; i < numSamples; i++) {
int sample = analogRead(MIC_PIN) - 512; // Normalize around 0
if (abs(sample) < noiseThreshold) continue; // Ignore weak signals
q0 = coeff * q1 - q2 + sample;
q2 = q1;
q1 = q0;
}
magnitude = sqrt(q1 * q1 + q2 * q2 - q1 * q2 * coeff);
return magnitude;
}
// Function to turn the motor on
void turnMotorOn() {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(ENA, 200); // Set motor speed (0-255)
}
// Function to turn the motor off
void turnMotorOff() {
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}
void setup() {
pinMode(ENA, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
Serial.begin(9600);
}
void loop() {
float magnitude = detectFrequency(targetFreq);
Serial.print("Detected Magnitude: ");
Serial.println(magnitude);
if (magnitude > detectionThreshold) {
Serial.println("Frequency detected! Turning on motor.");
turnMotorOn();
delay(motorRunTime);
turnMotorOff();
Serial.println("Motor off.");
}
delay(200); // Small delay to avoid constant triggering
}

