Skip to content

Technik Blog

Programmieren | Arduino | ESP32 | MicroPython | Python | Raspberry Pi | Raspberry Pi Pico

Menu
  • Smarthome
  • Arduino
  • ESP32 & Co.
  • Raspberry Pi & Pico
  • Solo Mining
  • Über mich
  • Deutsch
  • English
Menu

Weekend Project: 7 Segmentanzeige mit Servomotoren

Posted on 13. April 20196. März 2024 by Stefan Draeger

Im nachfolgenden Weekend Project möchte ich gerne aufzeigen wie man sich eine eigene, große 7 Segmentanzeige mit Servomotoren erstellen kann.

7 Segmentanzeige mit Servomotoren – „Ziffer 3“

Ich habe dieses Projekt zuerst in einem Instagram Beitrag gesehen und fand dieses cool, daher wollte ich dieses gerne nachbauen und natürlich auf meinem Blog einen Beitrag dazu schreiben.

7 Segmentanzeige mit Servomotoren - Ziffern 0 & 1
Dieses Video auf YouTube ansehen.

  • Was ist eine 7 Segmentanzeige?
  • Materialien & Werkzeuge
    • Materialien
    • Werkzeuge
    • elektrische Bauelemente
  • Vorlage
  • Aufbau der 7 Segmentanzeige mit Sperrholz
  • Anschließen der 7 Servomotoren
    • PWMServoDriverShield – Typ „PCA9685“
    • Spannungsversorgung der Servos
    • Programmieren des PAC9685 Servo Driver Shield
      • Einfaches Beispiel mit einem Servo
        • Video
    • Sketch für die 7 Segmentanzeige
    • interne Klasse „Segment“
      • kompletter Sketch
  • Download der Programme für die 7 Segmentanzeige mit Servomotoren

Was ist eine 7 Segmentanzeige?

Mit einer 7 Segmentanzeige kann man die Zahlen von 0 bis 9 und einfache Buchstaben anzeigen.

7 Segmentanzeige am MakerUNO
7 Segmentanzeige am MakerUNO

Ich habe bereits im Tutorial Arduino Lektion 62: 7 Segmentanzeige eine 7 Segmentanzeige vorgestellt. 

Materialien & Werkzeuge

Materialien

Folgende Materialien werden benötigt:

  • 2x 3 mm, DIN A4 Sperrholz,
  • Holzleiste, 20 cm lang, 10 mm stark
  • eventuell, Farbe für die Displayfläche,

Werkzeuge

  • Laubsäge,
    • Laubsägeblätter, fein
  • Heißklebepistole,
  • Holzleim,
  • Papierkleber, 
  • kleiner, Kreuzschraubendreher 
  • kleiner, Schlitzschraubendreher

elektrische Bauelemente

  • 1x Arduino Leonardo*,
    • USB Kabel mit Micro USB Stecker,
  • 7x Servo Motor 9g*,
  • 1x PWMServoDriverShield – Typ „PCA9685“*,
  • 6x Breadboardkabel, 20cm Lang, männlich – weiblich

Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!

Vorlage

Zunächst einmal habe ich mir eine Vorlage im Zeichenprogramm paint.net erzeugt und diese ausgedruckt dann auf das Sperrholz geklebt.

Vorlage für eine 7 Segmentanzeige auf Sperrholz
Vorlage für eine 7 Segmentanzeige auf Sperrholz

Ich habe dafür den Papierkleber der Firma „Pritt“ benutzt.
Diese ist deutlich besser als die günstigen.

Die Vorlage kannst du dir unter folgendem Link herunterladen:

Vorlage – 7 SegmentanzeigeHerunterladen

Aufbau der 7 Segmentanzeige mit Sperrholz

Im folgenden Video zeige ich, wie ich die 7 Segmentanzeige mit Sperrholz erstellt habe.

Zunächst einmal habe ich jedes Segment mit der Laubsäge ausgesägt und danach auf das korrekte Maß geschliffen.  Danach wurde eine kleine 2 cm lange Holzleiste montiert, damit dieses besser hält, habe ich jeweils ein 2 mm Loch hineingebohrt und ein 3 mm x 12 mm Kreuzschraube inkl. Holzleim verwendet. Wenn alle 7 Segmente montiert wurden dann wurden die Servomotoren mit der Heißklebepistole festgeklebt und diese danach auf die übrige Sperrholzplatte montiert. Zum Schluss habe ich die Segmente angestrichen.

