Aus Raspberry Pi Geek 12/2020

Mit dem TX-Pi-HAT den Raspberry Pi mit Fischertechnik verbinden (Seite 2)

Abbildung 2 zeigt den Schaltplan unseres Versuchsaufbaus. Im Großen und Ganzen sind nur die Verbindungen der einzelnen Module zu sehen. Die Widerstände an den Schaltern dienen dazu, das Potenzial der Eingänge auf 0 Volt zu ziehen. Alternativ könnte man auch die internen Pullup-Widerstände des MCP23017 verwenden. Das würde allerdings bedeuten, dass sich die Logik der Schalter umkehrt (Schalter gedrückt 0 Volt, sonst 5 Volt).

Abbildung 2: Der Schaltplan des Versuchsaufbaus.

Abbildung 2: Der Schaltplan des Versuchsaufbaus.

Der Endschalter für die Nullposition neigt sehr zum Prellen, schaltet also bei einem Pegelwechsel unkontrolliert schnell hin und her. Das würde unser Programm stören. Daher spendieren wir dem Aufbau einen kleinen Kondensator, den wir parallel zum Schalter anschließen, was das Prellen zuverlässig unterbindet. Es gibt noch viele weitere Möglichkeiten, das Prellen von Schaltern in den Griff zu bekommen, der Kondensator gehört aber zu den einfachsten Lösungen.

Abbildung 3 zeigt den kompletten Versuchsaufbau, der fast komplett aus Teilen von Fischertechnik besteht. Die Achsen, die den Aufzug führen, sowie die Achse für den Schneckenantrieb sind nicht original, da es diese Achsen von Fischertechnik selbst nicht in den benötigten Längen gibt. Auch die Taster und die dazugehörigen Halter stammen nicht aus dem Repertoire des Konstruktionsbaukastenherstellers: Das 3D-Modell dafür erhalten Sie bei Thingiverse [8].

Abbildung 3: Der vom Raspberry Pi gesteuerte Versuchslift.

Abbildung 3: Der vom Raspberry Pi gesteuerte Versuchslift.

Als Betriebssystem für den Raspberry Pi dient das aktuelle Raspberry Pi OS mit Desktop und empfohlener Software. Es steht auf der Homepage des Raspberry-Projekts zum Herunterladen bereit [9]. Wir verwenden hier die Full-Version, damit wir später keine zusätzlichen Pakete installieren müssen.

Um das MCP23017-I2C-Modul zu verwenden, müssen Sie zunächst einmal die I2C-Unterstützung des Raspberry Pi über dessen Konfigurationsprogramm aktivieren. Dazu tippen Sie auf der Shell sudo raspi-config, wählen den Punkt 5 Interfacing Options | P5 I2C und aktivieren mit Ja die I2C-Schnittstelle. Um zu überprüfen, ob das MCP23017-Modul richtig arbeitet, verwenden Sie das Tool I2c-detect, das die Ausgabe aus Listing 1 liefern sollte.

Listing 1

$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Klappt das, können Sie mit den Kommandos aus den ersten beiden Zeilen von Listing 2 den Port A des MCP23017 für die Eingabe konfigurieren und die aktuellen Werte auslesen. Jeder Schalter entspricht dabei einem Bit. Der Taster für die Nullposition ist direkt am Eingang I1 angeschlossen, sodass er sich über GPIO26 abfragen lässt (Zeile 3). Schließen Sie den Schalter so an, dass er eine 1 liefert, sobald er gedrückt ist.

Listing 2

$ i2cset -y 1 0x20 0x00 0xFF
$ watch -n 0.5 'i2cget -y 1 0x20 0x12'
$ gpio mode 26 in; watch -n 0.5 'gpio read 26'

Um den Motor zu testen, versetzen Sie im ersten Schritt alle benötigten GPIOs in den Ausgabemodus (Listing 3, Zeile 1). Dann setzen Sie den STBY– und den PWM-Eingang des Treiber-ICs auf logisch 1 (Zeile 2 und 3), um den Motorausgang zu aktivieren. Im letzten Schritt lassen Sie den Motor für jeweils eine Sekunde herunter- und wieder herauffahren (Zeile 4 und 5). Achten Sie bitte darauf, dass sich die Fahrgastzelle möglichst in der Mitte des Aufzugsschachts befindet, damit es nicht zu Kollisionen kommt.

Listing 3

$ gpio mode 24 out; gpio mode 23 out; gpio mode 21 out; gpio mode 22 out
$ gpio write 24 1
$ gpio write 23 1
$ gpio write 21 1; sleep 1; gpio write 21 0
$ gpio write 22 1; sleep 1; gpio write 22 0

