# Two signal with delay

I have a two pins for two blinks leds but I need delay the second signal from first. I start the first signal and I need start the second signal 50ms later. The first signal is 500ms HIGH and 500ms LOW, and the second signal is 400ms LOW and 600ms HIGH. If I start the second signal 50ms later, I can center the high period of the first signal with the low period of the second signal.

This is my code:

``````long DelaySecondSignal = 50;
int A = 1;

while (A == 1)
{
long millis_actuales = millis();

//Control Salida_A
if (millis_actuales - TiempoTranscurrido_SalidaA > (Estado_SalidaA ? 500 : 400)) {
TiempoTranscurrido_SalidaA = millis_actuales;
}

if (millis_actuales > DelaySecondSignal)
{
//Control Salida_B
if (millis_actuales - TiempoTranscurrido_SalidaB > (Estado_SalidaB ? 500 : 600)) {
TiempoTranscurrido_SalidaB = millis_actuales;
}
}
}
``````

TiempoTranscurrido_?? is a int and Estado_Salida? is a boolean.

I need start the second signal with 50ms of delay but "if (millis_actuales > DelaySecondSignal)" no work.

Thanks.

Your problem is that you are treating both signal separately. Instead you need to think about the events of turning LEDs on and off and where they lie on a combined timeline:

``````     0    100   200   300   400   500   600   700   800   900  1000
|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|
^  ^                       ^  ^
1 on  2 off                2 on  1 off
1: ooooooooooooooooooooooooooooooo
2: oooo                       oooooooooooooooooooooooooooooooooo
``````

You see how I have looped the time around so that the turning off of the second signal, which would normally come at 1050ms, in fact comes at 50ms. By just working in a single 1000ms block of time as a loop things become much simpler.

You can do it now with just a simple set of delays, now you have it laid out in a single timeline like that:

``````void loop() {
digitalWrite(led1, HIGH);
delay(50);
digitalWrite(led2, LOW);
delay(400);
digitalWrite(led2, HIGH);
delay(50);
digitalWrite(led1, LOW);
delay(500);
}
``````

All the `delay()` calls add up to 1000ms and it keeps looping around.

If you want to make it non-blocking you should set it up with a small finite state machine. There are 4 steady states which are the four spaces between the events on the timeline. There are 4 transitions, which are the events on the timeline. So you:

Start in state 0 with both LEDs on (which is how they are at the start of the timeline).

• 0: When 50ms have passed turn off LED 2 and move to state 1.
• 1: When 400ms have passed turn on LED 2 and move to state 2.
• 2: When 50ms have passed turn off LED 1 and move to state 3.
• 3: When 500ms have passed turn on LED 1 and move to state 0.
• This example work perfect, I can change the duty cycle and work. I have another question, How make this example without "delay()"? – Berto Dec 20 '16 at 16:58
• Like I say in the second half of my answer - with a Finite State Machine. – Majenko Dec 20 '16 at 16:59

I'd just base everything of `millis`.

``````int A = 1;

while (A == 1)
{
int phase = millis() % 1000;// modulo 1 second

// turn on A for the first 500ms of a period, and off for the rest
if( phase<500 )
digitalWrite(SalidaA, HIGH);
else
digitalWrite(SalidaA, LOW);

// turn on B for the first 50ms, and last 550ms of a period, and off for the rest
if( phase<50 || phase>=450 )
digitalWrite(SalidaB, HIGH);
else
digitalWrite(SalidaB, LOW);

}
``````
• I did not explain myself well. This example works but not well, for example if I change the length of the period, no work ok until after 1 second. For example, I have a Rate that is "150". I divide 60 seconds beetwen 150 and I have 0.4. Now I need repeat 50% HIGH - 50% LOW of cycle in 400ms in period A, but for example the period B is 35% HIGH - 65% LOW (35*400/100 = 140ms HIGH and 400-140= 260ms LOW). – Berto Dec 20 '16 at 17:15
• Majenko does not have this problem in his example because he repeats the cycle all time, so I asked if he knows how to do the same example with the milis() function. I need a similar PWM function with center aligned. – Berto Dec 20 '16 at 17:20
• Just multiply all the numbers by this 0.4. So 1000 becomes 400; 50 becomes 20 etc. – Gerben Dec 20 '16 at 21:06
• Now work, I changed "millis() % 1000;" by "millis() % 400;" and work ok but I DON'T KNOW WHY IT WORK, sorry. :( – Berto Dec 21 '16 at 16:43
• Do you know how modulo works? It's like like looking at a clock and saying; I don't care about the hours or minutes, I just want to know the seconds. After that you say; the first 5 seconds of every minute I want output A HIGH, the next 20 seconds LOW, and the rest of every minute HIGH again. For output B I want the output to be HIGH the first 30 seconds of every minute, and LOW the other 30 seconds. – Gerben Dec 21 '16 at 19:30