Loop stuck after specific number of iterations fails to reach end condition

Hello people!

I am building a riparium (aquarium with above water plants) as an ecosystem, and in order to do so I set out to write a relatively simple program (and circuit, UNO R3) to have LED strips simulate a diurnal rhythm, including hue changes throughout the day.

I have come a long way, from calculating steps by hand and coding them in by hand, to a semi-automated piece of code that just requires me to give certain milestones and it will take care of the steps and changes. However, as you might have guessed from my presence here I have run into a problem that several hours of searching and my relative inexperience couldn’t solve;

The code below does not give any error, but the hue will be stuck in the first for loop. More specifically, it gets stuck at iteration 3589 with the last value printed being 359 (not 3590). Without an error message it keeps running, but will not reach the end condition of the loop. My first search led me to believe it is some sort of overflow issue, my second thought was that it is some sort of accumulation of data that reaches a limit (explaining the unfinished last print?).

// This program is intended to simulate a diurnal rhythm with a colour changing spectrum over RGB ledstrips (for my riparium).
// Each loop dictates a set of RGB value changes between two set milestones.
// Problem: The program uploads and runs but p never reaches 3600 to end the first loop, but instead stops reporting at 3589, reporting the last value as 359 (no 0). Some kind of data accumulation going on?

#define REDPIN 10
#define GREENPIN 9
#define BLUEPIN 11
#define MINIM 20      // prevents flickering
#define SPEED 500     // for testing speed-up
#define TSTEP 1000    // iteration time step
#define HOURSTEPS (36*100)/(TSTEP/1000) // simplified to hours

void setup() {
  pinMode(REDPIN, OUTPUT);
  pinMode(GREENPIN, OUTPUT);
  pinMode(BLUEPIN, OUTPUT);
  Serial.begin(9600);
}


