1. Le matériel
Nous utiliserons un moteur compatible Power Functions mais nous aurions pu prendre un moteur LEGO de type M,L ou XL comme le montre ce lien. J'utilise actuellement ce type de matériel car on le trouve assez facilement sur AliExpress à des prix plus décents. Pour notre démo, j'utilise le boîtier à piles 9 volts, mais il est possible d'utiliser une alimentation universelle.
Nous utiliserons le matériel suivant :
- Un arduino
- Une carte groove pour arduino
- Un bouton du système groove
- Un bouton sensitif du système groove
- Une LED du système groove
- Un potentiomètre du système groove
- Un shield L298N
- Un micromoteur CADA compatible LEGO
- Des câbles Power Functions LEGO
- Deux microcontacts
- Deux résistances de 10 Kohms
- Une platine d'essai
- Des fils jumper
Et bien sûr, des LEGO pour le montage de la porte coulissante.
Le système groove n'est pas obligatoire, il permet seulement une meilleure connexion et une rapidité d'exécution. Les schémas suivants représenteront les composants sans système groove.
2. Le L298N
Le shield L298N nous permettra le pilotage du moteur avec l'Arduino. C'est le circuit de puissance, permettant l'inversion et les variations de vitesse des moteurs. L'Arduino n'enverra que les informations nécessaires, car ces sorties sont trop faibles en puissance pour alimenter les moteurs.
Voici un tableau représentant les différents états des entrées et les sorties correspondantes.
Si vous voulez en savoir plus sur ce module, visitez la page de Passion Electronique sur ce sujet.
Pour connecter le boîtier à piles LEGO et les moteurs LEGO, nous sommes obligés de cannibaliser les fils LEGO. Voici comment sont organisées les connexions : les fils extérieurs servent à l'alimentation des modules infrarouges par exemple et les deux fils intérieurs servent à alimenter les moteurs ou lumières.
3. Les projets
Dans ce tuto, nous commencerons par des montages simples.
3.a - Montage simple ON/OFF
Le montage est assez simple. Il faudra deux moteurs pour réaliser ce montage. Voici le schéma de câblage.
Le module L298N alimente l'arduino, ce qui évite d'avoir une alimentation supplémentaire. Attention, toutefois de ne pas dépasser la tension d'entrée de plus de 12 volts.
Le moteur de gauche est programmé pour s'arrêter en mode roue libre. Mais, la différence de fonctionnement avec les micromoteurs CADA n'est pas visible. Il faudrait utiliser des moteurs sans réducteurs.
Voici le code
/* Démo commande moteur ON/OFF */
// Connexion des pins au module Moteur L298N
// moteur gauche (out1-out2)
int enA = 13;
int in1 = 12;
int in2 = 11;
// moteur droite (out3-out4)
int enB = 10;
int in3 = 8;
int in4 = 9;
void setup()
{
//Initialisation port série
Serial.begin(9600);
// paramétrage des pins en sortie (OUTPUT)
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(enA, OUTPUT);
analogWrite(enA, 255);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
pinMode(enB, OUTPUT);
analogWrite(enB, 255);
}
void loop()
{
//le moteur gauche tourne
Serial.println("le moteur gauche tourne dans un sens");
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
analogWrite(enA, 255);
delay(2000);
//le moteur droit tourne
Serial.println("le moteur gauche tourne dans un sens");
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
delay(2000);
//stoppe les moteurs
Serial.println("le moteur gauche stoppe en blocage moteur");
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
delay(1000);
Serial.println("le moteur droit stoppe");
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
delay(1000);
//le moteur gauche tourne dans le sens inverse
Serial.println("le moteur tourne en sens inverse");
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
analogWrite(enA, 255);
delay(2000);
//le moteur droit tourne dans le sens inverse
Serial.println("le moteur tourne en sens inverse");
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
delay(2000);
//stoppe les moteurs
Serial.println("le moteur gauche stoppe en roue libre");
analogWrite(enA, 0);
delay(1000);
Serial.println("le moteur droit stoppe");
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
delay(1000);
}
Démo
3.b - Varier la vitesse
Nous allons voir comment faire varier la vitesse des moteurs. Nous utiliserons un seul moteur. Pour cela, on utilisera un potentiomètre et une LED qui s'allumera en fonction de la vitesse demandée. Ce montage peut être utile pour récupérer la valeur de la vitesse désirée grâce à la fenêtre du port série. Voici le schéma de câblage.
Le moniteur série de l'application arduino nous permettra de récupérer la valeur exacte pour le moteur.
Voici le code
/* Démo commande moteur avec vitesse variable
contrôlé par un potentiomètre
et inversion de sens par bouton */
// connect motor controller pins to Arduino digital pins
// motor one
int enA = 13;
int in1 = 12;
int in2 = 11;
/*macro definitions of Rotary angle sensor and LED pin*/
#define ROTARY_ANGLE_SENSOR A0
#define LED 3 //the Grove - LED is connected to PWM pin D3 of Arduino
#define ADC_REF 5 //reference voltage of ADC is 5v.If the Vcc switch on the seeeduino
//board switches to 3V3, the ADC_REF should be 3.3
#define GROVE_VCC 5 //VCC of the grove interface is normally 5v
#define FULL_ANGLE 300 //full value of the rotary angle is 300 degrees
const int buttonPin = 2; // pin du bouton miniature
const int TouchPin = 4; // pin du bouton sensitif
// variables will change:
int buttonState = 0; // variable pour l'état du bouton miniature
int sensorValue = 0; // variable pour l'état du bouton sensitif
void setup() {
//Initialize Serial Monitor
Serial.begin(9600);
// set all the motor control pins to outputs
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(enA, OUTPUT);
analogWrite(enA, 255);
//
pinMode(ROTARY_ANGLE_SENSOR, INPUT);
pinMode(LED,OUTPUT);
// initialisation des boutons
pinMode(buttonPin, INPUT);
pinMode(TouchPin, INPUT);
}
void loop() {
float voltage;
int sensor_value = analogRead(ROTARY_ANGLE_SENSOR);
voltage = (float)sensor_value*ADC_REF/1023;
float degrees = (voltage*FULL_ANGLE)/GROVE_VCC;
Serial.println("The angle between the mark and the starting position:");
Serial.println(degrees);
int brightness;
brightness = map(degrees, 0, FULL_ANGLE, 0, 255);
analogWrite(LED,brightness);
analogWrite(enA, brightness);
// Lecture du bouton miniature
buttonState = digitalRead(buttonPin);
// lecture du bouton sensitif
sensorValue = digitalRead(TouchPin);
if (buttonState == HIGH) {
Serial.println("le moteur tourne dans un sens");
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
} else if (sensorValue == 1) {
Serial.println("le moteur tourne en sens inverse");
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
} else if ((buttonState == LOW) && (sensorValue == 0)) {
Serial.println("le moteur stoppe");
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
}
}
Démo
3.c - Commande manuelle d'un moteur
Nous terminerons cette première partie, par la commande manuelle d'un moteur. Deux boutons (miniature et sensitif) permettrons la commande avant et arrière d'un moteur. Voici le schéma de principe.
Voici le code. J'utilise un bouton sensitif groove, mais le principe de fonctionnement est le même qu'un bouton miniature.
/* Démo commande moteur avec vitesse variable
contrôlé par un potentiomètre
et inversion de sens par bouton */
// connect motor controller pins to Arduino digital pins
// motor one
int enA = 10;
int in1 = 8;
int in2 = 9;
/*macro definitions of Rotary angle sensor and LED pin*/
#define ROTARY_ANGLE_SENSOR A0
#define LED 3 //the Grove - LED is connected to PWM pin D3 of Arduino
#define ADC_REF 5 //reference voltage of ADC is 5v.If the Vcc switch on the seeeduino
//board switches to 3V3, the ADC_REF should be 3.3
#define GROVE_VCC 5 //VCC of the grove interface is normally 5v
#define FULL_ANGLE 300 //full value of the rotary angle is 300 degrees
const int buttonPin = 2; // pin du bouton miniature
const int TouchPin = 4; // pin du bouton sensitif
// variables will change:
int buttonState = 0; // variable pour l'état du bouton miniature
int sensorValue = 0; // variable pour l'état du bouton sensitif
void setup() {
//Initialize Serial Monitor
Serial.begin(9600);
// set all the motor control pins to outputs
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(enA, OUTPUT);
analogWrite(enA, 255);
//
pinMode(ROTARY_ANGLE_SENSOR, INPUT);
pinMode(LED,OUTPUT);
// initialisation des boutons
pinMode(buttonPin, INPUT);
pinMode(TouchPin, INPUT);
}
void loop() {
float voltage;
int sensor_value = analogRead(ROTARY_ANGLE_SENSOR);
voltage = (float)sensor_value*ADC_REF/1023;
float degrees = (voltage*FULL_ANGLE)/GROVE_VCC;
Serial.println("The angle between the mark and the starting position:");
Serial.println(degrees);
int brightness;
brightness = map(degrees, 0, FULL_ANGLE, 0, 255);
analogWrite(LED,brightness);
analogWrite(enA, brightness);
// Lecture du bouton miniature
buttonState = digitalRead(buttonPin);
// lecture du bouton sensitif
sensorValue = digitalRead(TouchPin);
if (buttonState == HIGH) {
Serial.println("le moteur tourne dans un sens");
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
} else if (sensorValue == 1) {
Serial.println("le moteur tourne en sens inverse");
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
} else if ((buttonState == LOW) && (sensorValue == 0)) {
Serial.println("le moteur stoppe");
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
}
}
Démo
Ce tuto est terminé, la prochaine fois, nous verrons l'utilisation du moteur pour l'ouverture d'une porte coulissante en LEGO.