Turn pin on for 2 ms, turn off for 998 ms, repeat

Hello,

Would like help in figuring out how write a program that can turn a pin on for 2ms, turn it off for 998 ms, and repeat every second.

Here is my code:

unsigned long interval = 998;
unsigned long previousMillis = 0;

void setup() {
  
pinMode(8, OUTPUT); // will deliver 2ms pulse

Serial.begin(9600);

}

void loop() {
 

digitalWrite(8, LOW);


unsigned long currentMillis = millis();

if(currentMillis - previousMillis >= interval) {
  previousMillis = currentMillis;

  digitalWrite(8, HIGH);
}

  else {
    digitalWrite (8,LOW);
  }

I've tried using millis to do this, but when i examine the pulses on separate software it seems the pin only stays on for 80 microseconds. Any suggestions?

Thanks in advance

Why do you diddle with the pin on EVERY pass through loop()?

If that is ALL that the sketch is doing, there is no reason not to use delay().

delay(...) could work and is easier, but millis() is better in the long run. I applaud your use of millis(), but...

(1) You write about a 2 ms pulse, but there is nothing in the sketch to handle 2 ms.
(2) millis() on my Uno does not start at zero by the time that I get to it. Your first period (or first pulse length) will be short unless previousMillis is set up in the setup() function.
(3) It would help to have a variable that keeps track of whether you are outputting a pulse or waiting in the period between pulses. There is a way to avoid this but requires reading the state of pin 8 (which some experts deplore).
(4) Pins should have names and the names should be well chosen and used. There should be a global line similar to const byte pulseOut=8; and then pulseOut should be used everywhere we see that pin 8 is referred to.

There is no reason to start a serial connection. At least you show no reason in your sketch.

If you want to keep it simple:

void setup()
{  
	pinMode(8, OUTPUT);
}

void loop()
{
	digitalWrite(8, HIGH);
	delay(2);
	digitalWrite(8, LOW);
	delay(998);
}

But it will not be extremely accurate due to slight delays in performing the logic shifts. You can measure how inaccurate it is and tweak it or express your pleasure or displeasure with the above simple approach.

I don't know what a "logic shift" is, but this version will be even easier to tweak:

void setup()
{  
	pinMode(8, OUTPUT);
}

void loop()
{
	digitalWrite(8, HIGH);
	delayMicroseconds(2000);
	digitalWrite(8, LOW);
	delay(998);
}

delay(...) and delayMicroseconds(...) are easier than millis() and micros() but will introduce issues if there are other things that you want to add later.

It would be nice to know how accurate the 2 ms and the 998 ms need to be.

i'm very new but it would seem to me that you could just use the basic example for Blink...and just modify the delay counts and pin assignment or just use pin 13 instead

ry thi sin loop():

digitalWrite( 8, ((millis() % 1000 ) <= 1));

Really cool and probably works fine, but the function digitalWrite(...) is documented to take a value of HIGH or LOW, not true or false.

HIGH/LOW, true/false and 1/0 are the same thing :wink:

vaj4088:
Really cool and probably works fine, but the function digitalWrite(...) is documented to take a value of HIGH or LOW, not true or false.

. . . or if you prefer:

digitalWrite( 8, ((millis() % 1000 ) <= 1) ? (HIGH) : (LOW) );

People who don't like this technique also talk about its behavior at the millis() rollover (every approx 50 days).

vaj4088:
delay(...) could work and is easier, but millis() is better in the long run. I applaud your use of millis(), but...

(1) You write about a 2 ms pulse, but there is nothing in the sketch to handle 2 ms.
(2) millis() on my Uno does not start at zero by the time that I get to it. Your first period (or first pulse length) will be short unless previousMillis is set up in the setup() function.
(3) It would help to have a variable that keeps track of whether you are outputting a pulse or waiting in the period between pulses. There is a way to avoid this but requires reading the state of pin 8 (which some experts deplore).
(4) Pins should have names and the names should be well chosen and used. There should be a global line similar to const byte pulseOut=8; and then pulseOut should be used everywhere we see that pin 8 is referred to.

Thanks for the advice.

The reason I used millis was because this program will use analogRead to read a voltage during those 2ms that the pin is on, and then make a decision on what to output based on that voltage. Delay would not be able to work because it pauses the program.