OK Je récapitule:
On se fiche des objets, ce qui compte c'est l'appui sur le bouton et la progression du tapis
Vous êtes capable de mesurer des ticks pour l'avancée du tapis.
Si on dit qu'à l'instant T0 on est au tick 0 et on appuie sur le bouton alors aux ticks T350 , T425, T1100, T1600 et T2500 l'objet se trouvera en face d'une station de contrôle et il faut que l'unique Arduino qui compte les ticks active un pin correspondant à la station à ce moment là.
Donc disons qu'on appuie sur le bouton à l'instant Tn, il faut alors mémoriser que à
Tn+350 on active la pin S1 pendant x ms pour le batch 1
Tn+425 on active la pin S2 pendant x ms pour le batch 1
Tn+1100 on active la pin S3 pendant x ms pour le batch 1
Tn+1600 on active la pin S4 pendant x ms pour le batch 1
Tn+2500 on active la pin S5 pendant x ms pour le batch 1
et suivre ces points clés. Quand un point clé est atteint, alors on traite l'action et on l'enlève de la liste des points clés.
Maintenant disons que j'appuie sur le bouton à l'instant Tp alors il faut rajouter à la liste des points clés que à
Tp+350 on active la pin S1 pendant x ms pour le batch 2
Tp+425 on active la pin S2 pendant x ms pour le batch 2
Tp+1100 on active la pin S3 pendant x ms pour le batch 2
Tp+1600 on active la pin S4 pendant x ms pour le batch 2
Tp+2500 on active la pin S5 pendant x ms pour le batch 2
et toujours comparer le tick courant avec la liste des ticks importants
p peut se produire avant n+2500 donc on a plusieurs batch possibles en cours
j'ai bon ce coup ci ??
--> si vous pouvez avoir 10 objets au max sur la chaîne, comme chaque objet génère 5 ticks à surveiller, ça veut dire que votre tableau des ticks à surveiller doit compter au max 5x10= 50 entrées.
le programme est alors assez simple, c'est typiquement une définition de programme qui se prête bien à la programmation par machine à états (cf mon tuto éventuellement)
- le setup() initialise tout
- la loop surveille les évènements: il y en a 2 importants:
- Soit l'appui sur le bouton
- Soit un nouveau tick
--> lors de l'appui sur le bouton, on passe au batch suivant et il faut rajouter à la liste des ticks à surveiller les 5 valeurs calculées en fonction du tick en cours
--> lors d'un nouveau tick, il faut comparer la valeur courante avec tous les ticks importants et activer la pin associée si c'est reconnu comme un tick critique et dans ce cas sortir ce tick de la liste des ticks à surveiller.
==> ça veut dire que le tableau (ou liste) des ticks à surveiller doit comporter au moins le N° séquentiel du tick qui le déclenchera, le N° de la station/pin à activer (et éventuellement un N° de batch). Donc ce serait un tableau de structure.
pour être simple et éviter de trier la liste ou sortir des objets de la liste, la structure pourrait contenir un booléen qui dit si cette entrée a été traitée. on le met à false au moment de la création puis quand on arrive à ce tick et qu'on a exécuté la commande on le passe à true. Cette entrée devient donc dispo pour la prochaine fois où on doit insérer quelque chose dans la liste. (la fonction d'insertion des 5 ticks importants parcours le tableau et regarde si cette position dans le tableau est encore active)
sans tout coder pour vous, ça pourrait ressembler à cela:
struct tickImportant_t {
uint32_t tickDeclencheur;
uint32_t numeroDuBatch;
uint8_t numeroStation;
boolean entreeDisponible;
};
const uint8_t pinDesStations[] = {3, 4, 5, 6, 7};
const uint8_t nombreDeStations = sizeof(pinDesStations) / sizeof(pinDesStations[0]);
const uint16_t ticksRelatifDesStations[nombreDeStations] = {350u, 425u, 1100u, 1600u, 2500u};
const uint32_t dureeActivationStation = 20ul; // 20ms
const uint8_t nombreMaxDeBatchEnCours = 10;
const uint8_t nombreDeTicksASurveiller = nombreDeStations * nombreMaxDeBatchEnCours;
tickImportant_t tableauDesTicksASurveiller[nombreDeTicksASurveiller];
uint32_t bacthCourant;
uint32_t tickCourant;
void nouveauTick()
{
boolean attenteNecessaire = false;
tickCourant++;
// a-t-on des éléments à traiter
for (uint8_t indexTick = 0; indexTick < nombreDeTicksASurveiller; indexTick++) {
if (tableauDesTicksASurveiller[indexTick].entreeDisponible == false) {
if (tickCourant >= tableauDesTicksASurveiller[indexTick].tickDeclencheur) {
Serial.print(F("Batch "));
Serial.print(tableauDesTicksASurveiller[indexTick].numeroDuBatch);
Serial.print(F(" arrive station "));
Serial.println(tableauDesTicksASurveiller[indexTick].numeroStation);
attenteNecessaire = true;
digitalWrite(pinDesStations[tableauDesTicksASurveiller[indexTick].numeroStation], HIGH);
tableauDesTicksASurveiller[indexTick].entreeDisponible = true; // on l'a traité
}
}
}
if (attenteNecessaire) {
// on a activé au moins une pin on attend un peu puis on éteint toutes les pins sans se poser de question, c'est plus simple
delay(dureeActivationStation);
for (uint8_t i = 0; i < nombreDeStations; i++) digitalWrite(pinDesStations[i], LOW);
}
}
void setup() {
Serial.begin(115200);
bacthCourant = 0;
tickCourant = 0;
for (uint8_t i = 0; i < nombreDeStations; i++) {
pinMode(pinDesStations[i], OUTPUT);
digitalWrite(pinDesStations[i], LOW);
}
// tous les éléments du tableau sont dispo
for (uint8_t indexTick = 0; indexTick < nombreDeTicksASurveiller; indexTick++) {
tableauDesTicksASurveiller[indexTick].entreeDisponible = true; // dispo
}
}
void loop() {
}
un appel à la fonction nouveauTick()
doit se faire quand vous avez un nouveau tick comme son nom l'indique. la fonction parcourt le tableau des ticks à suivre et fait l'action si nécessaire puis attend un peu (s'il le faut) et libère toutes les pins
(on peut bien sûr simplifier car les 5 entrées associées à une pression sur le bouton sont déterminée par le premier tick, donc on pourrait aussi n'avoir que 10 entrées dans le tableau et calculer les ticks importants à chaque fois, ça évite d'avoir à insérer 5 éléments qui se ressemblent dans le tableau, on n'en met qu'un seul et on en déduit les autres)