Alors première remarque : voila qui est bien mieux organisé et bien plus logique que ta première version
Les opérations sont bien séparées, la loop est très facile à comprendre, bravo !
Par contre il y a une erreur : dans tes conditions, tu utilises &. Il faudrait utiliser &&.
Le premier (& tout seul) réalise une opération logique ET bit à bit entre deux variables, ça s'emploie comme on emploierait un autre opérateur comme + ou - par exemple, ce qui n'est pas tu tout ce que tu cherches à faire. Dans ton cas ça doit fonctionner, car les deux éléments dont tu réalises le ET bit à bit étant des conditions, donc des booléens, seul le premier bit compte, et ça marche, mais c'est un coup de chance !
Le second en revanche (&&) réalise un ET logique entre deux conditions, ce qui est très exactement ce que tu veux faire.
Si tu avais besoin de conditions OU il faudrait de la même manière employer || et non pas |
Pour ce qui est de simplifier la régulation en tirant partie des tableaux, oui en effet c'est très exactement la chose à faire, et c'était dans cette optique que je te disais à la réponse #10 de regarder mon code dans l'autre post : maintenant que (presque) toutes tes variables utiles sont dans des tableaux, il suffit de n'écrire qu'une seule fois le code de la régulation, et de placer ce code dans une boucle for qui va permettre d'incrémenter l'index des tableaux et de réaliser les tests autant de fois que nécessaire. Je dis "presque" car il te reste les numéros de broches des relais qui sont dans des variables séparées... Tu devrais facilement pourvoir convertir cela en un tableau sur le même modèle que les consignes 
Il sera ensuite encore possible de simplifier la fonction en organisant le "if" qui vérifie l'horaire différemment, mais ça on verra après 
Ensuite, l'affichage... Alors là par contre, tu t'es vraiment compliqué la vie à refaire tous les tests que tu as déjà fait dans la régulation, c'est dommage et inutile. Il serait bien plus simple de simplement faire un digitalRead(RELAIS_1) pour savoir si le relais 1 est ON ou OFF plutôt que de refaire les tests.
Et pour l'affichage des consignes jour/nuit, même simplification possible que dans la régulation.
Allez, un tuyau pour simplifier ça : utiliser un troisième tableau de consignes, rempli en début de loop() avec les valeurs soit du tableau de jour, soit du tableau de nuit, en fonction de l'heure. Ainsi le test sur l'heure n'est fait qu'une seule fois au lieu de le faire à chaque terrarium dans la régulation, puis à chaque terrarium dans l'affichage.
Par exemple tu vas créer un tableau de plus et une fonction :
byte Consigne[8];
void choixConsigne()
{
if (now.hour() > 9 & now.hour() < 21) {
// SI L'HEURE EST COMPRISE ENTRE 9H ET 21H
for (byte i=0; i<8; i++) {
Consigne[i] = Cons_jour[i];
}
}
else {
// SI L'HEURE EST COMPRISE ENTRE 21H ET 9H
for (byte i=0; i<8; i++) {
Consigne[i] = Cons_nuit[i];
}
}
}
Et bien entendu il faut appeler cette fonction choixConsigne() en début de loop() de manière à ce que le tableau Consigne soit à jour à tout moment.
Ensuite il suffit dans tous tes tests de supprimer le test de l'heure puisque qu'il est déjà fait et d'utiliser seulement le tableau Consigne[].
Entre ça et tirer partie des tableaux pour ta fonction de régulation, tu va diviser presque par deux la longueur de ton programme
Ça sera bien plus simple à lire et à débugger.
Quand un afficheur lcd affiche seulement quelques carrés en début de première ligne, c'est que son initialisation n'est pas faite. Donc soit tu as oublié de mettre lcd.begin(16,2) dans le setup(), soit la déclaration des broches n'est pas correcte.