# Controlling the Serial Monitor for 10 seconds

I am an amateur with Arduino and coding and I am learning in my lab class. My project consists of using a photoresistor to measure the brightness of a white LED. I have the following circuit built.

I am having problems with the code because I need the serial monitor to print every 1/10 of a second for 10 seconds. My professor started talking about the micros() function but never showed an example. I have an idea as to how I can utilize this function to control how long the Serial Monitor prints for but I have been unsuccessful. I know that setting a delay is good enough for reading every 1/10 of a second but how can I make the serial monitor print values for only 10 seconds?

I believe it should be a total of 100 readings.

This is my current code:

``````unsigned long start, finished, elapsed, total;
int analogInPin = A0;
int LEDpin = 9;           // LED on pin 9

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

void loop() {
analogWrite(LEDpin,255);  // LED brightness
start = millis();
delay(100);
finished = millis();
elapsed = finished - start;
total = elapsed*100;

if (total >= 10000){
Serial.end();
}
``````
• You could count to 100... Commented Sep 24, 2017 at 4:25
• If you can blink without `delay()`, then you can print without `delay()`. Commented Sep 24, 2017 at 10:22

Using `micros()` is very much like boiling an egg.

When you want your egg to be cooked just right you know that it needs to be in the boiling water for a certain amount of time. There's three ways you can achieve that:

1. Use an egg timer to alert you when the time has passed,
2. Sit and stare at the boiling pot counting the seconds as they slowly tick by (booooooring..... ...zzzZZZzzz...)
3. Remember what time you put the egg in the water and glance at the clock every so often to see how much time has passed.

Using `millis()` is like option 3. It tells you how many milliseconds have passed since the board was turned on (or since the last `millis()` rollover at roughly 49 days). So when you put the egg in the water you record the current time. Then you periodically compare the recorded time to the current time (a simple subtraction will suffice) to see if enough time has passed. When it has you remove the egg and chow down.

So to put that more in a coding context - when you start some operation, or want to measure a period of time from a point, you just save the time in a variable:

``````start = millis();
``````

(`start` must be `uint32_t`, aka `unsigned long`). To find if enough time has passed you just subtract that saved time from the current time and it gives you the elapsed time, which you can compare to your required elapsed time:

``````if (millis() - start >= 100) {
}
``````

1/10 of a second is 100ms, so if you hit a difference of 100ms (or more) then your time has arrived and you can do something.

If you want it to do it again after that then just set the "start" time to the current time again.

For instance, for your requirements:

``````void loop() {
// Record the start time - the static means it
// only happens once the first time loop() is run and
// it remembers the value between iterations
static uint32_t start = millis();

// Somewhere to store the number of values we
// have given - again, static so it remembers across
// iterations of loop()
static uint8_t count = 0;

if (count < 100) { // No more than 100 counts
if (millis() - start >= 100) { // Tick
start = millis(); // Do it again in 100ms time

count++; // Add one to the count
}
}
}
``````

Using `delay(100)` will cause the sketch to wait at that line for 100 milliseconds. That is not (quite) the same as DOING something every 100 milliseconds. The difference is that other things take time too, so the time will be 100 milliseconds plus how ever long everything else takes.

The solution used by @Majenko still has that problem in a small way, because a new `millis()` value is used to set the new value of `start`. In most situations, it will work fine, but it is possible that the either or both of the `millis()` results were more than 100 after the previous value of `start`. That would happen if code that replaces the comment took more than 100ms some time. The fix for that is very simple. Just change `start = millis()` to `start += 100`. That will attempt to speed up the following loop, if it was getting behind.

As a side note, it would be good to change the 100 millisecond references to a defined name. Either a `#define` or a `const`. Since the `millis()` function returns an "unsigned long" value, I would use the same data type for a related `const` value. That just means that the compiler will not have to (invisibly) convert between different types when doing the math operations.

``````#define REPORT_CYCLE 100
const unsigned long REPORT_CYCLE = 100; // milliseconds between measurement and reporting cycles
``````

If you are a beginner, you may not have seen `static` variables yet. If you know about them, fine, but if not, they can be replaced by `global` scope variables.

The @Majenko code uses a fixed count of 100 iterations to do the measurement and reporting. That works fine as long as neither the for 10 seconds or every 1/10 second changes. If either of those change, the count limit would also need to be recalculated and changed. Instead, I would use another defined name for how long to do measurement and reporting cycles, and let the compiler handle how many times that actually is.

Doing an `analogWrite()` sets the value (brightness here), which will stay constant until changed again. Since your program only sets a single value, it only needs to be done once. Move that statement to `setup()`.

There is no need to do `Serial.end()` when the reporting is done. That disables serial communication, but is unneeded, if no more `Serial.println()` commands are executed anyway.

To avoid calling `millis()` multiple times in the same 'pass' (in each if test), I like to call it once, and save the result.

Taking the @Majenko code, plus your starting sample, and described changes gets

``````// Intervals in milliseconds
#define REPORT_CYCLE 100
#define REPORT_INTERVAL 10000
unsigned long nextStart, endTime;
int analogInPin = A0;
int LEDpin = 9;           // LED on pin 9

void setup() {
Serial.begin(9600);
analogWrite(LEDpin,255);  // LED brightness
nextStart = millis(); // Time for "right now"
endTime = nextStart + REPORT_INTERVAL;
}

void loop() {
unsigned long now = millis();
if (now < endTime) { // still need to do more reporting
if (now >= nextStart) { // time to get and report another reading
nextStart += REPORT_CYCLE; // When the next reading should be done