flashing opposing leds

Hi,

I'm working on something relatively simple which I'm hoping to scale up to vibration motors but at the moment using led's to practice my coding. I want to make 2 leds flash at the same rate but with opposing timing. I have got this far, by setting one led to LOW and the other to HIGH at the start, but what this does is creates a pattern like;

led1, led2, long gap

what I'd like is led1, short gap, led2, short gap repeat.

Is there a simple way of setting both leds LOW but putting in a pause for one of the leds at the beginning of the loop (once only) of say: total time%2 (half the off time plus half the on time) so that it flashes with a lag of exactly half the flashing time?

// These variables store the flash pattern
// and the current state of the LED

int ledPin1 =  12;      // the number of the LED pin
int ledState1 = LOW;             // ledState used to set the LED
unsigned long previousMillis1 = 0;        // will store last time LED was updated
long OnTime1 = 250;           // milliseconds of on-time
long OffTime1 = 750;          // milliseconds of off-time

int ledPin2 =  13;      // the number of the LED pin
int ledState2 = HIGH;             // ledState used to set the LED
unsigned long previousMillis2 = 0;        // will store last time LED was updated
long OnTime2 = 250;           // milliseconds of on-time
long OffTime2 = 750;          // milliseconds of off-time

void setup() 
{
  // set the digital pin as output:
  pinMode(ledPin1, OUTPUT);      
  pinMode(ledPin2, OUTPUT);     


  
}

void loop()
{
  // check to see if it's time to change the state of the LED
  unsigned long currentMillis = millis();

  if((ledState1 == HIGH) && (currentMillis - previousMillis1 >= OnTime1))
  {
    ledState1 = LOW;  // Turn it off
    previousMillis1 = currentMillis;  // Remember the time
    digitalWrite(ledPin1, ledState1);  // Update the actual LED
  }
  else if ((ledState1 == LOW) && (currentMillis - previousMillis1 >= OffTime1))
  {
    ledState1 = HIGH;  // turn it on
    previousMillis1 = currentMillis;   // Remember the time
    digitalWrite(ledPin1, ledState1);   // Update the actual LED
  }
  
  if((ledState2 == HIGH) && (currentMillis - previousMillis2 >= OnTime2))
  {
    ledState2 = LOW;  // Turn it off
    previousMillis2 = currentMillis;  // Remember the time
    digitalWrite(ledPin2, ledState2);  // Update the actual LED
  }
  else if ((ledState2 == LOW) && (currentMillis - previousMillis2 >= OffTime2))
  {
    ledState2 = HIGH;  // turn it on
    previousMillis2 = currentMillis;   // Remember the time
    digitalWrite(ledPin2, ledState2);   // Update the actual LED
  }
}

Thanks for your anticipated suggestions!

#define LED1 12
#define LED2 13
#define blinkTime 250


void setup()
{
pinMode(LED1, OUTPUT);
pinMode (LED2, OUTPUT);

}

void loop()
{
unsigned long t=millis() % (blinkTime * 4);
digitalWrite( LED1, (t< blinkTime) );
digitalWrite( LED2, (t > blinkTime *2) && ( t < blinkTime * 3) );
}

viksta66:
what I’d like is
led1, short gap, led2, short gap repeat.

So that’s one lighting cycle which takes a constant time to finish.
Let’s name that ‘cycleTime’.

Just declare onTime and offTime within the lighting cycle for each LED, then start a new lighting cycle while the old one is finished and switch your LEDs on and off as you want it:

struct led_t {byte pin; unsigned long onTime; unsigned long offTime;};

led_t leds[]={
  {12,    0, 1000 },   // pin, onTime, offTime (relative in current cycle)
  {13, 2000, 3000 },
};

void setup() {
  Serial.begin(9600);
  for (int i=0;i<2;i++) pinMode(leds[i].pin, OUTPUT);
}

unsigned long cycleTime=10000, cycleStartTime;