DIY - 7 Segment Anzeige, Schritt 1 - Aufbau
Dieses Video auf YouTube ansehen.

Anschließen der 7 Servomotoren

Für den Betrieb der Servos verwende ich das PWMServoDriverShield vom Typ „PCA9685„. Dieses kann man bei ebay.de für knapp  5 € inkl. Versandkosten erwerben.

PWMServoDriverShield – Typ „PCA9685“

Das Shield hat den Vorteil, dass man die Servos per I2C ansprechen kann und somit die digitalen Pins des Mikrocontrollers freihat. Ein weiterer großer Vorteil ist, dass die somit hat man die Möglichkeit nicht nur 16 Servos zu betreiben, sondern bis zu 6x 16 Stück = 96 Stück.

PCA9685 16 Kanal Servo Driver Shield
PCA9685 16 Kanal Servo Driver Shield

Auf der Rückseite des Moduls sind die maximalen Lasten für das Modul aufgedruckt.

PCA9685 16 Kanal Servo Driver Shield - Rückseite
PCA9685 16 Kanal Servo Driver Shield – Rückseite

Das Modul verfügt über 16 Steckplätze für Servomotoren, diese sind in der korrekten Pinanordnung sodass man den Stecker des Servos direkt drauf stecken kann.

16 Kanal Servo Modul PCA9685 mit Servo
16 Kanal Servo Modul PCA9685 mit Servo

Des Weiteren verfügt das Modul über 6 Pins welche mit dem Microcontroller verbunden werden.

Je nach verwendeten Mikrocontroller muss das Modul anders angeschlossen werden. Hier nun die 3 Möglichkeiten für die gängigen Mikrocontroller der Arduino Baureihe:

Arduino UNO

  • VCC an 5V
  • GND an GND
  • SDA an analog A4
  • SCL an analog A5
Servo Driver Modul PAC9685 am Arduino UNO
Servo Driver Modul PAC9685 am Arduino UNO

Arduino Mega 2560 R3

  • VCC an 5V
  • GND an GND
  • SDA an digital 20
  • SCL an digital 21
Servo Driver Modul PAC9685 am Mega
Servo Driver Modul PAC9685 am Mega

Arduino Leonardo

  • VCC an 5V
  • GND an GND
  • SDA an SDA
  • SCL an SCL
Servo Driver Modul PAC9685 am Arduino Leonardo
Servo Driver Modul PAC9685 am Arduino Leonardo

Spannungsversorgung der Servos

Die Servos werden über einen Separaten Anschluß auf dem Modul mit Spannung versorgt. Die beiden Pins VCC & GND dienen „nur“ zum betrieb des Modules.

PAC9685 Schraubklemme für Spannungsversorgung der Servos
PAC9685 Schraubklemme für Spannungsversorgung der Servos

Programmieren des PAC9685 Servo Driver Shield

Damit wir das Modul verwenden können benötigen wir zusätzlich eine Bibliothek, diese können wir in der Arduino IDE bequem über den „Bibliotheksverwalter“ installieren.  

Die benötigte Bibliothek heißt „Adafruit PWM Servo Driver Library“ und kann über das Eingabefeld mit der Zeichenkette „pwm servo“ gefunden werden.

Arduino IDE - Bibliotheksverwalter "Adafruit PWM Servo Driver Library"
Arduino IDE – Bibliotheksverwalter „Adafruit PWM Servo Driver Library“

Wenn die Bibliothek installiert wurde kann es mit der Programmierung schon beginnen.

Einfaches Beispiel mit einem Servo

Als erstes wollen wir einen Servo betreiben und diesen von 0° bis 180° und zurück bewegen lassen.

#include <Wire.h> // OneWire Bibliothek
#include <Adafruit_PWMServoDriver.h> //Bibliothek für das PAC9585 Modul

//erzeugen einer Instanz für die Kommunikation
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); 

// Minimum der Pulselänge 
const int SERVOMIN = 125;
// Maximum der Pulselänge
const int SERVOMAX = 575;

