How to create a variable pause?

How can I create a variable pause in the microsecond range? The pause should be adjustable with a potentiometer. I don't have much experience and have tried to cobble together some code from online tutorials. Ultimately, I want to use `micros()`, but to see a result on the built-in LED, I created the pattern using `millis()`. It's not working. Perhaps someone can help me? Thanks for any help. Hans

//Arduino Test variable Pause mit Micros
// Eingebundene Bilbliotheken
#include <Arduino.h>
#include "avdweb_AnalogReadFast.h"
#include "digitalWriteFast.h"
// Define pin connections
const int stepPin = 13;
const int Pause_Millis = 1000;
unsigned long lastAction = 0;
long currentMillis;
const byte Poti = A1;
int Pause = 1000;


void setup() {
	pinModeFast(stepPin, OUTPUT);
	digitalWriteFast(stepPin, HIGH);
	int adc = analogRead(Poti);
  }
	
void loop () {
	int Poti_Value = analogReadFast(Poti);
	Pause = map(Poti_Value, 0, 1023, 0, Pause_Millis);
	delay(500);
	digitalWriteFast(stepPin, LOW);
	currentMillis = millis();
	if ((lastAction + Pause) < millis()) {
  lastAction = currentMillis;
	digitalWriteFast(stepPin, HIGH); 
	}
	} 

Elucidate precisely, please.

Please describe what you expected to happen and what happened instead.

This will give you what you want, but it isn't any different than using delay()

//Arduino Test variable Pause mit Micros
// Eingebundene Bilbliotheken
// Define pin connections
const int stepPin = 13;
const unsigned long Pause_Millis = 1000;
const byte Poti = A1;


void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("Ready");
  pinMode(stepPin, OUTPUT);
  digitalWrite(stepPin, HIGH);
  int adc = analogRead(Poti);
}

void loop() {
  int Poti_Value = analogRead(Poti);
  unsigned long Pause = map(Poti_Value, 0, 1023, 0, Pause_Millis);
  delay(500);
  digitalWrite(stepPin, LOW);
  unsigned long startMillis = millis();
  while (millis() - startMillis < Pause) {
    // do nothing - keep waiting
  }
  digitalWriteFast(stepPin, HIGH);
}

If OP is wanting timing as fine as micros, OP should use hysteresis on the potentiometer reading. In my opinion...

Maybe, if we knew what you are trying to do instead of how you are trying to do it...?

i think you're trying to use the pot to set the duration that an LED is periodically turned on, the duty-cycle

//Arduino Test variable pauseMsec mit Micros

const int       PinStep = 13;
const byte      PinPot  = A1;   // A0;

const unsigned long   MaxPauseMsec = 1000;
unsigned long   msec0;
unsigned long   msec1;

char  s [90];

// -----------------------------------------------------------------------------
void loop ()
{
    int           potVal    = analogRead (PinPot);
    unsigned long pauseMsec = map (potVal, 0, 1023, 0, MaxPauseMsec);

    sprintf (s, "potVal %4d, pause %8lu", potVal, pauseMsec);
    Serial.println (s);

    unsigned long msec = millis ();
    if (msec - msec0 >= MaxPauseMsec)   // restart
        msec0 = msec;
    else if (msec - msec0 < pauseMsec)
        digitalWrite (PinStep, HIGH);
    else
        digitalWrite (PinStep, LOW);
}

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (9600);

    pinMode       (PinStep, OUTPUT);
    digitalWrite  (PinStep, HIGH);
}

Hi @Holzwurm56 !

Here is a code that uses micros to do something similar to your sketch but non-blocking:

/*
   Forum: https://forum.arduino.cc/t/how-to-create-a-variable-pause/1440292
   Wokwi: https://wokwi.com/projects/461499361648079873

   ec2021
   2026/04/17

   * verwendet micros() anstelle von millis()
   * ist nicht blockierend (kein delay()) 

*/



//Arduino Test variable Pause mit Micros
// Eingebundene Bilbliotheken
#include <Arduino.h>
#include "avdweb_AnalogReadFast.h"
#include "digitalWriteFast.h"

enum class ACTION {IDLE, WHILEOFF};
// Define pin connections
constexpr byte Poti = A1;
constexpr byte stepPin = 13;
constexpr unsigned long maxPause = 1000; //ms

ACTION action = ACTION::IDLE;
unsigned long lastAction;
unsigned long Pause;
int Poti_Value;


void setup() {
  Serial.begin(115200);
  Serial.println("Ready");
  pinModeFast(stepPin, OUTPUT);
  digitalWriteFast(stepPin, HIGH);
  lastAction = micros();
}

void loop () {
  switch (action) {
    case ACTION::IDLE:
      Poti_Value = analogReadFast(Poti);
      Pause = map(Poti_Value, 0, 1023, 0, maxPause) * 1000; // milli to micro
      // Skip until 500 ms elapsed
      if (micros() - lastAction > 500000UL) {  // Replaces delay(500)
        action = ACTION::WHILEOFF;
        digitalWriteFast(stepPin, LOW);
        lastAction = micros();
      }
      break;
    case ACTION::WHILEOFF:
      // Skip until Pause elapsed
      if (micros() - lastAction > Pause) {
        action = ACTION::IDLE;
        digitalWriteFast(stepPin, HIGH);
        lastAction = micros();
      }
      break;
  }

}

You can test it on Wokwi:

