Using Millis to blink two leds at differant durations

In the sketch, micros( ) is being used for short intervals; you can get outputs as short as ≈ 10 µs and higher.

sorry Larry I did not explain myself very well.
at present the sketch starts both fuel injection and coil charge on at the same time and stay on for their individual setable times then repeats after the setable duration.
what I may have to do is also vary the start times to start the coil charge slightly before the fuel inject.
But as I said I will be testing on my project this evening Cairns Australia Time.
Where are you from?

Was in Cairns many years ago. :sweat:


We are a bit north of you, Calgary Alberta Canada. :cold_face:


If you would draw a timing diagram showing what the output relationships are, would be the best way to communicate your needs.

I will see if it works tonight before I annoy you further.
You live in a nice country from what I have seen.
we deffinatly don't get snow or cold weather. :wink:

Hi Larry I tried the sketch on my test rig.
Found a problem when the first injection cycle injected for 25ms. the rest as program 5Ms It did give me a direction as the extra fuel did ignite and give a larger flame.
i believe the long first pulse duration issue is the 12v battery which I am using to fire the injector coil, the ignition coil and run the high pressure fuel pump. but also powering the arduino which may be the problem maybe voltage flucuation.

If you would draw a timing diagram showing what the output relationships are, would be the best way to communicate your needs.

I will try and get it in a diagram this evening after work.
I am going to make a box to put it in to protect it from spark jump to other wires and use a second 12 Battery.
I seem to have damaged another Arduino as The USB not Recognised and flashing 3 times then stop but repeating.

This should be a link to the video of the initial 25ms injection.

Well that definitely let’s the smoke out.
:nerd_face:

.
Made a box.

Nice !

I had a thought Bubble.
The three const unsigned long I use for setting Led1, Led2 and duration.
if I used 3 Pots to adjust in real time and have a readout on a 2004 LCD display.
would that slow the sketch down.

There should be very little effect on speed.

Ok thanks I have ordered display ,
I will do some research on pot program.
I should be able to use serial print to see the output changes while writing the sketch.

couldnt wait for my order so purchased a 1602 LCD with buttons shield.
I does not want to play Just lights up the screen with bars on top line.
so lucky I purchased local I will take it back to see if there is a problem.

Ok I swapped Arduino and fixed display
so have an issue with one board

Hi Larry I have been going around in circles.
I have got my 1602 LCD with button shield in program.
But Trying to change times in real time.

lcd.print ("LED1onDuration = 8; "); //Display current .LED on duration. then use up down button to change then save
is this possible.
My code

//
//https://forum.arduino.cc/t/using-millis-to-blink-two-leds-at-differant-durations/944151?u=larryd
//
//  Version   YY/MM/DD     Comments
//  =======   ========     ===============================================
//  1.00      22/01/08     Running code
//  1.02      22/01/08     using micros() for better pulse timing
//
//
//
#include <LiquidCrystal.h>
//LCD pin to Arduino
const int pin_RS = 8; 
const int pin_EN = 9; 
const int pin_d4 = 4; 
const int pin_d5 = 5; 
const int pin_d6 = 6; 
const int pin_d7 = 7; 
const int pin_BL = 10; 
LiquidCrystal lcd( pin_RS,  pin_EN,  pin_d4,  pin_d5,  pin_d6,  pin_d7);
#define LEDon                           HIGH
#define LEDoff                          LOW

#define ENABLED                         true
#define DISABLED                        false

bool LED1Flag                         = DISABLED;
bool LED2Flag                         = DISABLED;
bool newCycleFlag                     = ENABLED;
bool nextCycleFlag                    = DISABLED;

const byte LED1pin                    = 0;
const byte LED2pin                    = 1;

unsigned long LED1onDuration    = 8;      //ON time for LED1
unsigned long LED2onDuration    = 10;     //ON time for LED2


const unsigned long LEDoffTime        = 2000;   //time between cycles
unsigned long LED1onMicros;
unsigned long LED2onMicros;
unsigned long nextCycleMillis;