Falls der Motor sich in die falsche Richtung bewegt, vertauschen Sie die zwei Zuleitungen am Motor. Damit sind alle Tests abgeschlossen. Die Funktion des Impulsgebers überprüfen Sie mit unserem Beispielprogramm. Falls Sie den Aufzug vorab in Aktion sehen möchten, schauen Sie doch einfach einmal bei Youtube vorbei [10].

Beispielprogramm

Wie eingangs schon erwähnt, ist das Testprogramm in C geschrieben, damit wir den Impulsgeber des Fischertechnik-Motors mithilfe eines interruptgesteuerten Codes abfragen können. Sehen wir uns nun das Programm lift.c etwas genauer an (Listing 4).

Listing 4

#include <stdio.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <wiringPiI2C.h>
// Constants
#define STBY 24
#define PWM1 23
#define UP   22
#define DOWN 21
#define ZERO 26
#define PULSE 27
#define DEBUG 0
//Global Variables
volatile int position;
volatile int direction;
int target;
void liftUp(void){
  if (DEBUG) {printf("Lift up\n");}
  direction=1;
  digitalWrite(UP,HIGH);
  digitalWrite(DOWN,LOW);
}
void liftDown(void){
  if (DEBUG) {printf("Lift down\n");}
  direction=0;
  digitalWrite(UP,LOW);
  digitalWrite(DOWN,HIGH);
}
void liftStop(void){
  digitalWrite(UP,HIGH);
  digitalWrite(DOWN,HIGH);
  if (DEBUG) {printf("Lift stop\n");}
}
void interruptZeroPosition(void){
  if (DEBUG) {printf("Zero Position\n");}
  liftStop();
  position=0;
}
void interruptPulse(void){
  if (DEBUG) {printf("Interrupt Pulse (%d)\n", position);}
  if (direction == 0) {
    position --;
  } else {
    position ++;
  }
  if (position==target) {
    liftStop();
  }
}
void init(void){
  wiringPiSetup();
  pinMode (STBY,  OUTPUT) ;
  pinMode (PWM1,  OUTPUT) ;
  pinMode (UP,    OUTPUT) ;
  pinMode (DOWN,  OUTPUT) ;
  pinMode (ZERO,  INPUT) ;
  pinMode (PULSE, INPUT) ;
  digitalWrite(PWM1,HIGH);
  digitalWrite(STBY,HIGH);
  wiringPiISR (ZERO,  INT_EDGE_RISING, &interruptZeroPosition);
  wiringPiISR (PULSE, INT_EDGE_RISING, &interruptPulse);
  liftDown();
  delay(20000);
  target=155;
  liftUp();
  delay(1000);
}
void go(int t){
  target=t;
  if (DEBUG) {printf("Target: %d Position: %d\n", target,position);}
  if (position>target){
    liftDown();
  } else {
    liftUp();
  }
}
int main(void) {
  init();
  int handle = wiringPiI2CSetup(0x20);
  wiringPiI2CWriteReg8(handle,0x00,0xff);
  int value;
  while(1){
    value=wiringPiI2CReadReg8 (handle,0x12);
    switch(value){
      case 1:  go(140);  break;
      case 2:  go(1110); break;
      case 4:  go(2155); break;
      case 8:  go(3155); break;
      case 16: go(4155); break;
      case 32: go(5150); break;
    }
    delay(50);
  }
}

Zu Beginn importiert der Code die nötigen Bibliotheken, definiert einige Konstanten, die die GPIO-Ports repräsentieren, und legt einige globale Variablen an. Das Schlüsselwort volatile definiert Variablen, die nicht gecacht werden dürfen, da sie auch von anderen Programmteilen verändert werden können. In unseren Fall betrifft das die beiden Interrupt-Handler interruptZeroPosition() und interruptPulse().

Der Handler interruptZeroPosition() sorgt dafür, dass die Variable position auf 0 gesetzt wird, sobald der Lift den Taster für die Nullposition erreicht. Zusätzlich stoppt die Funktion den Motor. Der zweite Interrupt-Handler dient dazu, die Variable position abhängig von der Bewegungsrichtung des Motors herauf- oder herunterzuzählen.

Die drei Funktionen liftUp(), liftDown und liftStop lassen den Aufzug in eine bestimmte Richtung fahren beziehungsweise halten ihn an. Hierbei gilt es zu beachten, dass die Funktion liftStop() den Motor mithilfe der Kurzschlussfunktion anhält. Das verhindert, dass der Aufzug über seine Zielposition herausfährt.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 6 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Raspberry Pi Geek bei Google Play Readly Logo
Nach oben