Petite critique constructive sur la forme :
La structure s’appelle relais, le tableau s’appelle commande alors que physiquement ça représente des volets.
Donc un truc comme cela me semblerait plus adapté
struct Volet {
const byte GPIO;
int count;
unsigned long start;
};
Volet lesVolets[] = {
{ 1, 0, 0},
{ 2, 0, 0},
{42, 0, 0},
{41, 0, 0},
{40, 0, 0},
};
const byte nbVolets = sizeof lesVolets / sizeof *lesVolets ;
Bien sûr quitte à avoir une struct autant franchir le pas et mettre une classe et embarquer les commandes sous forme de fonction dans la classe. Un constructeur approprié simplifierait aussi la déclaration (pas besoin des 0).
Donc un truc comme ça serait plus “propre” et lisible.
class Volet {
public:
const byte broche;
byte compteur;
unsigned long debut;
Volet(const byte gpio) : broche(gpio), compteur(0), debut(0) {}
void begin() {
pinMode(broche, OUTPUT);
digitalWrite(broche, HIGH);
}
void clicStart(byte nbImpulsions) {
compteur = nbImpulsions * 2;
debut = millis();
}
// autres commandes - je vous laisse faire
};
Volet lesVolets[] { 1, 2, 42, 41, 40 };
const byte nbVolets = sizeof lesVolets / sizeof *lesVolets;
Et par exemple le setup() devient
void setup() {
Serial.begin(115200);
for (Volet &volet : lesVolets) volet.begin();
lesVolets[0].clicStart(12);
lesVolets[2].clicStart(20);
lesVolets[4].clicStart(15);
}
On a ainsi une jolie abstraction des volets et le code principal utilise des commandes de haut niveau et lisibles pour faire quelque chose (faudrait changer clicStart pour avoir en fait une fonction monter, descendre et stop pour ne pas avoir à se soucier du nombre de clicks et une fonction générale qui fait tourner la machine à état). Je rajouterai aussi un const char * dans la classe pour donner un nom au volet qui servira dans l’interface web.
PS: tapé depuis mon iPhone donc pas sûr qu’il n’y ait pas une typo quelque part…