Skip to content

Instantly share code, notes, and snippets.

@Koepel
Created November 16, 2016 09:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Koepel/4fd63069a070c74d2e928ade9bc88d67 to your computer and use it in GitHub Desktop.
Save Koepel/4fd63069a070c74d2e928ade9bc88d67 to your computer and use it in GitHub Desktop.
Arduino sketch to calculate how much time is wasted in delays.
// Wasted
// ------
// Show the percentage of cpu time that is wasted in delay().
// ----------------------------------------------------------
//
// 8 nov 2016, by Koepel.
// first version. Public Domain.
//
// 16 nov 2016, by Koepel
// Added more comment. Added fixed delay inside yield().
// Calculate the percentage more flexible, to allow any
// interval time, instead of the fixed 1 minute.
// Tested with Arduino.cc IDE 1.6.12 and Arduino Uno
//
// Just some fun with delay() and millis().
// Call Wasted_init() during setup(),
// and add the code at the bottom.
// Have a serial port open, and it
// will print every minute how much
// precious cpu time is wasted in delays.
//
// The calculation of the percentage can be done
// in other places in your sketch. If you have something running
// a few times a minute or once every few minutes,
// then it can be done there as well.
// The variables can be used without restriction,
// and they don't have to be 'volatile', because
// there is no interrupt involved.
// If the calculation is done somewhere else, be sure to have:
// unsigned long wasted_currentMillis = millis();
//
void setup()
{
Serial.begin( 9600);
// while(!Serial); // for Leonardo
Serial.println( "Started");
Wasted_init(); // <-- add this to setup()
pinMode( 13, OUTPUT);
}
void loop()
{
// Test with delay() or calcPi() and see what the percentage is.
digitalWrite( 13, HIGH);
delay( 100);
// calcPi();
digitalWrite( 13, LOW);
delay( 100);
// calcPi();
}
void calcPi()
{
float x = 1.0;
float pi = 1.0;
for( unsigned long t = 2UL; t < 5000UL; t++)
{
x *= -1.0;
pi += x / ( (2.0 * (float) t) - 1.0);
}
pi *= 4;
// print pi, once in 100 times.
static int cnt;
cnt++;
if( cnt >= 100)
{
cnt = 0;
Serial.println( pi, 8);
}
}
// ---------------------------------------
// Add the following part to your sketch.
// It uses the Serial port to show every minute
// to the serial monitor which percentage of
// precious cpu time was wasted in delays.
//
// It only checks delay(), not delayMicroseconds().
// ---------------------------------------
// The preset value of 77967 is the value for
// an Arduino Uno (in case the init function is not called).
unsigned long wasted_CountsPerSecond = 77967;
unsigned long wasted_Count;
unsigned long wasted_previousMillis;
void Wasted_init()
{
// Calibrate the number of counts.
delay( 100); // wait a little, perhaps serial data is being transmitted.
wasted_Count = 0UL;
delay( 1000);
wasted_CountsPerSecond = wasted_Count;
// Make a fresh start for the next count.
wasted_Count = 0UL;
wasted_previousMillis = millis();
// Serial.print(F( "CountsPerSecond="));
// Serial.println( wasted_CountsPerSecond);
}
// Override the weak function that is called from delay().
// See : https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring.c
void yield()
{
// ----------------------------------------------------
// Begin of code to calculate the percentage
// ----------------------------------------------------
unsigned long wasted_currentMillis = millis();
if( wasted_currentMillis - wasted_previousMillis >= 60000UL) // every minute
{
// Hopefully the calculation will be okay with unsigned long.
// Calculating the interval is even valid in case of a rollover of millis().
// By calculating the interval in seconds, the accuracy drops for short intervals,
// but it makes it possible to use 32-bit unsigned long for longer intervals.
// The "wasted_Count" is multiplied by 100 for the percentage.
unsigned long interval_in_seconds = (wasted_currentMillis - wasted_previousMillis) / 1000UL;
unsigned long wasted_percentage = (wasted_Count * 100UL) / (wasted_CountsPerSecond * interval_in_seconds);
Serial.print(F( "Wasted: "));
Serial.print( wasted_percentage);
Serial.print(F( "%"));
if( wasted_percentage < 2UL) // less then 2% ?
{
// It turns out to be a very small percentage.
// Calculate the actual total delay in milliseconds in this interval.
unsigned long wasted_delay = wasted_Count / (wasted_CountsPerSecond / 1000UL);
Serial.print(F( " ("));
Serial.print( wasted_delay);
Serial.print(F( "ms)"));
}
Serial.println();
// Serial.print(F( "Count="));
// Serial.print( wasted_Count);
// Serial.print(F( ", interval="));
// Serial.print( interval_in_seconds);
// Serial.print(F( "s"));
// Serial.println();
// Set the variables for the next interval
wasted_previousMillis = wasted_currentMillis; // remember current time for next interval
wasted_Count = 0UL; // reset the counter
}
// ----------------------------------------------------
// End of code to calculate the percentage
// ----------------------------------------------------
// An extra fixed delay of 6 microseconds for fast processors.
// This is not needed for AVR chips, but it will do no harm.
// It will reduce the count for the unsigned long counter.
delayMicroseconds( 6);
wasted_Count++; // increment while being in the delay
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment