I was bored this evening - so here's the same old' millis() blink - but showing different on/off durations.
Indenting has been pushed - to help identify the separate blocks of code!
Also demonstrates conditional compilation with #define #ifdef and #endif
//----------------------------------------------
// BLINK ON-BOARD LED using millis()
// Demonstrating variable length on/off duration.
// Also illustrate using a function() without parameters
//----------------------------------------------
#define SERIAL_COMMENTS 115200 //comment-out, UNDEFine or delete if not required
//----------------------------------------------
#define LED_pin 13 // ths inbuilt UNO LED
//----------------------------------------------
unsigned long state_started_at;
// these /could/ be a smaller data type - sufficient to hold the durations
unsigned long blink_on_duration = 100; // mSecs LED on
unsigned long blink_off_duration = 1000; // mSecs LED off
bool LED_state = LOW; // initial state will be toggled as part of setup()
//----------------------------------------------
// set the LED pin direction to OUTPUT, and enable Serial if it is needed
// then send the initial LED_state out to the LED
//----------------------------------------------
void setup() {
pinMode (LED_pin, OUTPUT);
#ifdef SERIAL_COMMENTS // these lines can be deleted if you understand the code
// ensure serial is opened -before- calling toggle - so the LED_state can be displayed !
Serial.begin(SERIAL_COMMENTS);
#endif
toggle_LED(); // call a function to invert the LED_state
}
//----------------------------------------------
void loop() {
// depending on prevailing state and period - toggle LED to the 'other' state
if (LED_state) { // if the LED state is currently ON
// and the ON duration has elapsed
if (millis() - state_started_at >= blink_on_duration) {
#ifdef SERIAL_COMMENTS // these lines can be deleted if you understand the code
Serial.print("ON duration elapsed...");
#endif
toggle_LED();
}
} else { // then, the LED state must be OFF
// and the OFF duration has elapsed
if (millis() - state_started_at >= blink_off_duration) {
#ifdef SERIAL_COMMENTS // these lines can be deleted if you understand the code
Serial.print("OFF duration elapsed...");
#endif
toggle_LED();
}
}
}
//----------------------------------------------
// change the LED state from on->off and vice-versa with each call
//----------------------------------------------
void toggle_LED() {
LED_state = !LED_state; // invert the LED_state variable
#ifdef SERIAL_COMMENTS // these lines can be deleted if you understand the code
//------------------------
if (LED_state)
Serial.println ("TURN ON");
else
Serial.println ("TURN OFF");
#endif
//------------------------
// start a new duration for current LED_state
state_started_at = millis();
digitalWrite(LED_pin, LED_state); // push it out to the LED
}
//----------------------------------------------
Personally I would favour something like this
const byte ledPin = 13;
const unsigned long durations[] = {1000, 100};
byte indexToDurations = 0;
unsigned long startTime;
void setup()
{
pinMode(ledPin, OUTPUT);
startTime = millis();
}
void loop()
{
if (millis() - startTime >= durations[indexToDurations])
{
digitalWrite(ledPin, !digitalRead(ledPin));
startTime = startTime + durations[indexToDurations];
indexToDurations = !indexToDurations;
}
}
Yes, i agree if the purpose is solely to perform on/off blinking, but I feel it introduces too many skills inline for a beginner. - Indexing, arrays etc.
(I did consider folding the conditional block into a single line, but figured leaving it open would help newbies see the logoc more easily)
Most are looking for an understanding of why/how mills() can replace delay()
Good shot though, everything helps beginners grasp a bit more.
Cheers.
The inclusion of an array and an index index was deliberate as, I assume, was your use of a function and the scary looking #defines and #ifdefs, to say nothing of the truly nutty formatting.
For serial comments consider something like this:
// DebugMacros.h
/* Example of use:
#define DEBUG // <-----<<<< this line must appear before the include line
#include <DebugMacros.h>
*/
//If you comment the line: #define DEBUG
//The Macro lines are defined as blank, thus would be ignored by the compiler.
//If the line is NOT commented, these macros will be included in the sketch.
// examples:
// This converts to >>>>-----> This OR a Blank Line.
//---–----------------------------------------------------------------------------------------
// DPRINTLN("Testing123"); >>>>-----> Serial.println("Testing123");
// DPRINTLN(0xC0FFEEul,DEC); >>>>-----> Serial.println(0xC0FFEEul,DEC);
// DPRINTLN(12648430ul,HEX); >>>------> Serial.println(12648430ul,HEX);
// DPRINTLNF("This text came from flash"); Serial.println(F("This text came from flash"));
// DPRINT(myVariable); >>>>-----> Serial.print(myVariable);
// DELAY(100); >>>>-----> delay(100);
// SERIALBEGIN(9600); >>>>-----> Serial.begin(9600);
// PINMODE(13,OUTPUT); >>>>-----> pinMode(13,OUTPUT);
// TOGGLEd13; >>>>-----> PINB = 0x20; // D13 Toggle,for UNO ONLY
#ifdef DEBUG
//#define DPRINT(args...) Serial.print(args) //OR use the following syntax:
#define SERIALBEGIN(...) Serial.begin(__VA_ARGS__)
#define DPRINT(...) Serial.print(__VA_ARGS__)
#define DPRINTLN(...) Serial.println(__VA_ARGS__)
#define DRINTF(...) Serial.print(F(__VA_ARGS__))
#define DPRINTLNF(...) Serial.println(F(__VA_ARGS__)) //Printing text using the F macro
#define DELAY(...) delay(__VA_ARGS__)
#define PINMODE(...) pinMode(__VA_ARGS__)
#define TOGGLEd13 PINB = 0x20 //For the UNO only
#else
#define SERIALBEGIN(...) //blank line
#define DPRINT(...) //blank line
#define DPRINTLN(...) //blank line
#define DPRINTF(...) //blank line
#define DPRINTLNF(...) //blank line
#define DELAY(...) //blank line
#define PINMODE(...) //blank line
#define TOGGLEd13 //blank line
#endif
//***************************************************************
Consider this kind of format for updating a timing variable.
while ( currentMillis - millisOne >= delayTime )
{
millisOne = millisOne + delayTime;
}