Piloter un servomoteur avec un encodeur rotatif et afficher la position sur un écran OLED
Description :
Ce projet consiste à réaliser un système de contrôle de position pour un servomoteur à l’aide d’un encodeur rotatif, tout en affichant en temps réel la position désirée sur un écran OLED. L’objectif est de permettre à l’utilisateur d’ajuster l’angle du servomoteur de manière précise et intuitive simplement en tournant un bouton encodeur.
L’encodeur rotatif sert d’interface de commande : lorsqu’il est tourné dans un sens ou dans l’autre, il modifie la valeur de l’angle cible du servomoteur. Le bouton intégré à l’encodeur permet d’augmenter la vitesse de rotation du servomoteur.
Un écran OLED, généralement basé sur la technologie I2C (comme le module SSD1306), est utilisé pour afficher l’angle actuel sélectionné par l’utilisateur, offrant une lecture claire et immédiate. Le servomoteur s’oriente alors automatiquement vers cette position.
Ce projet combine des éléments essentiels de l’électronique embarquée — lecture d’encodeur, génération de signaux PWM, et affichage — et constitue une excellente introduction aux interfaces homme-machine et au contrôle de mouvement.
Prérequis :
- 1 x Carte Arduino Uno
- 1 x Encodeur rotatif avec interrupteur
- 1 x 0.91 inch OLED I2C Display 128 x 32 Pixels
- 1 x Condensateur 1000μf 16v (optionnel)
- 1 x Servomoteur
- 1 x Alimentation 5v
- 1 x Breadboard
- Fils de connexion
Version IDE :
- Arduino IDE 2.3.5
Bibliothèque :
- Adafruit_GFX.h (version: 1.12.1)
- Adafruit_SSD1306.h (version: 2.5.14)
- Adafruit BusIO (version: 1.17.1)
Vidéo de démonstration :
Schéma de câblage :


Code :
// Inclure les bibliothèques dont nous avons besoin
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire);
#include <Servo.h>
Servo myservo;
int Pinservo = 6;
#define S1 2 // Broche S1 de l'encodeur sur la pin 2 de l'Arduino
#define S2 3 // Broche S2 de l'encodeur sur la pin 3 de l'Arduino
int KEY = 4; // Broche KEY de l'encodeur sur la pin 4 de l'Arduino
int vitessepos[4] = { 1, 2, 4, 8 };
int selectvitesse;
int servopos = 0;
int etatActuelS1;
int etatPrecedentS1;
int etatActuelKEY;
int etatPrecedentKEY;
void setup() {
Serial.begin(9600);
pinMode(S1, INPUT); //Pin S1 déclarée en entrée
pinMode(S2, INPUT); //Pin S2 déclarée en entrée
pinMode(KEY, INPUT); // Pin KEY déclarée en entrée
etatPrecedentS1 = digitalRead(S1);
etatPrecedentKEY = digitalRead(KEY);
myservo.attach(Pinservo);
attachInterrupt(digitalPinToInterrupt(S1), updateEncoder, CHANGE);
// Démarrer les bibliothèques
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Address 0x3C for 128x32
display.clearDisplay();
//Défini la couleur du texte
display.setTextColor(WHITE);
delay(1000);
}
void loop() {
// On imprime les infos sur écran OLED
display.clearDisplay();
display.setCursor(105, 15);
display.drawLine(75, 0, 75, display.height() - 1, SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(0, 0);
display.println("Angle servo Vitesse");
display.setCursor(90, 15);
display.setTextSize(1);
display.println("x");
display.setCursor(105, 15);
display.println(vitessepos[selectvitesse]);
if (servopos < 10) {
display.setCursor(30, 15);
} else if (servopos >= 10 && servopos < 100) {
display.setCursor(20, 15);
} else {
display.setCursor(10, 15);
}
display.setTextSize(2);
display.println(servopos);
display.drawCircle(50, 18, 3, WHITE);
display.display();
myservo.write(servopos);
etatActuelKEY = digitalRead(KEY);
if (etatActuelKEY != etatPrecedentKEY) {
etatPrecedentKEY = etatActuelKEY;
if (etatActuelKEY == LOW)
selectvitesse++;
if (selectvitesse > 3) {
selectvitesse = 0;
}
delay(10);
}
}
void updateEncoder() {
etatActuelS1 = digitalRead(S1);
if (etatActuelS1 != etatPrecedentS1 && etatActuelS1 == 1) {
if (digitalRead(S2) != etatActuelS1) {
servopos = servopos - (1 * vitessepos[selectvitesse]);
} else {
servopos = servopos + (1 * vitessepos[selectvitesse]);
}
}
etatPrecedentS1 = etatActuelS1;
servopos = max(servopos, 0);
servopos = min(servopos, 180);
}