void loop() {

  int earlymorning[]    = {20, 0, 20}; // Milestone colours throughout the day
  int latemorning[]     = {30, 20, 40};
  int midday[]          = {110, 70, 40};
  int earlyafternoon[]  = {250, 200, 180};
  int lateafternoon[]   = {200, 180, 180};
  int night[]           = {40, 50, 80};
  int r, g, b;
  unsigned long p;

  // fade from morning pink to sky blue - Early Morning
  for (p = 0; p <= (HOURSTEPS); p++) {
    r = earlymorning[0] + round(p / (HOURSTEPS) / (latemorning[0] - earlymorning[0])); // Define stepsize between milestones and execute countup to generate colour values based on p
    g = earlymorning[1] + round(p / (HOURSTEPS) / (latemorning[1] - earlymorning[1]));
    b = earlymorning[2] + round(p / (HOURSTEPS) / (latemorning[2] - earlymorning[2]));
    analogWrite(REDPIN, max(r, MINIM));     // Consistency check to ensure LEDs are shut off under minimum value to prevent flickering
    analogWrite(GREENPIN, max(g, MINIM));
    analogWrite(BLUEPIN, max(b, MINIM));
    delay(round(TSTEP / SPEED));            // Timed delay. Division over SPEED for testing purposes, will be set to 1 in practice
    Serial.println(p);                      // Feedback to try and find what is going wrong

  }

  // fade from sky blue to soft yellow - Late Morning
  for (p = 0; p <= (HOURSTEPS); p++) {
    r = latemorning[0] + round(p / ((HOURSTEPS) / (midday[0] - latemorning[0])));
    g = latemorning[1] + round(p / ((HOURSTEPS) / (midday[1] - latemorning[1])));
    b = latemorning[2] + round(p / ((HOURSTEPS) / (midday[2] - latemorning[2])));
    analogWrite(REDPIN, max(r, MINIM));
    analogWrite(GREENPIN, max(g, MINIM));
    analogWrite(BLUEPIN, max(b, MINIM));
    delay(round(TSTEP / SPEED));
  }


  // fade from soft yellow to full sun - Midday
  for (p = 0; p <= (2 * HOURSTEPS); p++) {
    r = midday[0] + round(p / ((2 * HOURSTEPS) / (earlyafternoon[0] - midday[0])));
    g = midday[1] + round(p / ((2 * HOURSTEPS) / (earlyafternoon[1] - midday[1])));
    b = midday[2] + round(p / ((2 * HOURSTEPS) / (earlyafternoon[2] - midday[2])));
    analogWrite(REDPIN, max(r, MINIM));
    analogWrite(GREENPIN, max(g, MINIM));
    analogWrite(BLUEPIN, max(b, MINIM));
    delay(TSTEP / SPEED);
  }



  // midday delay - Midday (cont.)
  for (p = 0; p <= (6 * HOURSTEPS); p++) {
    delay(TSTEP / (SPEED));
  }

  // fade from full sun to calm sky - Early Afternoon
  for (p = 0; p <= (2 * HOURSTEPS); p++) {
    r = earlyafternoon[0] + round(p / ((2 * HOURSTEPS) / (lateafternoon[0] - earlyafternoon[0])));
    g = earlyafternoon[1] + round(p / ((2 * HOURSTEPS) / (lateafternoon[1] - earlyafternoon[1])));
    b = earlyafternoon[2] + round(p / ((2 * HOURSTEPS) / (lateafternoon[2] - earlyafternoon[2])));
    analogWrite(REDPIN, max(r, MINIM));
    analogWrite(GREENPIN, max(g, MINIM));
    analogWrite(BLUEPIN, max(b, MINIM));
    delay(TSTEP / SPEED);
  }



  // fade from calm sky to moonlight - Late Afternoon
  for (p = 0; p <= (2 * HOURSTEPS); p++) {
    r = lateafternoon[0] + round(p / ((2 * HOURSTEPS) / (night[0] - lateafternoon[0])));
    g = lateafternoon[1] + round(p / ((2 * HOURSTEPS) / (night[1] - lateafternoon[1])));
    b = lateafternoon[2] + round(p / ((2 * HOURSTEPS) / (night[2] - lateafternoon[2])));
    analogWrite(REDPIN, max(r, MINIM));
    analogWrite(GREENPIN, max(g, MINIM));
    analogWrite(BLUEPIN, max(b, MINIM));
    delay(TSTEP / SPEED);
  }


  // fade from moonlight to midnight - Night
  for (p = 0; p <= (2 * HOURSTEPS); p++) {
    r = night[0] + round(p / ((2 * HOURSTEPS) / (0 - night[0])));
    g = night[1] + round(p / ((2 * HOURSTEPS) / (0 - night[1])));
    b = night[2] + round(p / ((2 * HOURSTEPS) / (0 - night[2])));
    analogWrite(REDPIN, max(r, MINIM));
    analogWrite(GREENPIN, max(g, MINIM));
    analogWrite(BLUEPIN, max(b, MINIM));
    delay(TSTEP / SPEED);
  }

  // night delay - Night (cont.)
  for (p = 0; p <= (8 * HOURSTEPS); p++) {
    analogWrite(REDPIN, 0);
    analogWrite(GREENPIN, 0);
    analogWrite(BLUEPIN, 0);
    delay(TSTEP / (SPEED));
  }

}

After experimenting for several hours (unsigned values and such) I am not any further in understanding what is going wrong, and was hoping this community might be able to spot the stupid thing I did.

You have only one Serial.print statement in that entire sketch so you don't know that it has got stuck. It has probably simply left the part with the Serial.print statement and dropped into a few more delay() statements.
Add a few more Serial.print statements to track its behaviour.

Good suggestion. Previously had them in, a couple of de-bugging experiments ago, but narrowed it down to the first loop. Added them in the other loops again just now, same behaviour. It does not appear to be a reporting delay, nor would it explain the fixed hue.

I guess here you get a divide by 0 issue:

b = latemorning[2] + round(p / ((HOURSTEPS) / (midday[2] - latemorning[2])));

both midday[2] and latemorning[2] have the value 40.

Thank you! Yes, that makes total sense. Extra painful because the math part of this coding adventure was the one thing I was supposed to be able to do..

Thank you again for your help!