timing not working - speed motor and claps/peaks

Hello,

I have this project.
If arduino finds between 1-3 peaks (claps) in a 400 ms range it will perform an action.
If finds 1 peak, it will start a motor to run at full speed for Y time.
if finds 2 peaks, it will start the same motor to run at speed X for Z time.
if finds 3 peaks, it will start the same motor to run at speed L for P time.

Arduino responds to the peaks and the motor reacts but the motor doesn’t do the correct time. In fact, it doesn’t even stop. If it is at full speed, i can clap twice and it will turn to X speed, for example.

I can’t see what it wrong…

int soundSensor = 2;
int claps = 0;
long detectionSpanInitial = 0;
long detectionSpan = 0;

unsigned long previousMillis = 0;

const long interval1 = 1000;
const long interval2 = 100;
const long interval3 = 200;

void setup() {

pinMode(soundSensor, INPUT);
pinMode(12, OUTPUT); //Initiates Motor Channel A pin

}

void loop() {
unsigned long currentMillis = millis();
int sensorState = digitalRead(soundSensor);

if (sensorState == 0)
{
if (claps == 0)
{
detectionSpanInitial = detectionSpan = millis();
claps++;
}
else if (claps > 0 && millis()-detectionSpan >= 50)
{
detectionSpan = millis();
claps++;
}
}

if (millis()-detectionSpanInitial >= 400)
{
if ((claps == 1) && (currentMillis - previousMillis >= interval1))
{
previousMillis = currentMillis;
digitalWrite(12, HIGH); //Establishes forward direction
digitalWrite(9, LOW); //Disengage the Brake
analogWrite(3, 255); //Spins the motor at full speed

}
else if ((claps == 2) && (currentMillis - previousMillis >= interval2))
{
previousMillis = currentMillis;
digitalWrite(12, HIGH);
digitalWrite(9, LOW);
analogWrite(3, 125);
}
else if ((claps == 3) && (currentMillis - previousMillis >= interval3))
{
previousMillis = currentMillis;
digitalWrite(12, HIGH);
digitalWrite(9, LOW);
analogWrite(3, 70);
}
claps = 0;
}
}

detectionSpanInitial = detectionSpan = millis();
Does this look right?

dectectionSpan should be ‘unsigned long’
.

Hi,

Please read the first post in any forum entitled how to use this forum. http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code. It will be formatted in a scrolling window that makes it easier to read.

Thanks.. Tom.. :)

then look down to item #7 about how to post your code.

Use Tools + Auto Format first, to fix that piss-poor indenting.

      detectionSpan = millis();

Span hardly makes sense in the name of a variable that holds a discrete time. Some meaningful names, and proper indenting, will go a long ways towards pointing out the problem.

Hello again, thank you for your commentaries.

I managed to make the timing right as i wanted it. 1 clap/peak and the dc motor works for x seconds.. 2 claps/peaks and it works for y seconds..

however, now i want it to start another function if it is in the middle of a action. For example, the motor is running for x seconds due to 1 clap/peak. In the middle of the x seconds, 2 claps/peaks happen and the motor must start the 2 clap/peak function. I thought with millis() it would be enough, no? Ideas? thank you :)

int soundSensor = 2;
int claps = 0;
long detectionRangeInitial = 0;
long detectionRange = 0;

unsigned long previousMillis = 0;        // will store last time LED was updated

const long interval1 = 10000;
const long interval2 = 15000;
const long interval3 = 5000;

boolean motorRunning = false;
boolean motorRunning2 = false;
boolean motorRunning3 = false;

void setup() {
  pinMode(soundSensor, INPUT);
  pinMode(12, OUTPUT); //Initiates Motor Channel A pin
}

