Continuing the discussion from Fading at different times:
I'm wondering how to implement (if possible) switch case statements with the sketch shared by @jimLee. Would the mapping statements be included with each case or just the program part? Where would you insert the statements for the push button control. For ease, the same sketch includes minor changes, ie: pins changed to 2,3,4,5. Changed profile.addPoint times and extended Profile_ms to 1000ms.
I'm sure there are easier ways but for the sake of knowledge...
What I want to accomplish- Run this program with LEDs chasing in direction A, push a button, and change the direction or pattern/timing of the "fade".
Using Mega2560 board.
#include <multiMap.h>
#include <timeObj.h>
#include <idlers.h>
#define PROFILE_MS 1000 // Total time that the profile spans.
#define CHANGE_MS 4 // How much time between recalculating new brightness values.
#define LED_PIN1 2 // Need pins that have analog out.
#define LED_PIN2 3
#define LED_PIN3 4
#define LED_PIN4 5
// Create a class that takes a time,value profile and plays it as a PWM.
// And, runs in the background.
class mappedAnalog : public idler {
public:
mappedAnalog(multiMap* inMap,int inPin,float inChange,float totalMs);
virtual ~mappedAnalog(void);
void start(float delayMs=0);
virtual void idle(void);
multiMap* ourProfile;
int pin;
int frameMs;
float changeMs;
float profileMs;
timeObj changeTimer;
bool delaying;
};
mappedAnalog::mappedAnalog(multiMap* inMap,int inPin,float inChange,float totalMs) {
ourProfile = inMap;
pin = inPin;
frameMs = 0;
changeMs = inChange;
profileMs = totalMs;
changeTimer.setTime(changeMs,false);
delaying = false;
}
mappedAnalog::~mappedAnalog(void) { }
void mappedAnalog::start(float delayMs) {
if (delayMs>0) {
changeTimer.setTime(delayMs);
delaying = true;
}
hookup();
pinMode(pin,OUTPUT);
frameMs = 0;
changeTimer.start();
}
void mappedAnalog::idle(void) {
float newBright;
if (delaying) {
if(changeTimer.ding()) {
changeTimer.setTime(changeMs);
changeTimer.start();
delaying = false;
}
} else {
if (changeTimer.ding()) {
if (frameMs>=profileMs) {
frameMs = 0;
} else {
frameMs = frameMs + changeMs;
}
newBright = ourProfile->map(frameMs);
analogWrite(pin, round(newBright));
changeTimer.start();
}
}
}
// ********************* Program starts here *********************
multiMap profile; // Your time / brightness profile.
mappedAnalog* LED1; // An LED
mappedAnalog* LED2; // ANother..
mappedAnalog* LED3;
mappedAnalog* LED4; // Notice these are actually just global pointers to LED objects. Make as many as you need.
void setup(void) {
profile.addPoint(2,0); // Build the pofile by adding points (time in ms, brighness value)
profile.addPoint(PROFILE_MS/3,255); // Second point.
profile.addPoint(PROFILE_MS/2,0); // Last point. ( You can actually add as many points as you like. Go crazy! )
LED1 = new mappedAnalog(&profile,LED_PIN1,CHANGE_MS,PROFILE_MS); // Create first LED object. Address of profile, pin num, frame rate, total time for profile.
LED1->start(200); // Fire uip first LED.
LED2 = new mappedAnalog(&profile,LED_PIN2,CHANGE_MS,PROFILE_MS); // Create second LED.
LED2->start(400); // Fire it up with a preset delay before starting.
LED3 = new mappedAnalog(&profile,LED_PIN3,CHANGE_MS,PROFILE_MS); // Third LED
LED3->start(600);
LED4 = new mappedAnalog(&profile,LED_PIN4,CHANGE_MS,PROFILE_MS); // Third LED
LED4->start(800); // And again a delay from time 0 for actual start.
}
void loop(void) {
idle(); // Runs all the background things.
}