//Port an welchem der Servo angeschlossen ist
const int SERVO_PORT = 0;
//Pause zwischen den einzelnen Schritten
const int PAUSE = 25;

void setup() {
  //beginn der Kommunikation
  pwm.begin();  
  //setzen der PWM Frequenz auf 60Hz
  pwm.setPWMFreq(60);
}

void loop() {
  //Schleife von 0..180
  for(int angle = 0;angle<180;angle++){
      //setzen des aktuellen Wertes von "angle" an dem Servo
      //dabei muss der aktuelle Winkel auf die Pulslänge gemappt werden. 
      pwm.setPWM(SERVO_PORT, 0, map(angle,0, 180, SERVOMIN,SERVOMAX));
      //eine kleine Pause
      delay(PAUSE);
  }

  //Schleife von 180..0
  for(int angle = 180;angle>=0;angle--){
      //setzen des aktuellen Wertes von "angle" an dem Servo
      //dabei muss der aktuelle Winkel auf die Pulslänge gemappt werden. 
      pwm.setPWM(SERVO_PORT, 0, map(angle,0, 180, SERVOMIN,SERVOMAX));
      //eine kleine Pause
      delay(PAUSE);
  }
}
Video
PWM Servo Driver Shield PAC9685 mit einem Servo
Dieses Video auf YouTube ansehen.

Sketch für die 7 Segmentanzeige

interne Klasse „Segment“

Da ich bedingt durch die Künste nicht ganz gerade Sägen zu können etwas Toleranz in jedem Segment benötige habe ich mir die interne Klasse „Segment“ erzeugt.

Diese Klasse erhält

  • den Port an welchem der Servo angeschlossen ist,
  • den Namen,
  • den Wert „maxAngle“ für den untersten Wert,
  • den Wert „minAngle“ für den obersten Wert
class Segment{

 private:
  String name;
  int port;
  int maxAngle;
  int minAngle;

 public:
   Segment(String n, int p,int maxA, int minA){
     name = n;
     port = p;
     maxAngle = maxA;
     minAngle = minA;
   }

   String getName(){ return name; }
   int getPort(){ return port; }
   int getMaxAngle(){ return maxAngle; }
   int getMinAngle(){ return minAngle; }
};

Zunächst einmal werden wir also die Servos an den einzelnen Ports mit einer neuen Instanz der Klasse „Segment“ definieren.

Segment segmentA = Segment("Segment A", 0, 180, 90);
Segment segmentB = Segment("Segment B", 1, 180, 100);
Segment segmentC = Segment("Segment C", 2, 160, 60);
Segment segmentD = Segment("Segment D", 3, 160, 60);
Segment segmentE = Segment("Segment E", 4, 170, 60);
Segment segmentF = Segment("Segment F", 5, 140, 60);
Segment segmentG = Segment("Segment G", 6, 160, 90);

Ich verwende hier die Beschriftung A-G diese ist für die Definition der einzelnen Segmente einer 7 Segmentanzeige üblich.

7Segmentanzeige - Definition Segmente
7Segmentanzeige – Definition Segmente

Nun müssen wir noch in der Funktion „setup“ das PWM Modul „starten“ und die Frequenz für die Kommunikation festlegen, bei den von mir verwendeten Servos liegt diese bei 60Hz.

void setup() {
  Serial.begin(9600);
  Serial.println("16 channel Servo test!");

  pwm.begin();  
  pwm.setPWMFreq(60); 
}

In der Funktion „loop“ werden nun die einzelnen Funktionen zum Anzeigen einer Zahl aufgerufen. Ich habe dieses einmal beispielhaft für die Zahlen 0 & 1 getan.

void loop() {
  displayNum0();
  delay(PAUSE);
  displayNum1();
  delay(PAUSE);
}

In den Funktionen selber wird zunächst ein Reset ausgeführt, dieses sorgt dafür, dass alle Servos in den Zustand „nicht angezeigt“ gehen (quasi im Winkel von 180°).

