Bonjour à tous!
J'ai finalement décidé de m'y mettre, j'ai acheté 2 arduinos UNO et quelque accessoires pour bien débuter.
Je me suis donc lancé dans un projet qui m'a amené à jouer avec un arduino : un régulateur de vitesse pour ma R11 (ben quoi? elle monte très facilement au dessus de 150, et sur la route, c'est fatigant de gérer tout le temps l'accélérateur...) :~ .
Côté hardware :
un capteur "PMH" sur volant cranté du moteur adapté qui me délivre 40 impulsions par tour de moteur, remplacé par un GBF pour la phase mise-en-route.
un LCD 16 x 2 pour IHM
un clavier matriciel 5 x 4 (un clavier 16 touches + 4 poussoirs),
un servo pour actionner l'accélérateur.
Voilà mon montage :
Ne rentrons pas dans les détails de sécurité, pour l'instant, je souhaite juste gérer un asservissement de vitesse du moteur de la voiture. Les sécurités viendront après.
Mon gros problème :
1 - j'utilise les librairies "servo", "keypad", "liquidCrystal" et "MsTimer2", comptage par interruption externe 0 (broche 2) :
saisie au clavier d'un angle pour le servo et affichage du nombre d'impultions toutes les 202ms (meilleur rapport pour appliquer les facteurs de vitesse et tours moteur). Youpi, tout marche tout seul, mais :
- les timers servo et MsTimer2 se bouffent, et le comptage d'impulsion n'est pas du tout stable et le servo a des ratés.
- on est très loin de 202ms, plutôt dans les 180ms.
2 - OK, plan B : on oublie la lib "servo" (j'ai regardé le code, c'est bien trop "usine à gaz" pour ne gérer qu'un seul servo).
- attachInterrupt pour incrémenter un compteur (compteurImpul) via impulsions,
- Mstimer2 déclenche toutes les 20ms la routine suivante :
void traitement_timer(){ // proc appelée toutes les 20ms par le timer.
timerCount++; // on compte le nombre d'appel de cette routine
if (timerCount > 10) { // on a appelé 10 x la routine (donc 200ms), alors on lit le compteur d'impulsions
timerCount = 0; // RAZ compteur de routine
nbImpul = compteurImpul; // lecture compteur d'impulsions
compteurImpul = 0; // RAZ compteur d'impulsions
}
digitalWrite(servoPin, HIGH); // Début imp servo
delayMicroseconds(servoValue); // temps d’impulsion servo (entre 544 et 2400 µs)
digitalWrite(servoPin, LOW); // fin imp servo
if (timerCount == 0) { // on est dans le cas de la lecture compteur d'impulsions
/*
ici le code pour le traitement,
et quelque calculs,
affichage LCD du nbre d'impulsions etc etc
*/
}
}
C'est beau, relativement stable (+/- 1 imp, normal), je suis content, mais du coup, il ne me reste plus trop de temps pour le reste de mon programme, 10ms environ (la moitié des 20ms de périodicité).
Est-ce que certains d'entre vous on déjà joué dans cette configuration (utilisation de plusieurs timers)? ma solution ne me plait pas, j'aurais voulu continuer à jouer avec la solution 1...
Et grosse question : que se passe-t-il pendant une routine d'interruption timer et pendant un delayMicroseconds ou un delay? est-ce que mon compteur d'impulsions ne serait pas tout simplement désactivé le temps du traitement de la void ci-dessus? car il semble que quelques impulsions ne sont pas prises en compte, alors que pourtant il s'agit d'un beau signal carré 0-5V (de 500 à 5000Hz)???
Je trouve que la doc arduino reste très silencieuse là-dessus, comme si toutes les librairies étaient utilisables les unes avec les autres, sans aucune incompatibilité... je viens de voir que non, et je ne trouve aucune réponse à ce sujet...
Merci d'avoir lu ce... long message et merci à ceux qui auront des idées...