Bravo les gars et bonjour Vincent,
La solution est en fait de ralentir la fonction HandleCommand lorsqu'elle traite la trame 'M', je n'ai pas compris pourquoi mais le simple fait de mettre un delay(1); à résolu le problème.
Ce qui me frappe, c'est ce delay(1) 1ms alors que delayMicroseconds(1) 1µs m'irait mieux.
En remontant un peu dans le programme, Je m'aperçois qu'il manque une confirmation de fin de step. Voici le diagramme du DRV8825.
Code : Tout sélectionner
void sendMotorCmd(byte cmd)
{
Mot_Dir = (Mot_Dir & 0x0F) | (cmd & 0xf0); // Directions first!
ValCommDir();
delayMicroseconds(1); // eventually wait a little bit
Mot_Ck = (Mot_Ck & 0xF0) | (cmd & 0x0f); // and step
ValCommStep();
delayMicroseconds(5); // eventually wait a little bit
// and falling edge of step pulse
Mot_Ck = (Mot_Ck & 0xF0);
ValCommStep();
}
Nous voyons que nous mettons la direction à jour par "ValCommDir()", ensuite on attend 1 µs alors qu'il est nécessaire de 650ns donc c'est bien.
Ensuite nous envoyons la commande de Step par "ValCommStep()" Nous attendons 5µs pour le niveau 1 alors qu'il n'est nécessaire de 1.9µs pour le DRV8825 et 1µs pour le A4899 ensuite on remet le step à zéro et puis on revient dans la fonction "void handleCommand()" qui traite "case "M" " et on sort de l'interruption.
Qu'est-ce qui se passe lorsque l'on sort de l'interruption on reprend le fil normal du programme en ayant régénéré les registres. J'avoue que pour l'arduino en utilisant les bibliothèques d'entrées sorties, je ne sais pas vraiment comment est traité tout cela. On maîtrise plus facilement lorsque l'on pilote directement les ports.
Dans le programme actuel, lorsque l'on remet le step à zéro, on ne prend pas la sécurité du temps minimum de mise à zéro. C'est aussi 1.9µs pour le DRV8825 et 3µs pour le A4899.
Vincent en ajoutant un delay dans la trama "M" retarde le moment de sortie de l'interruption ce qui a pour effet de valider le temps de step à zéro.
Pour contrôler ceci il serait plus compréhensible d'ajouter ce delay dans la fonction "void sendMotorCmd(byte cmd)" et diminuer le temps de step à 1, on a du rab.
Voici ce que je préconise.
Code : Tout sélectionner
void sendMotorCmd(byte cmd)
{
Mot_Dir = (Mot_Dir & 0x0F) | (cmd & 0xf0); // Directions first!
ValCommDir();
delayMicroseconds(1); // eventually wait a little bit
Mot_Ck = (Mot_Ck & 0xF0) | (cmd & 0x0f); // and step
ValCommStep();
delayMicroseconds(3); // eventually wait a little bit
// and falling edge of step pulse
Mot_Ck = (Mot_Ck & 0xF0);
ValCommStep();
delayMicroseconds(2)
}
Nous voyons qu'il y a une différence entre les drivers DRV8825 et A4899. Le DRV est plus lent ce qui explique peut-être le problème.
De mon côté j'ai des DRV, je vais essayer la modif.
Bonnes cogitations
Alain