Blink 5 times; wait 2 seconds; blink 5 times

Didn't know how to title this one.

I'm doing three things somewhat simultaneously which work fine as long as the lines in void toggleRedLED () are commented out:

  1. Trigger a sound card every 5000 mS
  2. Blink a red LED at a rate of 100mS continuously
  3. Trigger a motor every 1200mS

But I want the red LED to blink not continuously, but at a rate of 100mS for 2000mS, turn off for 2000mS, start blinking again at a rate of 100mS for 2000mS, turn off for 2000mS again, etc, etc.

I tried to do this in void toggleRedLED (). But if I un-comment the lines the red LED doesn't blink at all.

Help please!

// Which pins are connected to what
const byte soundCardPin = 8; //to sound card
const byte redLEDpin = 13;
const byte motorPin = 2;  //vibrating motor


// Time periods of objects.
const unsigned long soundCardInterval = 5000;
const unsigned long redLEDinterval = 100;
const unsigned long redLEDpauseInterval = 2000;
const unsigned long motorInterval = 1200;


// Variable holding the time value so far. One for each "Time"
unsigned long soundCardTime;
unsigned long redLEDtime;
unsigned long redLEDpauseTime;
unsigned long motorTime;

int soundCardState = LOW;         // starting state of the sound card
int motorState = LOW;
int redLEDState = LOW;



void setup ()
{
  pinMode (soundCardPin, OUTPUT);
  pinMode (redLEDpin, OUTPUT);
  pinMode (motorPin, OUTPUT);
  soundCardTime = millis ();
  redLEDtime = millis ();
  redLEDpauseTime = millis ();
  motorTime = millis ();
  Serial.begin(9600);
}
///////////////////////////////////////////// end of setup

void toggleSoundCard ()
{
  soundCardState = !soundCardState;
  digitalWrite (soundCardPin, soundCardState);
  soundCardTime = millis ();     // remember when we toggled it
}
////////////////////////////////////// end of toggleSoundCard


void toggleRedLED ()
{
 // if ( (millis () - redLEDpauseTime) >= redLEDpauseInterval) {  //if pause >2000 flash red LED
    redLEDState = !redLEDState;
    digitalWrite (redLEDpin, redLEDState);
    redLEDtime = millis ();     // remember when we toggled it
//  } else {
//    digitalWrite(redLEDpin, LOW);  //turn off red LED for 2000mS
//    redLEDpauseTime = millis();
//  }
}
///////////////////////////////////////// end of toggleRedLED



void toggleMotor ()
{
  motorState = !motorState;
  digitalWrite (motorPin, motorState);    // remember when we toggled it
  motorTime = millis ();
}
////////////////////////////////////////////// end of toggleMotor


void loop ()
{
  // Handling the sound card.
  if ( (millis () - soundCardTime) >= soundCardInterval)
    toggleSoundCard ();

  // Handling the red LED.
  if ( (millis () - redLEDtime) >= redLEDinterval)
    toggleRedLED ();


  // Handling the motor
  if ( (millis () - motorTime) >= motorInterval)
    toggleMotor();

}  // end of loop

In the void Loop section all of your braces are missing for the if statements.

1ArduinoMan:
In the void Loop section all of your braces are missing for the if statements.

If there's just 1 single line of code to execute, then they can leave out the braces. It's one of those pesky rule things.

callmebob:
But I want the red LED to blink not continuously, but at a rate of 100mS for 2000mS, turn off for 2000mS, start blinking again at a rate of 100mS for 2000mS, turn off for 2000mS again, etc, etc.

When you mention 'rate of 100 msec'.... do you mean turn on for 100 millisec, then turn off for 100 millsec, then turn on for 100 millisec (repeatedly) for a duration of 2000 msec? Then no activity for the next 2000 msec, then start the show rolling all over again?

100 msec is an amount of 'time'. It is not a 'rate'.

Also, you mention triggering something 'every x msec'. But you also need to mention the duration of time that the device is going to be active..... like trigger a motor every X seconds, and keep it active for Y seconds.

Maybe you could do something like.....

(for the setup)
count = 0;
toggleduration = 100 msec
sleepduration = 2000 msec
nexttoggletime = millis() + toggleduration;  //nexttoggletime is the time for the next toggling
*better set the initial state of the LED here too somewhere - eg. ON initially*


(for the loop code)
if (millis() >= nexttoggletime)
 {
   *toggle the led*;  // <---put in whatever line is needed to toggle the LED state
   count = count + 1; //keeping count of the number of times we have toggled for
      if (count == 10)
      {
        nexttoggletime = millis() + sleepduration;  //after around 10 toggles, let's sleep a bit
        count = 0; //better set the count back to zero here
      }
 }

callmebob:
But I want the red LED to blink not continuously, but at a rate of 100mS for 2000mS, turn off for 2000mS, start blinking again at a rate of 100mS for 2000mS, turn off for 2000mS again, etc, etc.

If you think about it what you are describing is a long series of blinks with the OFF interval varying between 100ms and 2000ms.

Count the blinks as they happen. There will be 10 x 100ms blinks in 2000ms (assuming 100ms ON and 100ms OFF). When the count gets to 10 change the OFF interval to 2000. When the count gets to 11 change it back to 100.

I think this is the same as what @Southpark has suggested.

...R

Southpark:
....

nexttoggletime = millis() + toggleduration;  //nexttoggletime is the time for the next toggling

better set the initial state of the LED here too somewhere - eg. ON initially

(for the loop code)
if (millis() >= nexttoggletime)



...

this part of the code will generate a small issue (in ~50 days) when millis() + toggleduration rolls over

don't do additions when you play with millis() for timing events, use subtraction

if (millis() - lastToggleTime >= toggleduration) {...} then that will work fine

Yes, this is what I mean. I need some time to study everything else, but I wanted to clear this up right away.

Southpark:
When you mention 'rate of 100 msec'.... do you mean turn on for 100 millisec, then turn off for 100 millsec, then turn on for 100 millisec (repeatedly) for a duration of 2000 msec? Then no activity for the next 2000 msec, then start the show rolling all over again?

Southpark:
If there's just 1 single line of code to execute, then they can leave out the braces. It's one of those pesky rule things.

My personal rule is to always use braces to encompass the code executed when an if returns true, with the subsidiary rule that each brace goes on its own line. Using those rules there is never any doubt as to what code is intended to run and what code is actually run. It also avoids confusion with the syntax of other languages, some of which I believe use tab levels to determine what code is executed.