//******************************************************************************
void setup()
{
  pinMode(LED1pin, OUTPUT);         
  digitalWrite(LED1pin, LEDoff);    

  pinMode(LED2pin, OUTPUT);         
  digitalWrite(LED2pin, LEDoff);    
 
 lcd.begin(16, 2);
 lcd.setCursor(0,0);
 lcd.print("LED1onDuration1");
 lcd.setCursor(0,1);
 lcd.print("LED1on:");

} //END of setup()

//******************************************************************************
void loop()
{
   int x;
 x = analogRead (0);
 lcd.setCursor(10,1);
 if (x < 60) {
   lcd.print ("LED1onDuration    = 8; "); //Display current .LED on duration. then use up down button to change then save 
 }
 else if (x < 200) {
   lcd.print ("Up    ");
 }
 else if (x < 400){
   lcd.print ("Down  ");
 }
 else if (x < 600){
   lcd.print ("Left  ");
 }
 else if (x < 800)
 { lcd.print ("Select");
 }
  //****************************************               L E D s   O N  ?
  //turn on the LEDs ?
  if (newCycleFlag == ENABLED)
  {
    newCycleFlag = DISABLED;

    //both LEDs ON
    digitalWrite(LED1pin, LEDon);
    digitalWrite(LED2pin, LEDon);

    //enable the LED1 OFF TIMER
    LED1Flag = ENABLED;
    //start the TIMER
    LED1onMicros = micros();

    //enable the LED2 OFF TIMER
    LED2Flag = ENABLED;
    //start the TIMER
    LED2onMicros = micros();

    //enable the nextCycle TIMER
    nextCycleFlag = ENABLED;
    //start the TIMER
    nextCycleMillis = millis();

  }

  //****************************************               L E D 1   O F F   T I M E R
  //time to turn OFF LED1 ?
  if (LED1Flag == ENABLED && micros() - LED1onMicros >= LED1onDuration * 1000ul)
  {
    //DISABLE this TIMER
    LED1Flag = DISABLED;

    digitalWrite(LED1pin, LEDoff);
  }

  //****************************************               L E D 2   O F F   T I M E R
  //time to turn OFF LED2 ?
  if (LED2Flag == ENABLED && micros() - LED2onMicros >= LED2onDuration * 1000ul)
  {
    //DISABLE this TIMER
    LED2Flag = DISABLED;

    digitalWrite(LED2pin, LEDoff);
  }

  //****************************************               n e x t C y c l e   T I M E R
  //time to start a new cycle
  if (nextCycleFlag == ENABLED && millis() - nextCycleMillis >= LEDoffTime)
  {
    //DISABLE this TIMER
    nextCycleFlag = DISABLED;

    //allow another cycle to start
    newCycleFlag = ENABLED;
  }

  //****************************************
  //Other non blocking code goes here
  //****************************************

} //END of loop()

Pins 0 and 1 are used for Arduino RX and TX.

Here is one way do doing it:

N O T E : time on LCD is in μs (microseconds).

4 momentary switches are used on A0-A3

//
//https://forum.arduino.cc/t/using-millis-to-blink-two-leds-at-differant-durations/944151?u=larryd
//
//  Version   YY/MM/DD     Comments
//  =======   ========     =======================================================
//  1.00      22/01/08     Running code
//  1.02      22/01/08     using micros() for better pulse timing
//  1.03      22/01/16     Added LCD and increment and decrement switches to adjust timing of LEDs
//
//

//********************************************************************************
//remove comment marks for an I2C LCD
//#define serialLCDisBeingUsed  //uncomment if you have a serial LCD               <-----<<<<<

//********************************************************************************
#ifdef  serialLCDisBeingUsed
#include <Wire.h>

//Use I2C library:     https://github.com/duinoWitchery/hd44780
//LCD Reference:       https://www.arduino.cc/en/Reference/LiquidCrystal

//this LCD is I2C wired 
#include <hd44780.h>   //main hd44780 header

