Le 28BYJ-48 est un moteur pas à pas très populaire et économique, souvent utilisé dans les projets Arduino. En voici quelques caractéristiques :
L'ULN2003 est un circuits intégrés de commande de moteur Pas-à-Pas très populaire. Il est composé d'un réseau de 7 commutateurs (transistors Darlington), chacun capable de piloter des charges allant jusqu'à à 500mA et 50V.
Chaque commutateur permet de controller une bobine du moteur Pas-à-Pas. Pour l'alimentation du moteur, il faut prévoir un Volt de plus à cause de la chute de tension (Vce) dans les commutateur. Les diodes de récupération sont intégrées dans le circuit
Le module ULN2003 facilite grandement la connectique avec l'Arduino, le moteur et l'alimentation. Il possède:
Dans cet exemple on va utiliser le moteur pas-à-pas 28BYJ-48. Ce moteur existe en plusieurs versions. Nous utilisons une version 5V, 32 pas, réducteur 1/64, durée min d'un pas : 2 ms
#define PINA 11
#define PINB 10
#define PINC 9
#define PIND 8
void setup() {
stepperInit(LOW);
}
void loop() {
stepperStep(2048, 3);
delay(1000);
stepperStep(-2048, 3);
delay(1000);
}
///////////////////////////////////////
void stepperInit(byte tork) {
// Initialiser les commandes
// tork = LOW ==> couple faible
// tork = HIGH ==> couple fort
pinMode(PINA, OUTPUT);
pinMode(PINB, OUTPUT);
pinMode(PINC, OUTPUT);
pinMode(PIND, OUTPUT);
digitalWrite(PINA, HIGH);
digitalWrite(PINB, tork);
digitalWrite(PINC, LOW);
digitalWrite(PIND, LOW);
}
void stepperStep(int32_t steps, float step_time_ms) {
// Tourner de steps pas au rythme de step_time_ms par pas
// lire l'état actuel des bobines
byte A, B, C, D, S;
A = digitalRead(PINA) ;
B = digitalRead(PINB) ;
C = digitalRead(PINC) ;
D = digitalRead(PIND) ;
//commencer le décalage
if (steps > 0) {
for (int i = 0; i < steps; i++) {
S = D;
D = C;
C = B;
B = A;
A = S;
digitalWrite(PINA, A);
digitalWrite(PINB, B);
digitalWrite(PINC, C);
digitalWrite(PIND, D);
if(step_time_ms > 1)delay(step_time_ms);
else delayMicroseconds(step_time_ms * 1000 - 27);
}
} else {
for (int i = 0; i < abs(steps); i++) {
S = A;
A = B;
B = C;
C = D;
D = S;
digitalWrite(PINA, A);
digitalWrite(PINB, B);
digitalWrite(PINC, C);
digitalWrite(PIND, D);
if(step_time_ms > 1)delay(step_time_ms);
else delayMicroseconds(step_time_ms * 1000 - 27);
}
}
}
#define PINA 11
#define PINB 10
#define PINC 9
#define PIND 8
void setup() {
Serial.begin(9600);
Serial.setTimeout(5000);
Serial.println("Taper une commande suivie d'un paramètre :");
Serial.println("stepms 4.7 ---> Définir la durée d'un pas à 4.7 ms");
Serial.println("step 100 ---> En avant de 100 pas");
Serial.println("step -200 ---> En arrière de 200 pas");
Serial.println("Valider par Enter (CR, LF ou les deux)");
stepperInit(LOW);
}
float T = 50; // stepTime par défaut
void loop() {
if (Serial.available()) {
String cmd = Serial.readStringUntil(' ');
float param = Serial.parseFloat();
clearInputBuffer();
Serial.println("----> " + cmd + " " + String(param));
if(cmd == "step") stepperStep(param,T);
else if (cmd == "stepms")T = param;
else Serial.println("Mauvaise commande");
}
}
void stepperInit(byte tork) {
// Initialiser les commandes
// tork = LOW ==> couple faible
// tork = HIGH ==> couple fort
pinMode(PINA, OUTPUT);
pinMode(PINB, OUTPUT);
pinMode(PINC, OUTPUT);
pinMode(PIND, OUTPUT);
digitalWrite(PINA, HIGH);
digitalWrite(PINB, tork);
digitalWrite(PINC, LOW);
digitalWrite(PIND, LOW);
}
void stepperStep(int32_t steps, float step_time_ms) {
// Tourner de steps pas au rythme de step_time_ms par pas
// lire l'etat actuel des bobines
byte A, B, C, D, S;
A = digitalRead(PINA) ;
B = digitalRead(PINB) ;
C = digitalRead(PINC) ;
D = digitalRead(PIND) ;
//commencer le décalage
if (steps > 0) {
for (int i = 0; i < steps; i++) {
S = D;
D = C;
C = B;
B = A;
A = S;
digitalWrite(PINA, A);
digitalWrite(PINB, B);
digitalWrite(PINC, C);
digitalWrite(PIND, D);
if(step_time_ms > 10)delay(step_time_ms);
else delayMicroseconds(step_time_ms * 1000 - 27);
}
} else {
for (int i = 0; i < abs(steps); i++) {
S = A;
A = B;
B = C;
C = D;
D = S;
digitalWrite(PINA, A);
digitalWrite(PINB, B);
digitalWrite(PINC, C);
digitalWrite(PIND, D);
if(step_time_ms > 10)delay(step_time_ms);
else delayMicroseconds(step_time_ms * 1000 - 27);
}
}
}
void clearInputBuffer() {
do {
delay(2);
Serial.read();
} while (Serial.available());
}
La librairie Stepper intégrée à l'IDE Arduino permet de contrôler facilement des moteurs pas-à-pas sans avoir besoin d'installer des bibliothèques externes. Voici ce qu'il faut savoir:
La librairie est facile à utiliser. On a un constructeur pour créer un objet qui contrôle le moteur et deux fonctions et 2 fonctions pour l'actionner:
Stepper myStepper(200, 8, 9, 10, 11);
myStepper.setSpeed(15); // 15 tours par minute
myStepper.step(100); // avancer de 100 pas
myStepper.step(-100); // reculer de 100 pas
Ce code fonctionne pour un moteur unipolaire ou un moteur bipolaire. Les branchement diffèrent selon le type du moteur. Voir images plus haut. Faire attention avec le moteur unipolaire (Ordre A, C, B, D)
#include <Stepper.h>
// Déclaration du moteur
Stepper myStepper(200, 8, 9, 10, 11);
void setup() {
myStepper.setSpeed(15); // 15 tours/minute
}
void loop() {
myStepper.step(200); // Tour complet dans un sens
delay(1000);
myStepper.step(-200); // Tour complet dans l'autre sens
delay(1000);
}
Dans le schéma proposé :
// For Arduino Uno, Nano, Micro Magician, Mini Driver, Lilly Pad and any other board using ATmega 8, 168 or 328
//-------------- fréquences PWM sur les broches D5 & D6 -------------------------------
TCCR0B = TCCR0B & B11111000 | B00000001; // f = 62500.00 Hz, T = 0.016ms
TCCR0B = TCCR0B & B11111000 | B00000010; // f = 7812.50 Hz, T = 0.128ms
TCCR0B = TCCR0B & B11111000 | B00000011; // f = 976.56 Hz, T = 1.024ms (The DEFAULT)
TCCR0B = TCCR0B & B11111000 | B00000100; // f = 244.14 Hz, T = 4.096ms
TCCR0B = TCCR0B & B11111000 | B00000101; // f = 61.04 Hz, T = 16.383ms
//---------------------------------------------- Set PWM frequency for D9 & D10 ------------------------------
TCCR1B = TCCR1B & B11111000 | B00000001; // f = 31372.55 Hz, T = 0.032ms
TCCR1B = TCCR1B & B11111000 | B00000010; // f = 3921.16 Hz, T = 0.255ms
TCCR1B = TCCR1B & B11111000 | B00000011; // f = 490.20 Hz, T = 2.04ms (The DEFAULT)
TCCR1B = TCCR1B & B11111000 | B00000100; // f = 122.55 Hz, T = 8.16ms
TCCR1B = TCCR1B & B11111000 | B00000101; // f = 30.64 Hz, T = 32.637ms
//---------------------------------------------- Set PWM frequency for D3 & D11 ------------------------------
TCCR2B = TCCR2B & B11111000 | B00000001; // f = 31372.55 Hz, T = 0.032ms
TCCR2B = TCCR2B & B11111000 | B00000010; // f = 3921.16 Hz, T = 0.255ms
TCCR2B = TCCR2B & B11111000 | B00000011; // f = 980.39 Hz, T = 1.020ms
TCCR2B = TCCR2B & B11111000 | B00000100; // f = 490.20 Hz, T = 2.04ms (The DEFAULT)
TCCR2B = TCCR2B & B11111000 | B00000101; // f = 245.10 Hz, T = 4.080ms
TCCR2B = TCCR2B & B11111000 | B00000110; // f = 122.55 Hz, T = 8.16ms
TCCR2B = TCCR2B & B11111000 | B00000111; // f = 30.64 Hz, T = 32.637ms
/*
* Test du module TB6600
* moteur 200 pas
* microstep = 1
*/
#define PUL 8
#define DIR 9
#define PULSE_ms 4 // 1 tour par 200 x 8ms = 1.6s
void setup() {
pinMode(PUL, OUTPUT);
pinMode(DIR, OUTPUT);
digitalWrite(PUL,HIGH);
digitalWrite(DIR,HIGH);
for(int i = 0 ; i < 200 ; i++){
digitalWrite(PUL,LOW);
delay(PULSE_ms);
digitalWrite(PUL,HIGH);
delay(PULSE_ms);
}
digitalWrite(DIR,LOW);
delay(1);
for(int i = 0 ; i < 200 ; i++){
digitalWrite(PUL,LOW);
delay(PULSE_ms);
digitalWrite(PUL,HIGH);
delay(PULSE_ms);
}
}
void loop() {
}