Bonjour,
Pour répondre à Jean-Luc :
- lorsqu'il n'y a rien à voir, la détection renvoie dans tous les cas une valeur de l'ordre de 35 à 40cm. Je suppose que vue la faible hauteur d'implantation, c'est le plateau qui rentre dans l'angle de vision. Mais dans le code, toute valeur supérieure à 25cm étant éliminée c'est donc sans effet.
- et je viens de mesurer l'entraxe entre mes deux voies : 39mm, très précisément.
Je précise, c'est aussi un élément de réponse à Dominique, que j'ai posé une voie "volante" de l'autre côté pour avoir deux convois encadrant celui visé par le détecteur, ceci sans influence sensible sur l'asservissement de freinage.
(je crois effectivement qu'un arrêt en fond de remise sera la meilleure utilisation possible de ce capteur)
et donc pour répondre à Dominique et compléter le précédent post :
- schéma de montage : bien qu'on voit 6 broches soudées je n'ai utilisé que VCC (3,3V mais prend le 5V), GND et le signal I2C (SDA/SCL, via un multiplexeur tca9548a mais tout à fait falcultatif), c'est tout.
- je crois que je réponds aux deux autres questions avec ceci ?
L'interaction à la centrale ? Conformément à la library, le détecteur s'intègre par :
- la création d'instance(s)
VL53L0X laserSensor = VL53L0X();
- et l'initialisation dans le setup :
laserSensor.setTimeout(500);
if (!laserSensor.init()) {
Serial.println("Failed to detect and initialize laserSensor!");
while (1) {} }
laserSensor.startContinuous(100); // ( l'argument "100" reste à valider...)
Puis dans le reste du code : Supposons, pour une section "voie de garage" (siding) donnée :
- d'une part, une fonction qui surveille qu'un CONVOI y est engagé (autrement dit, pas forcément une motrice), LEQUEL, son sens de déplacement et sa vitesse ;
selon conditions, notamment que le convoi entre (et/ou "recule") sur cette section, cette fonction en appellera une autre, dédiée par exemple aux sidings équipés de détection laser, laquelle contiendra une instruction de ce type :
engine[train].siding2(laserSensor.readRangeContinuousMillimeters() / 10) ; // envoi d'une lecture à une instance engine[x] de la classe "HandleEngine"
- d'autre part donc : la classe "HandleEngine" qui gère les paramètres MOTRICE, accélérations, vitesse, arrêts etc ;
Dans cette classe il y aura :
float _speedRef ; // variable de calcul (signée)
byte _latency ; // sets a minimum PWM ("voltage") applied to the engine (!obligatoire! à prédéterminer pour chaque motrice) (pas "cste" car ajustable dans ma classe)
(byte _velocity ; // le pendant de "latency", bride la Vmax à une valeur réaliste (facultatif !)
public :
float iniSpeed ; // vitesse relevée au moment où le convoi entre dans le champ de prise en charge (25 cm... dans ma config) du laserSensor
int speedRef ; // consigne PWM (signée à ce stade)
-----------------------------------------------------------------------------------------------------------
(void siding1() ; // éventuelle méthode dédiée aux sidings sans détection laser)
void siding2(int laser) ; // méthode dédiée aux sidings équipés
et donc la méthode siding2, qui recevra la mesure laser en argument et pourra ressembler à :
void HandleEngine::siding2(int laser)
{ if (joysXaxis > -200 || joysXaxis == -999) // ...ou autre chose, signifiant "vas-y, pas de reprise en manuel"
{ if (laser < 25 && joysXaxis < 200)
{ iniSpeed = min(iniSpeed peed, _speedRef) ; // dans MON CAS, en marche arrière _speedRef augmente lorsque le train ralentit, d'où le "min", qui fige la vitesse initiale
_speedRef = max(iniSpeed, (0.8*_latency + iniSpeed peed)*(laser-2)/23-0.8*_latency) ; // idem, la valeur "max" correspond au plus petit des deux termes, le second étant un bête vitesse=a*laser+b
}
if ( abs(_speedRef) < 0.8 * latency) { _speedRef = 0 ; iniSpeed = 0 ; } // extinction de la PWM, reset de iniSpeed
speedRef = _speedRef ;
}
}
Quant-aux perturbations latérales, j'ai fait le test en encadrant la voie d'essai avec deux convois, sans perturbation sensible de la mesure.
Cordialement à tous
Phlippe