Reading with 1 millisecond delay

I'm trying to read millis with 1 millisecond delay.
But delay is not working properly.
What should be the proper code to this short interval delay value ?
delay

float myTime;

void setup() {
  Serial.begin(9600);
}
void loop() {
  
  myTime = millis();
 
  Serial.println(myTime); // prints time since program started
  delay(1);          // wait a second so as not to send massive amounts of data
}

What is wrong, the comment, or the value for delay?

delay(1000); // wait a second

delayMicroseconds(1000); // wait a millisecond

Why do you use a float to hold millis?
Why do you want to block on Serial?
9600 baud means about 1000 chars a second,
that is not enough to print at least 6 chars 1000 times.

An unsigned long is sufficient, and you may get better precision by using delayMicroseconds(1000);

@Whandall beat me to it

in this case if i use serial baud 57600 and delayMicroseconds(1000) what data type should i use please suggest ?

out put value will a sensor value.

the actual code is :

void setup() {
  // initialize serial communication at 9600 bits per second:
  //Serial.begin(9600);
  Serial.begin(500000);
}

// the loop routine runs over and over again forever:
void loop() {
 
  static int timer = 1;
  
  if(Serial.available() > 0)
  {
    timer = Serial.parseFloat();
    
    Serial.print(">");
    Serial.print(timer);
    Serial.println("<");
   //Serial.flush();
  }
 
  int sensorValue = analogRead(A0);
  float distance;
 
  
  float voltage = sensorValue * (5.0 / 1023.0);


  
 
  distance = 20*voltage - 0.051;
  Serial.println(distance);
   
  delay(timer);
}

even if i do the code like this

still output value is not 100% accurate
delay1

long myTime;

void setup() {
  Serial.begin(57600);
}
void loop() {
  //Serial.print("Time: ");
  myTime = millis();
  //myTime = 47.56;

  Serial.println(myTime); // prints time since program started
  //delay(1);          // wait a second so as not to send massive amounts of data
  delayMicroseconds(997);
}

Your first code does not use delayMicroseconds.

All variables used to hold millis or micros should be unsigned long.

You need ten bits to transfer one byte, println() adds two more chars to the output stream.
do the computation yourself.

What is hard to understand in unsigned long?
Millis does not take all values, sometimes it skips.

Something you will notice is that occasionally millis() will skip a number, advancing by 2 instead of 1. The millis counter is driven by an interrupt based off the 16MHz oscillator, with the interrupt occurring at 1.024mS intervals, requiring a periodic adjustment to keep the time interval fairly correct long term.

Forget about using a delay, just check for when the value of millis() changes.

unsigned long myTime;
unsigned long previousMillis;

void setup() {
  Serial.begin(115200);
}

void loop() {
  myTime = millis();
  if (myTime != previousMillis) {
    Serial.println(myTime); // prints time since program started
    previousMillis = myTime;
  }
}
1 Like

noted with thanks.
understand the point.

noted with thanks.
learned the logic.

The which @RAJ_Faisal is uploaded as termed is as actual code is correct?
Is that working ??? Anyone confirm about please.
if the actual code is that, so why this is not working on my side.
Let me know
Thanks

In addition to what has been said, you're using serial.println which means that serial transfer is sometimes "busy in the background"; serial reads and writes rely on interrupts and those take precedence over the code in your sketch as it is now. So sometimes the microcontroller may simply be busy for a millisecond with other tasks and as a result it may skip a beat.

That is a much worse (and untrue) description of the millis behavior.
It was explained already correctly.

Millis itself obviously doesn't skills a beat, but the serial print may appear to skip one.

Again, not true. Millis skips with or without printing.

Not at the frequency shown in this sketch given the 2.4% deviation.

Again, not true.

uint32_t lastVal;

void setup() {
  Serial.begin(115200);
}

void loop() {
  uint32_t topLoop = millis();
  if (topLoop != lastVal) {
    if (topLoop - lastVal > 1) {
      Serial.print(F("skip from "));
      Serial.print(lastVal);
      Serial.print(F(" to "));
      Serial.println(topLoop);
    }
    lastVal = topLoop;
  }
}
skip from 41 to 43
skip from 84 to 86
skip from 126 to 128
skip from 169 to 171
skip from 212 to 214
skip from 254 to 256
skip from 297 to 299
skip from 340 to 342
skip from 382 to 384
skip from 425 to 427
skip from 468 to 470
skip from 510 to 512
skip from 553 to 555
skip from 596 to 598
skip from 638 to 640
skip from 681 to 683
skip from 724 to 726
skip from 766 to 768
skip from 809 to 811
skip from 852 to 854
skip from 894 to 896
skip from 937 to 939
skip from 980 to 982
skip from 1022 to 1024
skip from 1065 to 1067
skip from 1108 to 1110
skip from 1150 to 1152
skip from 1193 to 1195

And that makes absolute sense, to keep the millis as close to the real milliseconds,
you have to adjust when the error reaches 1 millisecond, after each 42nd cycle of 16MHz/1024 counts.

There are no background processes on a standard AVR that take anywhere near 1 milli second.

Details can be found here:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.