Last active
August 29, 2015 14:20
-
-
Save ckxng/086929a6922f4e45e3d6 to your computer and use it in GitHub Desktop.
Asynchronous Arduino LED Blinking
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __ASYNCBLINK_H | |
#define __ASYNCBLINK_H | |
namespace ckxng { | |
namespace asyncBlink { | |
namespace _impl { | |
/*** | |
*** STRUCTURE DEFINITIONS | |
***/ | |
/** | |
* A data structure for holding a sequence of pins and their states. This | |
* allows blink to track the states of multiple pins simultaneously. | |
* \param pin the pin number on the board. This pin should already | |
* be set to OUTPUT mode. | |
* \param currentState will begin as LOW, then toggle between LOW and | |
* HIGH when blink(pin,ms) is called after ms milliseconds | |
* \param lastChangeTimestamp the timestamp in milliseconds of the | |
* last time blink(pin,ms) changed the state of the LED | |
* \param next a pointer to the next pin, or NULL | |
*/ | |
struct pinList { | |
int pin = 0; | |
int currentState = 0; | |
long lastChangeTimestamp = 0; | |
pinList *next = 0; | |
}; | |
/*** | |
*** GLOBAL VARIABLES | |
***/ | |
pinList *pinData = new pinList(); /** holds the pin data for blink */ | |
/*** | |
*** FUNCTION DECLARATIONS | |
***/ | |
/** | |
* Will cause a LED on pin to change state HIGH->LOW or LOW->HIGH if the | |
* state was last changed at least ms milliseconds ago. | |
* \param pin the pin number on the board. This pin should already | |
* be set to OUTPUT mode. | |
* \param ms the number of milliseconds that must have passed before | |
* changing the state | |
*/ | |
void blink(int pin, int ms); | |
/** | |
* Will cause a LED on pin to change state HIGH->LOW or LOW->HIGH if the | |
* state was last changed at least ms milliseconds ago. This function | |
* is called by blink(pin,ms) and is typically not called directly. | |
* \param pin the pin number on the board. This pin should already | |
* be set to OUTPUT mode. | |
* \param ms the number of milliseconds that must have passed before | |
* changing the state | |
* \param node the linked list that holds pin data | |
*/ | |
void blink(int pin, int ms, pinList *node); | |
} | |
using _impl::blink; | |
} | |
} | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "asyncBlink.h"; | |
namespace ckxng { | |
namespace async { | |
namespace _impl { | |
void blink(int pin, int ms) { | |
blink(pin, ms, pinData); | |
} | |
void blink(int pin, int ms, pinList *node) { | |
/* something's wrong, abort! */ | |
if(node == NULL) { | |
return; | |
/* we found the right node for this pin */ | |
} else if(node->pin == pin) { | |
long now = millis(); | |
/* flip the pin and set the timestamp if sufficient time has passed */ | |
if(node->lastChangeTimestamp + ms < now) { | |
node->lastChangeTimestamp = now; | |
node->currentState = node->currentState==HIGH?LOW:HIGH; | |
digitalWrite(pin, node->currentState); | |
} | |
/* end of the list, append the pin to the list and recurse to it */ | |
} else if(node->next == NULL) { | |
node->next = new pinList(); | |
node->next->pin = pin; | |
node->next->currentState = LOW; | |
blink(pin, ms, node->next); | |
/* search for the correct pin by recursing to the next node */ | |
} else { | |
blink(pin, ms, node->next); | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// set clock to 1MHz; 1 microsecond = 1 clock cycle | |
#define F_CPU 1000000L | |
#include "asyncBlink.h" | |
int led = 13; | |
void setup() { | |
pinMode(led, OUTPUT); | |
Serial.begin(9600); | |
} | |
void loop() { | |
ckxng::asyncBlink::blink(led, 100); | |
delay(10); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment