Problem with delay() and millis()

Hi everyone,

I'm working on my first Arduino project and I've run into a problem. I'm trying to produce a square wave at a specific frequency on pin 8 of the Arduin Digital (PWM). Initially I used delayMicroseconds(), which seemed to work fine until I realized that I may want an interval longer than 16mSec.

I've tried using delay() and millis() but neither seems to work- after uploading the file the output goes low, I see a single cycle, and then the output remains low (no square wave).

Arduino IDE v1.8.13
Arduino Uno

This is the code I'm running. All three methods for producing the delay have been included (with the two that don't work being commented out). What am I doing wrong?

int LEDpin = 13;
int CH1pin = 8;


int times = 100;
int chan = 1;
int duration = 1;
unsigned long time_now = 0;


int main() {


  Serial.begin(115200);
  pinMode(LEDpin, OUTPUT);
  pinMode(CH1pin, OUTPUT);


  time_now = millis();


  while (times == 100)
  {
    digitalWrite(CH1pin, LOW);
    delayMicroseconds(duration);
    //delay(duration);
    //while(millis() < time_now + duration){
    //}
    digitalWrite(CH1pin, HIGH);
    delayMicroseconds(duration);
    //delay(duration);
    //while(millis() < time_now + duration){
    //}
  }
}

Thanks!
Allan

int duration = 1;

delayMicroseconds(duration);

Read this:

"This function works very accurately in the range 3 microseconds and up. We cannot assure that delayMicroseconds will perform precisely for smaller delay-times."

delay() should work, but you are limited to integer millisecond delays. What time periods do you want?

I was hoping to be able to set the delay from 1mSec to 100mSec. I just don't understand why delayMicroseconds() works but delay() and millis() doesn't.

Allan124

    //while(millis() < time_now + duration){

It probably isn't the cause of your problem, but while you're looking at this, it's worth mentioning that this is a flawed statement.

You should never compare millis() to a future time stamp. It will not work correctly when millis() rolls over. You need to subtract millis() from the time stamp, and compare the result with a value

    //while(millis() - time_stamp < duration){

allan124:
I was hoping to be able to set the delay from 1mSec to 100mSec.

We talking milli or micro here?

-jim lee

Maximum delayMicroseconds is 16383 (16.383 millis). (Unless it's been changed recently).

Yes, I was hoping to switch to delay() because I read that the delayMicroseconds() command doesn't work beyond delayMicroseconds(16000). The range I was shooting for is 1millisecond to 100milliseconds.

Thanks for the help everyone!
Allan

Two delayMicroseconds(10000) in succession is the equiv of "delayMicroseconds(20000)".

The range I was shooting for is 1millisecond to 100milliseconds.

What is the problem? Clean up the messy code you posted, avoid using a call to main() and DO use delay() statements

  void loop() {
    digitalWrite(CH1pin, LOW);
    delay(duration);
    digitalWrite(CH1pin, HIGH);
    delay(duration);
}

You forgot to call init() and initVariant() in main(). You can't expect all of the library functions to work if you don't initialize the library.

Thanks for all of the help!
I ended up going back to the Blink example in 0.1Basics and structuring the code similar to that.

int CH1pin = 8;
int duration = 1;
unsigned long time_now = 0;


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


void loop() {
  time_now = millis();
  digitalWrite(CH1pin, LOW);
  //delayMicroseconds(duration);
  //delay(duration);
  while(millis() - time_now < duration){
  }
  time_now = millis();
  digitalWrite(CH1pin, HIGH);
  //delayMicroseconds(duration);
  //delay(duration);
  while(millis() - time_now < duration){
  }
}

All three methods run now.

-Allan

This is blocking code. You might as well use delay() if you are going to do that.

  while(millis() - time_now < duration){
  }
  time_now = millis();
  digitalWrite(CH1pin, HIGH);
  //delayMicroseconds(duration);
  //delay(duration);
  while(millis() - time_now < duration){
  }

What you need for non blocking is something like:

  if (millis() - time_now >= duration){
  time_now = millis();
  digitalWrite(CH1pin, HIGH);
  }