https://wokwi.com/projects/461499361648079873

However your final intention is unclear. Using a diode to visually see an effect of a few micros will not work; your eyes aren't quick enough. And depending on the duration you might be better off with the function delayMicroseconds() than using a non-blocking method.

It depends ...

This example allows a potentiometer to adjust the time between LED_BUILTIN blinks from 250milliseconds to 1000milliseconds, then toggles LED_BUILTIN ON for 100ms, then OFF.

const byte potpin = A0; // adjustable input
int minpause = 250, maxpause = 1000, duration = 100, pot; // pause parameters
unsigned long timer, timeout; // timing between LED blinks

void setup() {
  pinMode(LED_BUILTIN, OUTPUT); // LED 13
}

void loop () {
  unsigned long timeout = map(analogRead(potpin), 0, 1023, minpause, maxpause);
  if (millis() - timer > timeout) {
    timer = millis();
    digitalWrite(LED_BUILTIN, HIGH);
    delay(duration);
    digitalWrite(LED_BUILTIN, LOW);
  }
}

https://docs.arduino.cc/language-reference/en/functions/time/delayMicroseconds/

Thank you so much for your help. blh64's code works exactly as I hoped. blh64, I mentioned in the topic that I want to use `micros()` in the final version. I can't use variables with `delayMicroseconds()`, but it works with `micros()`. Pause will be the variable.

Thanks again, Hans

Why do you think that? The same nonsense as Your Previous Topic.

@Holzwurm56 Have you serial printed your Pause variable? I suspect that if you do, you will see that the value of Pause changes a little bit without moving the potentiometer. I am not sure if your specific needs (or you) will care or not. But it will fluctuate the way it is currently coded using the code in post #4.

I confirmed with serial printing that the code in post 4 did fluctuate the values. At least with my UNO, my wiring, and my POT that is wired up to it. This code below was copied from post #4. I changed the potentiometer's pin number to A4 because I already had that one wired to my UNO. I commented out the digitalWrite's and while loop. I changed the delay to 100mS so I could watch the values faster. I added some hysteresis to the analog input. This gives a stable reading:

//----------------------------------------------------------
//=================== WITH DEADBAND ========================
//----------------------------------------------------------

const int stepPin = 13;
const unsigned long Pause_Millis = 1000;
const byte Poti = A4;

//Hysteresis variables
int stableValue = 0;
const int deadband = 2;  /*Ignore small ADC noise. Change as needed.
                         Lower value is more sensitive, higher value is less sensitive.*/
unsigned long Pause;


void setup() {
  Serial.begin(9600);
  delay(1000);
  Serial.println("Ready");
  pinMode(stepPin, OUTPUT);
  digitalWrite(stepPin, HIGH);
  int adc = analogRead(Poti);
}

void loop() {
  int Poti_Value = analogRead(Poti);

  if (abs(Poti_Value - stableValue) > deadband) {
    stableValue = Poti_Value;
  }

  Pause = map(stableValue, 0, 1023, 0, Pause_Millis);
  delay(100);

  /*digitalWrite(stepPin, LOW);
  unsigned long startMillis = millis();
  while (millis() - startMillis < Pause) {
    // do nothing - keep waiting
  }
  digitalWriteFast(stepPin, HIGH);*/

  Serial.println(Pause);
}

Yes you can, but you need to be aware that it only works with delays of up to 16383μs. If you try to use a longer delay then you end up with a shorter than expected delay as the 14 bit number overflows.

If you need to produce longer delays then you can get round this by calling the function several times; or you can use a combination of delay( ), followed by delayMicroseconds( ).

That way delay( ) gives you the majority of the required delay, and delayMicroseconds is just used to get the precision required.

You haven't told us what range of delays you are actually trying to achieve.

fade a led?

seems to be on/off but not clear if the pot is intended to affect the

  • on/off duration
  • the period of flashing
  • on/off duration with a fixed off/on duration
    it's never obvious if LOW/HIGH is ON/OFF

combining the use of a delay, setting an output LOW and a improperly written timer

  • using an if statement
  • checking for <
    is flawed

the following amy have been what the OP was attempting

    delay (500);
    digitalWriteFast (stepPin, LOW);

    lastAction    = currentMillis;         // previous millis()
    currentMillis = millis ();
    while if ((lastAction + Pause) < millis())
        ;                                  // wait

    digitalWriteFast (stepPin, HIGH); 

It is likely that the OP has not thought or learned much about Arduino timing but then the Arduino Tutorial Example has variable type mistakes that will crash before running for 25 days.

OP, hey;

Both millis() and micros() return unsigned long values.

Rollover millis() happens in 49.7-some days.

Rollover micros() happens 71.58-some minutes, and when close counts we use micros so rollover isn't so far off.

With unsigned math we have one formula that crosses rollover or not every time up to one full turnover minus one.

Elapsed time = end time - start time // works every time unsigned

If your needed intervals are shorter, unsigned int can hold 65.535 seconds or 65.535 millis and need 2 bytes each in say an array. 16 bit time calculations run twice as fast as 32 bit so faster and tighter. You can go 8 bit but beware; millis() low 8 bits skip 6 values out of 256 (250 1024-micros ticks + 6 skips), it will never == 255 and every milli precision is +/- 1. If close matters, use micros!

if ( micros() - startMicros >= waitMicros ) { wait is over, do the thing };

if ( micros() - startMicros < whileMicros ) { do the thing until while };