Le circuit L293 possède deux entrées qui fixent la polarité du pont, et par conséquent le sens de rotation du moteur, et une entrée d'activation qui permet de faire varier la tension moyenne appliquée au moteur en pratiquant une modulation en largeur d'impulsions (PWM en anglais ou MLI en français).
Dans l'exemple, les deux premières entrées sont commandées par les sorties 3 et 4 de l'Arduino, et la dernière est commandée par la sortie 9.
Avec un niveau haut sur la sortie 3 et un niveau bas sur la sortie 4, le moteur tournera dans un sens. Avec un niveau bas sur la sortie 3 et un niveau haut sur la sortie 4, le moteur tournera dans le sens inverse.
L'Arduino offre la possibilité de fournir directement un signal PWM sur la sortie 9. Mais comme la fréquence de ce signal est assez élevée, pour limiter les pertes en commutation des transistors du pont il est préférable de créer ce signal PWM logiciellement, avec une fréquence plus faible de l'ordre du kilohertz.
Ainsi, par exemple :
- pour arrêter le moteur (tension moyenne = 0 V) on maintient tout le temps la sortie 9 à l'état bas (rapport cyclique = 0%) ;
- pour faire tourner le moteur au quart du régime maxi (tension moyenne = 3 V) on maintient périodiquement la sortie 9 à l'état haut durant 250 µs et à l'état bas durant 750 µs (rapport cyclique = 25%) ;
- pour faire tourner le moteur à mi-régime (tension moyenne = 6 V) on maintient périodiquement la sortie 9 à l'état haut durant 500 µs et à l'état bas durant 500 µs (rapport cyclique = 50%) ;
- pour faire tourner le moteur à trois quarts du régime maxi (tension moyenne = 9 V) on maintient périodiquement la sortie 9 à l'état haut durant 750 µs et à l'état bas durant 250 µs (rapport cyclique = 75%) ;
- pour faire tourner le moteur à plein régime (tension moyenne = 12 V) on maintient tout le temps la sortie 9 à l'état haut (rapport cyclique = 100%).
Voici un exemple de programme que j'ai fait sur un coin de table pour piloter le moteur selon une séquence déterminée :
(NB : je n'ai pas tenu compte du temps pris pour l'exécution du code, par conséquent les temporisations réalisées ne seront un peu plus longues que prévu, et les niveaux de tension sur le moteur pas non plus exacts).Code:const int sortieInput1 = 3; // "Input 1" = pin 2 du L293D const int sortieInput2 = 4; // "Input 2" = pin 7 du L293D const int sortieEnable = 9; // "Enable 1" = pin 1 du L293D const int nombreEtapes = 14; // durées en millisecondes et vitesses en % pour chaque étape de la séquence const int tableDurees[nombreEtapes] = { 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 3000, 0 }; const int tableVitesses[nombreEtapes] = { 25, 50, 75, 100, 75, 50, 25, 0, -50, 50, -50, 50, -50, 0 }; int numeroEtape; // compteur des étapes de la séquence int decompteurTemps; // décompte du temps passé dans l'étape en cours int vitesse; // vitesse moteur pour l'étape en cours void setup() { // fixe le mode des pins de sortie de l'Arduino pinMode(sortieInput1, OUTPUT); pinMode(sortieInput2, OUTPUT); pinMode(sortieEnable, OUTPUT); // commence avec le moteur à l'arrêt digitalWrite(sortieEnable, LOW); // initialise la séquence numeroEtape = 0; decompteurTemps = 0; } void loop() { if ( decompteurTemps==0 ) // début ou étape en cours terminée ? { if (numeroEtape>=nombreEtapes) return; // quitte si terminé decompteurTemps = tableDurees[numeroEtape]; // lit la durée de l'étape (en millisecondes) vitesse = tableVitesses[numeroEtape]; // lit la vitesse du moteur pour l'étape (en %) numeroEtape++; // numéro de l'étape suivante sensMoteur(vitesse); // fixe la polarité du pont } pwm(vitesse); // génère le signal pwm durant 1 milliseconde decompteurTemps--; // décompte le temps } void sensMoteur(int pourcent) { digitalWrite(sortieEnable, LOW); if (pourcent>0) { digitalWrite(sortieInput1, LOW); digitalWrite(sortieInput2, HIGH); } else { digitalWrite(sortieInput1, HIGH); digitalWrite(sortieInput2, LOW); } } void pwm(int pourcent) { int microsec = pourcent<0 ? -10*pourcent : 10*pourcent; if( microsec>=1000 ) // 12 V { digitalWrite(sortieEnable, HIGH); delayMicroseconds(1000); return; } digitalWrite(sortieEnable, LOW); delayMicroseconds(1000-microsec); if( microsec==0 ) // 0 V return; digitalWrite(sortieEnable, HIGH); delayMicroseconds(microsec); }
-----