Arduino UNO Controlled Gear Motor and Servo System with Integrated Encoder
View and Edit Project In Cirkit Designer
Circuit Documentation
Summary
This document provides a detailed overview of a circuit that includes a Gear Motor with an integrated Encoder, a 12V Battery, an Arduino UNO, a Shield Cytron MD-10, and a Servo. The circuit is designed to control the motor and servo using the Arduino UNO, with the Shield Cytron MD-10 acting as a motor driver. The encoder provides feedback for motor speed control.
Component List
Gear Motor with Integrated Encoder
- Description: A motor with an integrated encoder for speed feedback.
- Pins: MOTOR -, MOTOR+, Encoder -, Encoder +, Encoder A, Encoder B
12V Battery
- Description: A power source for the circuit.
- Pins: -, +
Arduino UNO
- Description: A microcontroller board used to control the motor and servo.
- Pins: UNUSED, IOREF, Reset, 3.3V, 5V, GND, Vin, A0, A1, A2, A3, A4, A5, SCL, SDA, AREF, D13, D12, D11, D10, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0
Shield Cytron MD-10
- Description: A motor driver shield for the Arduino.
- Pins: borne positive, Borne négative, Sortie A, Sortie B, D7, pin PWM, Codeur pin A, Codeur pin B, pin dir, DIR, PWM, GND
Servo
- Description: A servo motor for precise control of angular position.
- Pins: GND, VCC, PWM
Wiring Details
Gear Motor with Integrated Encoder
- Encoder + connected to Arduino UNO 3.3V
- Encoder B connected to Arduino UNO D4
- Encoder A connected to Arduino UNO D2
- Encoder - connected to Arduino UNO GND
- MOTOR+ connected to Shield Cytron MD-10 Sortie A
- MOTOR - connected to Shield Cytron MD-10 Sortie B
12V Battery
- + connected to Shield Cytron MD-10 borne positive
- - connected to Shield Cytron MD-10 Borne négative
Arduino UNO
- 3.3V connected to Gear Motor with Integrated Encoder Encoder +
- D4 connected to Gear Motor with Integrated Encoder Encoder B
- D2 connected to Gear Motor with Integrated Encoder Encoder A
- GND connected to Gear Motor with Integrated Encoder Encoder -
- GND connected to Shield Cytron MD-10 GND
- 5V connected to Servo VCC
- D9 connected to Servo PWM
- D8 connected to Shield Cytron MD-10 DIR
- D5 connected to Shield Cytron MD-10 PWM
Shield Cytron MD-10
- borne positive connected to 12V Battery +
- Borne négative connected to 12V Battery -
- Sortie A connected to Gear Motor with Integrated Encoder MOTOR+
- Sortie B connected to Gear Motor with Integrated Encoder MOTOR -
- GND connected to Arduino UNO GND
- DIR connected to Arduino UNO D8
- PWM connected to Arduino UNO D5
Servo
- VCC connected to Arduino UNO 5V
- GND connected to Arduino UNO GND
- PWM connected to Arduino UNO D9
Documented Code
#include <Servo.h> // Bibliothèque pour contrôler le servo-moteur
#include <FlexiTimer2.h> // Bibliothèque pour les tâches périodiques
#include <digitalWriteFast.h> // Bibliothèque pour des opérations numériques rapides
// Définition des broches
#define CODEUR_PIN_A 2 // Broche A de l'encodeur
#define CODEUR_PIN_B 3 // Broche B de l'encodeur
#define PIN_PWM 5 // Broche pour le signal PWM du moteur
#define PIN_DIR 8 // Broche pour la direction du moteur
// Constantes
#define SERIAL_PRINT_INTERVAL 50 // Intervalle pour l'affichage de la vitesse sur le port série (ms)
#define CADENCE_MS 50 // Période du timer pour la mesure de la vitesse (ms)
#define TICKS_PER_ROTATION 64 // Nombre d'impulsions par rotation de l'encodeur
#define MS_TO_S 0.001 // Facteur de conversion millisecondes en secondes
#define RAD_TO_RPM (60 / (2 * PI)) // Facteur de conversion de rad/s en tr/min (RPM)
// Variables globales
Servo servoMotor; // Objet servo pour contrôler le servo-moteur
volatile long encoderTicks = 0; // Compteur d'impulsions de l'encodeur
float rpm = 0; // Vitesse calculée en tr/min
int servoAngle = 90; // Angle initial du servo-moteur (position neutre)
// Fonction de configuration (appelée une seule fois au début)
void setup() {
Serial.begin(9600); // Initialisation de la communication série
servoMotor.attach(9); // Connexion du servo-moteur sur la broche 9
servoMotor.write(servoAngle); // Position initiale du servo-moteur
pinMode(PIN_PWM, OUTPUT); // Configuration de la broche PWM comme sortie
pinMode(PIN_DIR, OUTPUT); // Configuration de la broche de direction comme sortie
// Initialisation du timer pour la mesure de la vitesse
FlexiTimer2::set(CADENCE_MS, 1, measureSpeed);
FlexiTimer2::start();
// Configuration des interruptions pour les broches de l'encodeur
attachInterrupt(digitalPinToInterrupt(CODEUR_PIN_A), handleEncoderA, CHANGE);
attachInterrupt(digitalPinToInterrupt(CODEUR_PIN_B), handleEncoderB, CHANGE);
}
// Boucle principale (exécutée en continu)
void loop() {
handleSerialCommands(); // Traitement des commandes reçues via le port série
// Affichage périodique de la vitesse
static unsigned long lastReportTime = 0;
if (millis() - lastReportTime >= SERIAL_PRINT_INTERVAL) {
lastReportTime = millis();
Serial.print("SPEED:");
Serial.println(rpm, 2); // Affichage de la vitesse avec 2 décimales
}
}
// Fonction pour traiter les commandes reçues via le port série
void handleSerialCommands() {
if (Serial.available() > 0) { // Si une commande est disponible
char command = Serial.read(); // Lecture de la commande
// Gestion des commandes en fonction du caractère reçu
switch (command) {
case 'O': handleServoCommand(); break; // Commande pour ajuster l'angle du servo
case 'R': handleMotorCommand(LOW); break; // Commande pour faire tourner le moteur à droite
case 'L': handleMotorCommand(HIGH); break; // Commande pour faire tourner le moteur à gauche
case 'S': stopMotor(); break; // Commande pour arrêter le moteur
default: Serial.println("Unknown command!"); break; // Commande non reconnue
}
}
}
// Fonction pour ajuster l'angle du servo-moteur
void handleServoCommand() {
int angle = constrain(Serial.parseInt(), 0, 180); // Lecture de l'angle et contrainte entre 0 et 180 degrés
servoMotor.write(angle); // Déplacement du servo à l'angle spécifié
servoAngle = angle; // Mise à jour de la variable globale
Serial.print("Servo Angle: ");
Serial.println(servoAngle); // Affichage de l'angle actuel
}
// Fonction pour contrôler le moteur (direction et vitesse)
void handleMotorCommand(bool direction) {
int speed = constrain(Serial.parseInt(), 0, 255); // Lecture de la vitesse et contrainte entre 0 et 255
analogWrite(PIN_PWM, speed); // Application du signal PWM pour contrôler la vitesse
digitalWrite(PIN_DIR, direction); // Configuration de la direction du moteur
Serial.print("Motor Direction: ");
Serial.println(direction == LOW ? "Right" : "Left"); // Affichage de la direction
Serial.print("Motor Speed: ");
Serial.println(speed); // Affichage de la vitesse
}
// Fonction pour arrêter le moteur
void stopMotor() {
analogWrite(PIN_PWM, 0); // Mise de la vitesse à 0 (arrêt complet)
Serial.println("Motor Stopped"); // Affichage d'un message d'arrêt
}
// Fonction pour mesurer la vitesse du moteur
void measureSpeed() {
// Calcul de la vitesse en tr/min (RPM)
rpm = (encoderTicks / (float)TICKS_PER_ROTATION) / (CADENCE_MS * MS_TO_S) * RAD_TO_RPM;
encoderTicks = 0; // Réinitialisation du compteur d'impulsions
}
// Gestion