void reset(){
  resetSegment(segmentA);
  delay(PAUSE_KL);
  resetSegment(segmentB);
  delay(PAUSE_KL);
  resetSegment(segmentC);
  delay(PAUSE_KL);
  resetSegment(segmentD);
  delay(PAUSE_KL);
  resetSegment(segmentE);
  delay(PAUSE_KL);
  resetSegment(segmentF);
  delay(PAUSE_KL);
  resetSegment(segmentG);
}

Da ich doppelten Quellcode vermeiden möchte, habe ich mir wiederum eine extra Funktion geschrieben, in welcher ich den Port übergebe und diese mit dem Servo auf den benötigten Winkel setzt.

void resetSegment(Segment segment){
  moveServo("reset ->",segment.getName(),segment.getPort(), angleToPulse(segment.getMaxAngle()));
}

Hier kommt auch schon die nächste Funktion „moveServo“ hat 3 Parameter, 

  • die Aktion, für die Ausgabe auf dem Seriellen Monitor der Arduino IDE,
  • den Port, an welchem der Servo angeschlossen ist,
  • der Winkel, in welchem Winkel der Servo versetzt werden soll
void moveServo(String action, String name, int port, int angle){
  Serial.print(action);
  Serial.println(name);  
  pwm.setPWM(port, 0, angleToPulse(angle));
}

Da das Modul PAC9685 mit Pulsen anstatt Winkeln arbeitet müssen wir zunächst den gewünschten Winkel in ein Pulse umwandeln, dazu nutzen wir die Funktion „map“. Wir wissen, dass bei Pulse „125“ der minimale Wert (also 0°) und bei „575“ der maximale Wert erreicht (also 180°) ist.

int angleToPulse(int ang){
   return map(ang,0, 180, SERVOMIN,SERVOMAX);
}

Nehmen wir einmal Beispielhaft die Zahl „0“, hier müssen alle Segmente aufgerichtet werden außer das Segment „G“. Wie erwähnt wird zunächst ein Reset ausgeführt, danach wird jedes einzelne Segment aufgerichtet. Zwischen den einzelnen Segmenten habe ich eine kleine Pause eingeführt, dieses musste ich machen da es wohl zeitliche Probleme gibt.

void displayNum0(){
  reset();
  moveUp(segmentA);
  delay(PAUSE_KL);
  moveUp(segmentB);
  delay(PAUSE_KL);
  moveUp(segmentC);
  delay(PAUSE_KL);
  moveUp(segmentD);
  delay(PAUSE_KL);
  moveUp(segmentE);
  delay(PAUSE_KL);
  moveUp(segmentF);
}

Für die Zahl „1“ würden dann nur das Segment „B“ & „C“ aktiviert usw.

kompletter Sketch

Hier nun der komplette Sketch. Im unteren Bereich dieses Tutorials findest du den Sketch zum bequemen Download.

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

#define SERVOMIN  125 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  575 // this is the 'maximum' pulse length count (out of 4096)

const int PAUSE = 1000;
const int PAUSE_KL = 250;

class Segment{

 private:
  String name;
  int port;
  int maxAngle;
  int minAngle;

 public:
   Segment(String n, int p,int maxA, int minA){
     name = n;
     port = p;
     maxAngle = maxA;
     minAngle = minA;
   }

   String getName(){ return name; }
   int getPort(){ return port; }
   int getMaxAngle(){ return maxAngle; }
   int getMinAngle(){ return minAngle; }
};

Segment segmentA = Segment("Segment A", 0, 180, 90);
Segment segmentB = Segment("Segment B", 1, 180, 100);
Segment segmentC = Segment("Segment C", 2, 160, 60);
Segment segmentD = Segment("Segment D", 3, 160, 60);
Segment segmentE = Segment("Segment E", 4, 170, 60);
Segment segmentF = Segment("Segment F", 5, 140, 60);
Segment segmentG = Segment("Segment G", 6, 160, 90);


void setup() {
  Serial.begin(9600);
  Serial.println("16 channel Servo test!");

  pwm.begin();  
  pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates
}

void loop() {
  displayNum0();
  delay(PAUSE);
  displayNum1();
  delay(PAUSE);
}

void displayNum0(){
  reset();
  moveUp(segmentA);
  delay(PAUSE_KL);
  moveUp(segmentB);
  delay(PAUSE_KL);
  moveUp(segmentC);
  delay(PAUSE_KL);
  moveUp(segmentD);
  delay(PAUSE_KL);
  moveUp(segmentE);
  delay(PAUSE_KL);
  moveUp(segmentF);
}