//NOTE:
//hd44780_I2Cexp control LCD using I2C I/O expander backpack (PCF8574 or MCP23008)
//hd44780_I2Clcd control LCD with native I2C interface (PCF2116, PCF2119x, etc...)

#include <hd44780ioClass/hd44780_I2Cexp.h> //I2C expander i/o class header

//If you do not know what your I2C address is, first run the 'I2C_Scanner' sketch
//OR
//Run: I2CexpDiag.ino
//C:\Users\YourName\Documents\Arduino1.69\libraries\hd44780\examples\ioClass\hd44780_I2Cexp\I2CexpDiag

hd44780_I2Cexp lcd(0x3F);
//hd44780_I2Cexp lcd(0x27);

//********************************************************************************

#else

//this LCD is parallel wired 
#include <LiquidCrystal.h>

// LCD pin         4   6  11  12  13  14
//                RS  EN  D4  D5  D6  D7
LiquidCrystal lcd( 8,  9,  4,  5,  6,  7);

#endif

//********************************************************************************

#define LEDon                           HIGH
#define LEDoff                          LOW

#define ENABLED                         true
#define DISABLED                        false

#define OPENED                          HIGH
#define CLOSED                          LOW  //+5V---[Internal 50k]---PIN---[switch]---GND

const byte LED1pin                    = 2;
const byte LED2pin                    = 3;

const byte heartbeatLED               = 13;

const byte incSwitch1                 = 14;  //same as A0
const byte decSwitch1                 = 15;  //same as A1

const byte incSwitch2                 = 16;  //same as A2
const byte decSwitch2                 = 17;  //same as A3

bool LED1Flag                         = DISABLED;
bool LED2Flag                         = DISABLED;
bool newCycleFlag                     = ENABLED;
bool nextCycleFlag                    = DISABLED;

byte lastIncSwitch1;
byte lastDecSwitch1;

byte lastIncSwitch2;
byte lastDecSwitch2;

unsigned int incDecAmount             = 100;         //100us

unsigned long LED1onDuration          =  8 * 1000UL; //ON time for LED1
unsigned long LED2onDuration          = 10 * 1000UL; //ON time for LED2

const unsigned long LEDoffTime        = 2000;   //time between cycles

unsigned long heartbeatMillis;
unsigned long LED1onMicros;
unsigned long LED2onMicros;
unsigned long nextCycleMillis;
unsigned long switchMillis;


//******************************************************************************
void setup()
{
  pinMode(heartbeatLED, OUTPUT);

  pinMode(LED1pin, OUTPUT);
  digitalWrite(LED1pin, LEDoff);

  pinMode(LED2pin, OUTPUT);
  digitalWrite(LED2pin, LEDoff);

  pinMode(incSwitch1, INPUT_PULLUP);
  pinMode(decSwitch1, INPUT_PULLUP);

  pinMode(incSwitch2, INPUT_PULLUP);
  pinMode(decSwitch2, INPUT_PULLUP);

  lcd.begin(16, 2);
  lcd.setCursor(0, 0);

  //                   111111
  //         0123456789012345
  lcd.print("LED1 ON =       ");

  lcd.setCursor(10, 0);
  lcd.print(LED1onDuration);

  lcd.setCursor(0, 1);
  //                   111111
  //         0123456789012345
  lcd.print("LED2 ON =       ");

  lcd.setCursor(10, 1);
  lcd.print(LED2onDuration);


} //END of setup()


//******************************************************************************
void loop()
{
  //****************************************
  //is it time to toggle the heartbeatLED ?
  if (millis() - heartbeatMillis >= 500)
  {
    //restart this TIMER
    heartbeatMillis = millis();

    //Toggle the heartbeatLED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));

  }

  //****************************************
  //is it time to check the switches ?
  if (millis() - switchMillis >= 50)
  {
    //restart this TIMER
    switchMillis = millis();

    checkSwitches();

  }

  //****************************************               L E D s   O N  ?
  //turn on the LEDs ?
  if (newCycleFlag == ENABLED)
  {
    newCycleFlag = DISABLED;

    //both LEDs ON
    digitalWrite(LED1pin, LEDon);
    digitalWrite(LED2pin, LEDon);

    //enable the LED1 OFF TIMER
    LED1Flag = ENABLED;
    //start the TIMER
    LED1onMicros = micros();

    //enable the LED2 OFF TIMER
    LED2Flag = ENABLED;
    //start the TIMER
    LED2onMicros = micros();

    //enable the nextCycle TIMER
    nextCycleFlag = ENABLED;
    //start the TIMER
    nextCycleMillis = millis();

  }

  //****************************************               L E D 1   O F F   T I M E R
  //time to turn OFF LED1 ?
  if (LED1Flag == ENABLED && micros() - LED1onMicros >= LED1onDuration)
  {
    //DISABLE this TIMER
    LED1Flag = DISABLED;

    digitalWrite(LED1pin, LEDoff);
  }

  //****************************************               L E D 2   O F F   T I M E R
  //time to turn OFF LED2 ?
  if (LED2Flag == ENABLED && micros() - LED2onMicros >= LED2onDuration)
  {
    //DISABLE this TIMER
    LED2Flag = DISABLED;

    digitalWrite(LED2pin, LEDoff);
  }

  //****************************************               n e x t C y c l e   T I M E R
  //time to start a new cycle
  if (nextCycleFlag == ENABLED && millis() - nextCycleMillis >= LEDoffTime)
  {
    //DISABLE this TIMER
    nextCycleFlag = DISABLED;

    //allow another cycle to start
    newCycleFlag = ENABLED;
  }

  //****************************************
  //Other non blocking code goes here
  //****************************************

} //END of loop()


//******************************************************************************
void checkSwitches()
{
  //****************************************      i n c S w i t c h 1
  byte state = digitalRead(incSwitch1);

  if (lastIncSwitch1 != state)
  {
    //update to the new state
    lastIncSwitch1 = state;

    if (state == CLOSED)
    {
      LED1onDuration = LED1onDuration + incDecAmount;

      lcd.setCursor(0, 0);
      //                   111111
      //         0123456789012345
      lcd.print("LED1 ON =       ");

      lcd.setCursor(10, 0);
      lcd.print(LED1onDuration);
    }

  }

  //****************************************      d e c S w i t c h 1
  state = digitalRead(decSwitch1);

  if (lastDecSwitch1 != state)
  {
    //update to the new state
    lastDecSwitch1 = state;

    if (state == CLOSED)
    {
      LED1onDuration = LED1onDuration - incDecAmount;

      lcd.setCursor(0, 0);
      //                   111111
      //         0123456789012345
      lcd.print("LED1 ON =       ");

      lcd.setCursor(10, 0);
      lcd.print(LED1onDuration);
    }

  }

  //****************************************      i n c S w i t c h 2
  state = digitalRead(incSwitch2);

  if (lastIncSwitch2 != state)
  {
    //update to the new state
    lastIncSwitch2 = state;

    if (state == CLOSED)
    {
      LED2onDuration = LED2onDuration + incDecAmount;

      lcd.setCursor(0, 1);
      //                   111111
      //         0123456789012345
      lcd.print("LED2 ON =       ");

      lcd.setCursor(10, 1);
      lcd.print(LED2onDuration);
    }

  }

  //****************************************      d e c S w i t c h 2
  state = digitalRead(decSwitch2);

  if (lastDecSwitch2 != state)
  {
    //update to the new state
    lastDecSwitch2 = state;

    if (state == CLOSED)
    {
      LED2onDuration = LED2onDuration - incDecAmount;

      lcd.setCursor(0, 1);
      //                   111111
      //         0123456789012345
      lcd.print("LED2 ON =       ");

      lcd.setCursor(10, 1);
      lcd.print(LED2onDuration);
    }

  }

} //END of   checkSwitches()

Hi Larry you have been busy.
I have printed your code at Work.
I will look at and see if I can follow you code this evening.
I have watched dozens of videos and still couldn't get my head around adjusting the
unsigned long in the code with a LCD Button.