// Forum: https://forum.arduino.cc/t/using-analogwrite-and-getting-strange-initial-results/1260900/
// This Wokwi project: https://wokwi.com/projects/398128680494393345
// SIM Day Night Control Rel.3 ver.0
#define initRed 0
#define initGrn 0
#define initBlu 200
int prevRedPWM = initRed; // start with 6:00 AM values
int prevGrnPWM = initGrn;
int prevBluPWM = initBlu;
int RedPWMTarget, GrnPWMTarget, BluPWMTarget; // PWM variables
float diffRed, diffGrn, diffBlu;
int iter, maxiter; // time/schedule variables
unsigned long fadeTime;
unsigned long currentTime, beginTime, loopBegin;
int RedOut = 11; // GPIO ouput pins in use (no input GPIO pins) 9,11,10
int GrnOut = 10;
int BluOut = 9;
//test bool readln_PWMColors(int& Value1, int& Value2, int& Value3);
bool doneRed = false, doneGrn = false, doneBlu = false; // status boolean variables
int RedPWM = initRed;
int GrnPWM = initGrn;
int BluPWM = initBlu;
const unsigned long deltaSchedule = 5000ul;
const int indexMax = 10;
int simData [indexMax] [3] = {
// R G B
{ 0, 0, 200}, // night
{ 0, 0, 200},
{ 50, 0, 200},
{ 254, 84, 0}, // sunrise
{ 254, 84, 0},
{ 245, 245, 245}, // daylight
{ 245, 245, 245},
{ 245, 245, 245},
{ 152, 0, 217}, // sunset
{ 152, 0, 217}
};
// =======
// setup
// =======
void setup() {
Serial.begin(9600);
fadeTime = (unsigned long) ((deltaSchedule / 256) - 1);
maxiter = deltaSchedule / fadeTime;
pinMode(RedOut, OUTPUT); // GPIO ouput pins in use (no input GPIO pins)
pinMode(GrnOut, OUTPUT);
pinMode(BluOut, OUTPUT);
Serial.print("Test blinks... ");
for(int b=255; b>0; b/=2)
{
analogWrite(RedOut, b);
analogWrite(GrnOut, b);
analogWrite(BluOut, b);
delay(200);
analogWrite(RedOut, 0);
analogWrite(GrnOut, 0);
analogWrite(BluOut, 0);
delay(200);
}
Serial.println("Done");
delay(1000);
// Set up initial state
analogWrite(RedOut, initRed); // output initial PWM values
analogWrite(GrnOut, initGrn);
analogWrite(BluOut, initBlu);
}
// ======
// loop
// ======
void loop() {
// Wait for color change command,,,
//test### while ( !Serial.available());
for (int index = 0; index < indexMax; index++) { //test
// test### Get target PWM connands from test/sim array
// Get target PWM values for LED colors from serial port.
// test### readln_PWMColors(RedPWMTarget, GrnPWMTarget, BluPWMTarget);
RedPWMTarget = simData [index][0]; //test###
GrnPWMTarget = simData [index][1]; //test###
BluPWMTarget = simData [index][2]; //test###
// Calculate incremental differences to target PWM values
diffRed = (float)(RedPWMTarget - prevRedPWM) / (float)maxiter; // Calculate PWM changes for Red fade
diffGrn = (float)(GrnPWMTarget - prevGrnPWM) / (float)maxiter; // ditto for Green fade
diffBlu = (float)(BluPWMTarget - prevBluPWM) / (float)maxiter; // ditto for Blue fade
// initialize flags (doneXxx)mand times (xxxxTime/xxxxBegin)
doneRed = false; doneGrn = false; doneBlu = false; // set color output status
beginTime = millis(); currentTime = millis(); loopBegin = millis(); iter = 1;
//while elapsed time is less than the defined time for each loop
while (currentTime - loopBegin <= deltaSchedule)
{
currentTime = millis();
if (currentTime - beginTime >= fadeTime) { // fade from old to new PWM values in the current timeslice
// while elapsed time is less than the calculated fade time
// Red PWM
if (!doneRed) { // not done displaying Red
RedPWM = (int)((float)prevRedPWM + ((float)iter * diffRed)); // calculate next(?previous) PWM value
if (abs(RedPWM - RedPWMTarget) <= 1) { // check for end of fade
RedPWM = RedPWMTarget; // set PWM value = target
doneRed = true; // set flag indicating finished fading to target PWM value
}
}
// Grn PWM
if (!doneGrn) {
GrnPWM = (int)((float)prevGrnPWM + ((float)iter * diffGrn));
if (abs(GrnPWM - GrnPWMTarget) <= 1) { // check for end of fade
GrnPWM = GrnPWMTarget;
doneGrn = true;
}
}
// Blu PWM
if (!doneBlu) {
BluPWM = (int)((float)prevBluPWM + ((float)iter * diffBlu));
if (abs(BluPWM - BluPWMTarget) <= 1) { // check for end of fade
BluPWM = BluPWMTarget;
doneBlu = true;
}
}
analogWrite(RedOut, RedPWM); // output intermediate/final PWM values
analogWrite(GrnOut, GrnPWM);
analogWrite(BluOut, BluPWM);
iter++; // test###
beginTime = millis(); // set beginning of next timeslice
} // for fading time slice
} // while in current scenario
prevRedPWM = RedPWM;
prevGrnPWM = GrnPWM;
prevBluPWM = BluPWM;
} // end fade command (while/for)
RedPWM = 0; GrnPWM = 0; BluPWM = 0;
}common anode
common cathode