Here's my attempt. You'll need my SimpleTimer library http://arduino.cc/playground/Code/SimpleTimer
#include <SimpleTimer.h>
// sequence 1: led on
// sequence 2: led fading on and off
// sequence 3: led blinking with interval 1s
// sequence 4: led blinking with interval 0,5s
// pin 3 = pwm output to led
// pin 2 = input, select button (active low)
SimpleTimer timer;
int ledPin = 3;
int btnPin = 2;
int seq_2_timerId;
int seq_3_timerId;
int seq_4_timerId;
int currSequence = 0; // current running sequence; 0 = no sequence is running, led off
const int NUM_SEQ = 4; // number of implemented sequences
void ledOn() {
digitalWrite(ledPin, HIGH);
}
void ledOff() {
digitalWrite(ledPin, LOW);
}
void ledBlink() {
static boolean isLedOn = false;
if (isLedOn) {
ledOn();
}
else {
ledOff();
}
isLedOn = isLedOn ? false : true;
}
void ledPwm(boolean reset = false) {
static int pwmLevel = 0;
static int pwmStep = 1;
static int maxPwmLevel = 255;
static int pwmDirection = 1;
if (reset) {
pwmLevel = 0;
pwmDirection = 1;
}
analogWrite(ledPin, pwmLevel);
pwmLevel += pwmDirection;
if (pwmLevel >= maxPwmLevel) {
pwmLevel = maxPwmLevel;
pwmDirection = -1;
}
else if (pwmLevel <= 0) {
pwmLevel = 0;
pwmDirection = 1;
}
}
void ledPwmTmrCallback() {
ledPwm();
}
void seq1_start() {
ledOn();
}
void seq1_stop() {
ledOff();
}
void seq2_start() {
ledPwm(true);
timer.enable(seq_2_timerId);
}
void seq2_stop() {
timer.disable(seq_2_timerId);
}
void seq3_start() {
timer.enable(seq_3_timerId);
}
void seq3_stop() {
timer.disable(seq_3_timerId);
}
void seq4_start() {
timer.enable(seq_4_timerId);
}
void seq4_stop() {
timer.disable(seq_4_timerId);
}
void seq1_setup() {
}
void seq2_setup() {
seq_2_timerId = timer.setInterval(5, ledPwmTmrCallback);
}
void seq3_setup() {
seq_3_timerId = timer.setInterval(1000, ledBlink);
}
void seq4_setup() {
seq_4_timerId = timer.setInterval(500, ledBlink);
}
void selectNextSequence() {
currSequence++;
if (currSequence > NUM_SEQ) {
currSequence = 0;
}
switch (currSequence) {
case 0:
seq1_stop();
seq2_stop();
seq3_stop();
seq4_stop();
Serial.println("Off");
break;
case 1:
seq1_start();
seq2_stop();
seq3_stop();
seq4_stop();
Serial.println("Seq 1: led on");
break;
case 2:
seq1_stop();
seq2_start();
seq3_stop();
seq4_stop();
Serial.println("Seq 2: fading on and off");
break;
case 3:
seq1_stop();
seq2_stop();
seq3_start();
seq4_stop();
Serial.println("Seq 3: blink 1s");
break;
case 4:
seq1_stop();
seq2_stop();
seq3_stop();
seq4_start();
Serial.println("Seq 4: blink 0,5s");
break;
}
}
void serialEvent() {
char ch;
ch = Serial.read();
if (ch == 'P') {
selectNextSequence();
}
}
int btnRead() {
return digitalRead(btnPin);
//return (analogRead(btnPin) > 500 ? HIGH : LOW);
}
void btnCheck() {
static int prevState = 0;
static int currState = 0;
currState = btnRead();
if (currState != prevState) {
if (currState == LOW) { // button is active low
selectNextSequence();
}
}
prevState = currState;
}
void setup() {
// hw initialization
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(btnPin, INPUT);
digitalWrite(btnPin, HIGH); // internal pullup
ledOff();
// sequence setup
seq1_setup();
seq2_setup();
seq3_setup();
seq4_setup();
// stop all sequences
seq1_stop();
seq2_stop();
seq3_stop();
seq4_stop();
// button polling routine
timer.setInterval(20, btnCheck);
// print usage
Serial.println("Send P to cycle through sequences.");
}
void loop() {
timer.run();
}
(Compiled and tested on a Arduino UNO board. To be precise, the board didn't have a pushbutton attached to it, but had a fotoresistor instead, so I used it to simulate a button (see commented line in btnRead). This version digitally reads a button, though.)
Usage: connect the led driver to pin 3 (active high); fire up the serial monitor @9600 and send P char to cycle through sequences.
Otherwise, connect an active low switch to pin 2 to achieve the same effect. Keep the serial monitor open to see what sequence it's running.
Improving the code by using an array of function pointers or an array of objects is left as an exercise for the reader ![]()