How to produce low frequency pulse width modulation using millis() ?

Hi,

I'm designing a controller for relay. I cannot use the PWM because the period is too small for relay application.

I want to use millis.. i have tried many times but failed..
can anyone help me please?

const int ledPin =  2;      // the number of the LED pin            // ledState used to set the LED
long current = 0;        // will store last time LED was updated
long current2 = 0;

long period = 4000;           
long offtime = 8000;
void setup() {
  pinMode(ledPin, OUTPUT);      
}

void loop()
{

  static unsigned long current = millis();
    static unsigned long current2 = millis();
 
  if(millis()-current > offtime) 
  {
     
      digitalWrite(ledPin,HIGH);
      current=millis();
  }

if(millis()-current2 > period) 
  {
     
      digitalWrite(ledPin,LOW);
      current2=millis();
  }  
  
}

nevermind, i got it from relay example

#define RelayPin 2


int WindowSize = 4000;
unsigned long windowStartTime;
double Setpoint, Input, Output;
void setup()
{
  
  windowStartTime = millis();
  
  pinMode(RelayPin,OUTPUT);
}

void loop()
{
  Output = 1000;

  /************************************************
   * turn the output pin on/off based on pid output
   ************************************************/
  unsigned long now = millis();
  if(now - windowStartTime>WindowSize)
  { //time to shift the Relay Window
    windowStartTime += WindowSize;
  }
  if(Output > now - windowStartTime) digitalWrite(RelayPin,HIGH);
  else digitalWrite(RelayPin,LOW);

}

All your time variables should be unsigned longs.
Why are you declaring current and current2 again in loop() when they're declared already?
If you want the LED to alternate between on and off, you'll need a flag to keep track of it's state. Try this:

const int ledPin =  2;      // the number of the LED pin            
unsigned long current = 0;        // will store last time LED was updated
unsigned long current2 = 0;
unsigned long period = 4000;           
unsigned long offtime = 8000;
boolean flagLED =false; //LED off at start
void setup() {
  pinMode(ledPin, OUTPUT);   
  current=millis() ;   
}

void loop(){
   if(millis()-current > offtime && flagLED ==false) {
         digitalWrite(ledPin,HIGH);
         current2=millis();  //set start of wait time for switch off 
         flagLED = true;
   }
   if(millis()-current2 > period && flagLED==true) {
         digitalWrite(ledPin,LOW);
         current=millis(); //set start of wait time for switch on
         flagLED==false;
   }  
}

Henry_Best:
All your time variables should be unsigned longs.
Why are you declaring current and current2 again in loop() when they're declared already?
If you want the LED to alternate between on and off, you'll need a flag to keep track of it's state. Try this:

or:

void loop()

{
  if (millis()-current < 8000UL ) digitalWrite(ledPin,HIGH);
  else if (millis()-current < 12000UL) digitalWrite(ledPin,LOW);
  else current = millis();
}

The blink without delay example is a low frequency PWM application using millis.
It's a fixed duty cycle, for sure, but that's easily remedied.

BulldogLowell:

Henry_Best:
All your time variables should be unsigned longs.
Why are you declaring current and current2 again in loop() when they're declared already?
If you want the LED to alternate between on and off, you'll need a flag to keep track of it's state. Try this:

or:

void loop()

{
 if (millis()-current < 8000UL ) digitalWrite(ledPin,HIGH);
 else if (millis()-current < 12000UL) digitalWrite(ledPin,LOW);
 else current = millis();
}

Neat, except he wants the on time to be 4000 and the off time to be 8000. All he needs to do is to change the first line.

Nice. Excuse me if its a stupid question but what does the xxxxxUL do.

drksam:
Nice. Excuse me if its a stupid question but what does the xxxxxUL do.

It is an Unsigned Long integer comparing against the result of this (millis()-current) which are both UL's too.

I personally like to make sure that my numbers all play together (having learned the hard way).

Henry_Best:
]Neat, except he wants the on time to be 4000 and the off time to be 8000. All he needs to do is to change the first line.

good eye!

Thanks for tip.