Diseño Controlador Acuario

Hola voy a hacer mi aporte:
En esta parte del código:

void loop() {
 unsigned long currentMillis = millis();
 button.tick();
 LeeEncoder(0, 7, 1, 1);  // Lee el enconder de 0 a 7, de a 1 paso y con tope final.

 if (currentMillis % 6000 < 5) {  //  Si el resto de dividir currentMillis por 6000 da menos que 5...
 ImprimeFecha();
 ImprimeHora();
 ImprimeTemp();
 }
}

se va a cumplir cuando sea por ejemplo 6000,6001,6002,6003,6004 y en el "mejor de los casos" pero en el transcurso se cumple y se va a actualizar como 20 veces aquí un ejemplo de lo que digo:
Prueba1.png
Ahora asi como muestra por serial va actualizar en la pantalla para lo cual presentó algo que puede ser mejor tendrías que añadir las siguientes líneas y borra en el que tu tienes, espero se entienda

#define tiempoPresentarDatos 6000UL // Tiempo al que se quiera realizar las acciones ejemplo 6s (1000ms = 1s)
unsigned long tiempoActualDatos = 0;

void loop() {
 if (millis() - tiempoActualDatos >= tiempoPresentarDatos) { // Si el tiempo actual menos el tiempo anterior  es mayor o igual a 6 segundos 
 tiempoActualDatos = millis(); // Actualiza el tiempo Actual
 //Resto del codigo que quieras que se cumpla cada 6 segundos
 }
}

Prueba2.png
Ahora también por ejemplo en esta parte utilizas una función y en el cual en una condición la utilizas para para comprobar si tiene tope o no

void LeeEncoder(int ROTARYMIN, int ROTARYMAX, int ROTARYSTEPS, int ROTARYTOPE )
{ 
  encoder.tick();  // Lee el encoder y actualiza el puntero. La librería lleva la cuenta desde 0.
  newPos = encoder.getPosition() * ROTARYSTEPS; // Asigna a newPos el puntero del encoder multiplicado por los pasos. 

  if (ROTARYTOPE == 1) {  // Si el rotor tiene tope entonces no se pasa de valor
    if (newPos < ROTARYMIN) {    // Solo si el puntero es menor a Valor Mínimo ->
      encoder.setPosition(ROTARYMIN / ROTARYSTEPS);  // Se fija el puntero al valor mínimo por los pasos
      newPos = ROTARYMIN;  
    }
    if (newPos > ROTARYMAX) {   // Solo si el puntero es mayor a Valor Máximo ->
      encoder.setPosition(ROTARYMAX / ROTARYSTEPS);  // Se fija el puntero al valor mínimo por los pasos
      newPos = ROTARYMAX;

    }
  }

  if (ROTARYTOPE == 0) {  // Si el rotor SI tiene tope entonces se pasa del valor máximo al mínimo y viceversa.
    if (newPos < ROTARYMIN) {  // Solo si el puntero es menor a Valor Mínimo ->
      encoder.setPosition(ROTARYMAX / ROTARYSTEPS);
      newPos = ROTARYMAX;  // Entonces el puntero saltará del mínimo al máximo

    }
    if (newPos > ROTARYMAX) { // Solo si el puntero es mayor al Valor Máximo ->
      encoder.setPosition(ROTARYMIN / ROTARYSTEPS);
      newPos = ROTARYMIN;  // Entonces el puntero saltará del máximo al  mínimo.
    }
  }
}

lo que veo un poco innecesario ya que ese no va a cambiar en el transcurso del funcionamiento si no solo cuando se configura por lo que creo que se podría utilizar de esta forma como ejemplo

#define encoderTope 1
void loop() {

#if encoderTope == 1
 if (newPos < ROTARYMIN) {    // Solo si el puntero es menor a Valor Mínimo ->
 encoder.setPosition(ROTARYMIN / ROTARYSTEPS);  // Se fija el puntero al valor mínimo por los pasos
 newPos = ROTARYMIN;
 }
 if (newPos > ROTARYMAX) {   // Solo si el puntero es mayor a Valor Máximo ->
 encoder.setPosition(ROTARYMAX / ROTARYSTEPS);  // Se fija el puntero al valor mínimo por los pasos
 newPos = ROTARYMAX;
 }
#else 
 if (newPos < ROTARYMIN) {  // Solo si el puntero es menor a Valor Mínimo ->
 encoder.setPosition(ROTARYMAX / ROTARYSTEPS);
 newPos = ROTARYMAX;  // Entonces el puntero saltará del mínimo al máximo
}
 if (newPos > ROTARYMAX) { // Solo si el puntero es mayor al Valor Máximo ->
 encoder.setPosition(ROTARYMIN / ROTARYSTEPS);
 newPos = ROTARYMIN;  // Entonces el puntero saltará del máximo al  mínimo.
 }
#endif
}

Qué te parece @surbyte sería una mejor forma o no haría gran diferencia

Prueba1.png

Prueba2.png