void loop() {
  long nowMillis=millis();
  if (nowMillis-cycleStartTime>=cycleTime) // start new lighting cycle when time is due
    cycleStartTime+=cycleTime;
  long diff=nowMillis-cycleStartTime; // where are we in the current cycle?
  for (int i=0;i<2;i++)
  {  
    if (diff>=leds[i].onTime && diff<leds[i].offTime)
      digitalWrite(leds[i].pin,HIGH);
    else  
      digitalWrite(leds[i].pin,LOW);
  }
  // uncomment the following lines for debug meesages on Serial
//  Serial.print(digitalRead(leds[0].pin));
//  Serial.println(digitalRead(leds[1].pin));
}

Look at the demo several things at a time which illustrates how to use millis() to manage time

...R

thanks for those suggestions. I tried the first one, thanks KenF. It worked beautifully… but now I’m experimenting with adding analogue input to change the off time of both leds.
I did this successfully using 1 led, but now with 2 of them there is no obvious change of speed, the only thing that happens is I get a bit of flickering at one end of the pot sweep.

My code is below- I tried basing KenF’s code on offtime rather than ontime (as ontime will be a constant and offtime variable) which didn’t break anything. I’m just not getting the analogue effect I’m after. What have I missed??

// These variables store the flash pattern
// and the current state of the LED

int ledPin1 =  12;      // the number of the LED pin
int ledState1 = LOW;             // ledState used to set the LED
unsigned long previousMillis1 = 0;        // will store last time LED was updated


long OnTime = 250;




int ledPin2 =  13;      // the number of the LED pin
int ledState2 = LOW;             // ledState used to set the LED
unsigned long previousMillis2 = 0;        // will store last time LED was updated
           // milliseconds of on-time
          // milliseconds of off-time


const int speedInPin = A0; // analogue pin for speed control




void setup() 
{
  // set the digital pin as output:
  pinMode(ledPin1, OUTPUT);      
  pinMode(ledPin2, OUTPUT);     
 
 
  
}

void loop()
{
  
  long OffValue = analogRead(speedInPin);   // read pot 
  long OffTime = map(OffTime, 0, 1023, 300, 3000); // map pot reading to millis values of off time
  
  
  unsigned long t=millis() % (OffTime * 4);
  digitalWrite(ledPin1, (t < OffTime));
  digitalWrite(ledPin2, (t > OffTime * 2) && (t < OffTime * 3));
  
  
  
  // check to see if it's time to change the state of the LED
  unsigned long currentMillis = millis();
 
  if((ledState1 == HIGH) && (currentMillis - previousMillis1 >= OnTime))
  {
    ledState1 = LOW;  // Turn it off
    previousMillis1 = currentMillis;  // Remember the time
    digitalWrite(ledPin1, ledState1);  // Update the actual LED
  }
  else if ((ledState1 == LOW) && (currentMillis - previousMillis1 >= OffTime))
  {
    ledState1 = HIGH;  // turn it on
    previousMillis1 = currentMillis;   // Remember the time
    digitalWrite(ledPin1, ledState1);	  // Update the actual LED
  }
  
  if((ledState2 == HIGH) && (currentMillis - previousMillis2 >= OnTime))
  {
    ledState2 = LOW;  // Turn it off
    previousMillis2 = currentMillis;  // Remember the time
    digitalWrite(ledPin2, ledState2);  // Update the actual LED
  }
  else if ((ledState2 == LOW) && (currentMillis - previousMillis2 >= OffTime))
  {
    ledState2 = HIGH;  // turn it on
    previousMillis2 = currentMillis;   // Remember the time
    digitalWrite(ledPin2, ledState2);	  // Update the actual LED
  }
}

Untested

#define LED1 12
#define LED2 13
#define onTime 250
#define speedInPin A0

void setup()
{
pinMode(LED1, OUTPUT);
pinMode (LED2, OUTPUT);

}

void loop()
{
int OffValue = analogRead(speedInPin);   // read pot 
unsigned long offTime = map(offTime, 0, 1023, 300, 3000); // map pot reading to millis values of off time

unsigned long t=millis() % ( (onTime + offTime) * 2);
digitalWrite( LED1, (t < onTime) );
digitalWrite( LED2, (t > onTime + offTime) &&  t < (onTime *2 + offTime)  );
}