void loop() {
  
  unsigned long currentMillis = millis();
  int sensorState = digitalRead(soundSensor);

  if (sensorState == 0)
  {
    if (claps == 0)
    {
      detectionRangeInitial = detectionRange = millis();
      claps++;
    }
    else if (claps > 0 && millis() - detectionRange >= 50)
    {
      detectionRange = millis();
      claps++;
    }
  }

  if (millis() - detectionRangeInitial >= 400)
  {
    if ((claps == 1) && (currentMillis - previousMillis >= interval1))
    {
      previousMillis = currentMillis;
      motorRunning = true;
      digitalWrite(12, HIGH);
      digitalWrite(9, LOW);
      analogWrite(3, 255);   //Spins the motor on Channel A at full speed

    }
    else if ((claps == 2) && (currentMillis - previousMillis >= interval2))
    {
      previousMillis = currentMillis;
      motorRunning2 = true;
      digitalWrite(12, HIGH);
      digitalWrite(9, LOW);
      analogWrite(3, 125);   //Spins the motor on Channel A at full speed
    }
    else  if ((claps == 3) && (currentMillis - previousMillis >= interval3))
    {
      previousMillis = currentMillis;
      motorRunning3 = true;
      digitalWrite(12, HIGH);
      digitalWrite(9, LOW);
      analogWrite(3, 70);
    }
    claps = 0;
  }
  if ( motorRunning && (millis() - previousMillis > interval1) )
  {
    digitalWrite(12, HIGH);
    digitalWrite(9, HIGH);
    analogWrite(3, 0); ;
    motorRunning = false;
  }
  if ( motorRunning2 && (millis() - previousMillis > interval2) )
  {
    digitalWrite(12, HIGH);
    digitalWrite(9, HIGH);
    analogWrite(3, 0); ;
    motorRunning = false;
  }
  if ( motorRunning3 && (millis() - previousMillis > interval3) )
  {
    digitalWrite(12, HIGH);
    digitalWrite(9, HIGH);
    analogWrite(3, 0); ;
    motorRunning = false;
  }
}

however, now i want it to start another function if it is in the middle of a action.

Pretend we don't know what you are talking about. Because, really, we don't. When what is in the middle of what action? What is it that should start another function?

You seem to think that calling a function results in an immediate return, and that that function and loop() continue to execute in parallel. That is NOT what happens.

I thought with millis() it would be enough, no?

It would. You need to separate the clap detection from the act upon the number of claps. Then, you can change the action whenever you detect a different number of claps.

PaulS:
Pretend we don’t know what you are talking about. Because, really, we don’t. When what is in the middle of what action? What is it that should start another function?

i described what i wanted to happen and even i put an example. "however, now i want it to start another function if it is in the middle of a action.
For example, the motor is running for x seconds due to 1 clap/peak. In the middle of the x seconds, 2 claps/peaks happen and the motor must start the 2 clap/peak function."

let me try another aproach. If i clap one time, the motor will run for 15 seconds. However if during those 15 seconds the motor detects 2 claps it will stop his current action and do another action (motor will run for 10 seconds).

PaulS:
It would. You need to separate the clap detection from the act upon the number of claps. Then, you can change the action whenever you detect a different number of claps.

didn’t thought of that, let me see what i can do. Thanks

However if during those 15 seconds the motor detects 2 claps it will stop

Is the motor really capable of detecting claps?

PaulS:
Is the motor really capable of detecting claps?

opps sorry.

I meant " If i clap one time, the motor will run for 15 seconds. However if during those 15 seconds the microphone attached to the ARDUINO detects 2 claps, arduino will make the motor stop his current action and make the motor do another action correspond to the 2 claps (motor will run for 10 seconds).

loly_pt: opps sorry.

I meant " If i clap one time, the motor will run for 15 seconds. However if during those 15 seconds the microphone attached to the ARDUINO detects 2 claps, arduino will make the motor stop his current action and make the motor do another action correspond to the 2 claps (motor will run for 10 seconds).

The microphone can't detect a clap, either. The Arduino is the only thing that can. The reason that I harp on this is that understanding what does what, and being able to clearly define what the requirements are is critical to being able to implement the requirements.

For instance, suppose that the Arduino detects one clap, and starts the motor running. 8 seconds later, it detects two claps. How much longer should the motor run? Two seconds, for a total of 10 seconds? Or ten seconds, because two claps means run the motor for 10 more seconds?

PaulS:
For instance, suppose that the Arduino detects one clap, and starts the motor running. 8 seconds later, it detects two claps. How much longer should the motor run? Two seconds, for a total of 10 seconds? Or ten seconds, because two claps means run the motor for 10 more seconds?

oh ok, sorry, in the future posts i will be more detailed with the parameters.

Answering your questions. When arduino detects two claps he will start the motor running for more ten seconds, because two claps means run the motor for 10 seconds.

I changed the millis() to delay() just to test it out.

The timing parts is gone. If i do 1 clap the motor will just do the correct speed forever. However if i do 2 claps he will do the 2 clap-speed. The same if i do 3 claps. Forever. no stop.

Wasn't suppose with millis() the arduino be capable of doing the action for 1 clap and also for 2 claps (maybe stops and the 2 clap-action)?