voice activated switch & timer.h library

Hello,
I’m looking to make a simple voice activated mobile for my new son or daughter (too early to know yet). I recently came across an Arduino Uno Rev. 3 someone had tossed, so I figured I would put it to better use than landfill filler. Everything works fine on the board. So far I’ve put together a sketch using Simon Monk’s Timer.h library (below), and wired the components (jpg attached).

Circuit components:
(Circuit layout attached)
Electret mic/amplifier connected to A0, GND & 3.3VDC
Crydom ODC5 solid state relay enabled via digital pin 9
5VDC power supply for DC motor

What I expect to happen:
Arduino monitors the signal on A0. When signal level exceeds predefined threshold, a DC motor is immediately enabled for x amount of time. When time has elapsed, DC motor is disabled and Arduino continues to monitor signal on A0.

What actually happens:
Arduino monitors the signal on A0 just fine. However, when the signal level exceeds the predefined threshold, the DC motor is not immediately enabled. Instead, the motor is enabled after x amount of time, then shuts off.
Functionally this is fine for short periods of time. Practically though if I choose to set the time to say 10 minutes, it just wouldn’t work. I’ve experimented with the HIGH/LOW arguments in the pulse function and threshold levels with no affect. It’s certainly possible I am not using the library correctly. If someone could please review the code and make some suggestions it would be greatly appreciated!

#include "Timer.h"

const int buffer_size = 10;
const int threshold = 25;
int noises[buffer_size];
int cur_index = 0;
int microphone_pin = 0;
int motorPin = 9;
int range = 0;
 
// instance of Timer object
Timer t;

void setup() {
	Serial.begin(9600);
	// every 200ms, call levelCheck function 
	t.every(200, levelCheck);
	// set digitial pin 9 as output
	pinMode(motorPin, OUTPUT);
}

void loop() {
	// read the value from the sensor:
	noises[cur_index] = analogRead(microphone_pin);
	cur_index = (cur_index + 1) % buffer_size;
	range = find_range(noises, buffer_size);
	Serial.print(range);
	Serial.print("   ~    ");
	Serial.println(noises[cur_index]);
	delay(200);
	t.update();
}
// find_range function
int find_range(int* array, int length){
	int minimum = array[0];
	int maximum = array[0];
	for (int i = 1; i < length; i++){
		if (array[i] < minimum) minimum = array[i];
		if (array[i] > maximum) maximum = array[i];
	}
	return maximum - minimum;
}
// levelCheck function
void levelCheck(){
	if (range > threshold){
		t.pulse(motorPin, 10000, LOW);
	}

}

Hi jcj8166

void levelCheck(){
    if (range > threshold){
        t.pulse(motorPin, 10000, LOW);
    }
}

There may be problems with repeat calls to t.pulse() once the pulse has started (which will happen if the sound level stays above the threshold).

Maybe change levelCheck to be like this:

void levelCheck(){
    if (!motorRunning && (range > threshold)) {
                digitalWrite(motorPin, //the value to start it//);
                motorRunning = true;
        t.after(10000, stopMotor);
    }
}

Then add a callback to stop the motor:

void stopMotor(){
     digitalWrite(motorPin, //the value to stop it//);
     motorRunning = false;
}

And declare motorRunning as a global boolean variable.

Regards

Ray

Ray, Thanks for the feedback. So it looks as though t.pulse() may not work as I has initially expected it to. I'll try this out tonight. Thank you very much. John