Zum Inhalt springen

Eigene Klassen und Objekte am Beispiel einer Motorsteuerung

Eine Klasse (class) ist die zentrale Datenstruktur in C++. Sie enthält nicht nur Daten, sondern auch Methoden, um die Daten selbstständig zu verwalten.

Am Beispiel einer Motorklasse wird gezeigt, wie eine Klasse benutzt wird und wie sie aufgebaut ist.

Rechts sieht man ein kleines Programm, das einen Motor zwei Sekunden vorwärts und anschließend 2 Sekunden rückwärts laufen lässt.

Bei dieser Art der Programmierung muss man ständig wissen, mit welchen Pins der Motor anzusteuern ist. Sollen dann noch mehrere Motoren gesteuert werden, wird das Programm sehr schnell unübersichtlich.

Mit einer Motor-Klasse geht das wesentlich eleganter:

#include"motor.h"

Motor M1(5,6,7);

void setup() 
{

}

void loop() 
{
  M1.power(200);
  delay(1000);
  M1.power(-300);
  delay(1000);
  M1.power(0);
}

Um die Klasse Motor überhaupt nutzen zu können muss mittels #include "motor.h" die sogenannte Header-Datei eingebunden werden.

Mit Motor M1(5,6,7); wird das Objekt M1 vom Typ Motor erzeugt. Man beachte, dass hier die Pins für die Motorsteuerung übergeben werden.

In der setup-Methode ist es nicht mehr nötig, den Pinmode für die Pins auf OUTPUT zusetzen. Das macht das Motor-Objekt selbst.

M1.power(200); ist eine Methode des Objekts M1, die den Motor mit einer Leistung von 200 einschaltet. Mögliche Leistungswerte sind -255 bis 255. Dabei dreht sich der Motor bei negativen Werten rückwärts. M1.power(0); stoppt den Motor.

Die Header-Datei

In der Header-Datei (hier motor.h) werden die Methoden und Daten festgelegt.

Hier sind das die Methoden Motor(int e,int a,int b); und power(int p); sowie die Variablen int en,m1,m2;

Der Konstruktor

Die Methode Motor hat den gleichen Namen, wie die Klasse, zu der sie gehört. Die Methode Motor wird aufgerufen, sobald ein Objekt vom Typ Motor erzeugt wird. Solche Methoden werden Konstruktor genannt. Im Konstruktor der Klasse Motor werden zunächst die übergebenen Pinnummern gespeichert und die Pins auf OUTPUT gestellt.

Compiler-Anweisungen

Mit

#ifndef Motor_h 
#define Motor_h 
... 
#endif

wird dafür gesorgt, dass die Header-Datei nur einmal ausgewertet wird.

#ifndef Motor_h
#define Motor_h

# include "Arduino.h"


class Motor
{
  private:
  int en,m1,m2;
  
  public:
  
  Motor(int e,int a,int b);
  void power(int p);
};
#endif

Zugriffskontrolle

Ein grundlegendes Konzept der objektorientierten Programmierung ist die Datenkapselung.

Daten oder Methoden, die mit private deklariert wurden, sind nur von Methoden der Klasse aus erreichbar.

Im Beispiel soll nicht direkt auf die Variablen en, m1 und m2 zugegriffen werden. Das ist ja die Aufgabe der Klasse Motor.

Auf Daten oder Methoden, die mit public deklariert werden, kann von außen zugegriffen werden. Die Methode power ist eine solche Methode. Mit M1.power(200); benutzen wir die Methode power des Objekts M1, um den Motor auf eine Leistung von 200 zu stellen. Die Methode power hat, da sie in der Klasse Motor deklariert wurde, Zugriff auf die Variablen en, m1 und m2.

Die cpp-Datei

Die Implementierung, d.h. der Code für die jeweiligen Methoden der Klasse, erfolgt in einer cpp-Datei (hier motor.cpp).

In der Methode Motor(int e, int a,int b), dem Konstruktor, werden zunächst die übergebenen Pinnummern in den Variablen en,m1 und ,m2 gespeichert. Anschließend werden die entsprechenden Pins auf OUTPUT gestellt.

In der Methodepower(int p) wird zunächst dafür gesorgt, dass -255<=p<=255 ist.
Für p>=0 läuft der Motor mit einer Leistung von p vorwärts.
Für p<0 läuft der Motor mit einer Leistung von -p rückwärts.

Das Beispiel kann hier heruntergeladen werden.

#include"motor.h"

Motor::Motor(int e, int a,int b)
{
  en=e;
  m1=a;
  m2=b;
  pinMode(en,OUTPUT);
  pinMode(m1,OUTPUT);
  pinMode(m2,OUTPUT);
}

void Motor::power(int p)
{
  p=constrain(p,-255,255);
  if(p>=0)
  {
    analogWrite(en,p);
    digitalWrite(m1,HIGH);
    digitalWrite(m2,LOW);
  }
  else
  {
    analogWrite(en,-p);
    digitalWrite(m2,HIGH);
    digitalWrite(m1,LOW);
  }
}
#endif