Cirkit Designer LogoCirkit DesignerYour all-in-one circuit design IDE Launch Cirkit Designer App

Arduino UNO Controlled Gear Motor and Servo System with Integrated Encoder

View and Edit Project In Cirkit DesignerImage of Arduino UNO Controlled Gear Motor and Servo System with Integrated Encoder

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

12V Battery

Arduino UNO

Shield Cytron MD-10

Servo

Wiring Details

Gear Motor with Integrated Encoder

12V Battery

Arduino UNO

Shield Cytron MD-10

Servo

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