void displayNum1(){
  reset();
  moveUp(segmentB);
  delay(PAUSE_KL);
  moveUp(segmentC);
}

void displayNum2(){
  reset();
  moveUp(segmentA);
  delay(PAUSE_KL);
  moveUp(segmentB);
  delay(PAUSE_KL);
  moveUp(segmentG);
  delay(PAUSE_KL);
  moveUp(segmentE);
  delay(PAUSE_KL);
  moveUp(segmentD);
  delay(PAUSE_KL);
}

void displayNum3(){
  reset();
  moveUp(segmentA);
  moveUp(segmentB);
  moveUp(segmentG);
  moveUp(segmentC);
  moveUp(segmentD);
}

void displayNum4(){
  reset();
  moveUp(segmentF);
  moveUp(segmentG);
  moveUp(segmentB);
  moveUp(segmentC);
}

void displayNum5(){
  reset();
  moveUp(segmentA);
  moveUp(segmentF);
  moveUp(segmentG);
  moveUp(segmentC);
  moveUp(segmentD);
}

void displayNum6(){
  reset();
  moveUp(segmentA);
  moveUp(segmentF);
  moveUp(segmentG);
  moveUp(segmentE);
  moveUp(segmentD);
  moveUp(segmentC);
}

void displayNum7(){
  reset();
  moveUp(segmentA);
  moveUp(segmentB);
  moveUp(segmentC);
}

void displayNum8(){
  reset();
  moveUp(segmentA);
  moveUp(segmentB);
  moveUp(segmentC);
  moveUp(segmentD);
  moveUp(segmentE);
  moveUp(segmentF);
  moveUp(segmentG);
}

void displayNum9(){
  reset();
  moveUp(segmentA);
  moveUp(segmentB);
  moveUp(segmentC);
  moveUp(segmentG);
  moveUp(segmentF);
}

void reset(){
  resetSegment(segmentA);
  delay(PAUSE_KL);
  resetSegment(segmentB);
  delay(PAUSE_KL);
  resetSegment(segmentC);
  delay(PAUSE_KL);
  resetSegment(segmentD);
  delay(PAUSE_KL);
  resetSegment(segmentE);
  delay(PAUSE_KL);
  resetSegment(segmentF);
  delay(PAUSE_KL);
  resetSegment(segmentG);
}

void resetSegment(Segment segment){
  moveServo("reset ->",segment.getName(),segment.getPort(), segment.getMaxAngle());
}

void moveUp(Segment segment){
  moveServo("moveUp ->",segment.getName(),segment.getPort(), segment.getMinAngle());
}

void moveDown(Segment segment){
  moveServo("moveDown ->",segment.getName(),segment.getPort(), segment.getMaxAngle());
}

void moveServo(String action, String name, int port, int angle){
  Serial.print(action);
  Serial.println(name);  
  pwm.setPWM(port, 0, angleToPulse(angle));
}

int angleToPulse(int ang){
   return map(ang,0, 180, SERVOMIN,SERVOMAX);
}

Download der Programme für die 7 Segmentanzeige mit Servomotoren

Vorlage – 7 SegmentanzeigeHerunterladen
7 Segmentanzeige mit Servomotoren – SketchHerunterladen
PAC9685 simple Servo SketchHerunterladen

Schreibe einen Kommentar Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden?
Support-Ticket erstellen

Newsletter abonnieren

Bleib auf dem Laufenden: Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32 und mehr – direkt in dein Postfach.

Jetzt Newsletter abonnieren

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee.
So hilfst du mit, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

draeger-it.blog auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kategorien

Tools

  • Unix-Zeitstempel-Rechner
  • ASCII Tabelle
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner
  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix – Generator

Links

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com

Stefan Draeger
Königsberger Str. 13
38364 Schöningen

Tel.: 01778501273
E-Mail: info@draeger-it.blog

Folge mir auf

  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
©2025 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Optionen verwalten Dienste verwalten Verwalten von {vendor_count}-Lieferanten Lese mehr über diese Zwecke
Einstellungen anzeigen
{title} {title} {title}