Startseite>Fischertechnik-Förderbänder per Controllino ansteuern
Aus Raspberry Pi Geek 10/2018

Fischertechnik-Förderbänder per Controllino ansteuern (Seite 2)

Das hat den Vorteil, dass sich die Werte vor dem Kompilieren einsetzen lassen, ohne gesonderten Speicherplatz für Variablen zu erfordern. Damit lassen sich Programme kleiner und schneller gestalten. Würden wir hier mit const arbeiten, hieße das, für jede Konstante Speicher zu reservieren. Da der Mikrocontroller des Controllino in lediglich 265 KByte RAM alle Variablen, die Software und die verwendeten Bibliotheken vorhalten muss, gehört ressourcenschonender Code hier zum Pflichtprogramm.

Nun folgt die Definition der globalen Variablen. Dabei enthalten b0 bis b6 (Zeile 14) die digitalen Werte der Eingänge B0 bis B6. Hier gilt es, für die Erklärung etwas auszuholen.

Die Lichtschranken arbeiten mit 5 Volt, der Controllino dagegen mit 12 Volt. Aus dem Controllino-Basics-Artikel in dieser Ausgabe wissen Sie, dass der Controllino bei einer Betriebsspannung von 12 Volt Eingangsspannungen ab 9 Volt aufwärts als logisch 1 interpretiert. Die Lichtschranke erreicht also nie den Spannungspegel, der für eine logische 1 nötig wäre. Daher behelfen wir uns mit einem Trick: Wir lesen die Eingänge der Lichtschranken als Analogwerte ein und generieren daraus die Digitalwerte für die Eingänge. Diese landen dann in den Variablen b0 bis b6. Da der Metallsensor ausreichend hohe Pegel benutzt, entfällt bei ihm dieser Kunstgriff.

Die Variablen, die auf _previous enden (Zeile 15), speichern die Werte des vorherigen Schleifendurchlaufs. Das benötigen wir, um auf Flanken zu reagieren. Die Variablen metall und roboter (Zeile 16) dienen als Hilfsvariablen, die sich merken, ob der Metallsensor angeschlagen hat und der Roboter benachrichtigt wurde. Um Wartezeiten zu realisieren, speichern die auf _timer endenden Variablen die Timestamps bestimmter Aktionen (Zeile 17).

Die Funktion setup() ab Zeile 19 setzt die Pin-Modes für alle Ein- und Ausgänge; es gibt keinen speziellen Pin-Mode für die Analogeingänge.

Die loop()-Funktion ab Zeile 34 läuft als Endlosschleife. Ihre ersten Zeilen lesen die Analogwerte der Lichtschranken sowie des Metallsensors ein und wandeln diese in boolesche Werte um. Dabei kommt der C-Operator ?: zum Einsatz. Falls der logische Ausdruck vor dem Fragezeichen wahr ist, gibt der Operator den Wert vor dem Doppelpunkt zurück, ansonsten den dahinter. Mit diesem Ausdruck lassen sich einfache Fallunterscheidungen mit Zuweisung sehr leicht realisieren. Die Variablen b0 bis b6 speichern mithilfe dieses Operators die logischen Zustände aller Eingänge.

Wie eingangs erwähnt, besteht der kompakte Code fast nur aus Bedingungen. Nehmen wir direkt das erste if in Zeile 43 als Beispiel: Durch die logische Bedingung b5&&!b5_previous erreichen wir, dass der Code innerhalb des If-Blocks nur dann ausgeführt wird, wenn eine positive Flanke am Eingang B5 auftritt. In diesem Fall setzen wir die Variable metal auf HIGH, sprich: Der Metallsensor hat ausgelöst und wir speichern den Wert für die Zukunft.

Die Lichtschranken zum Starten der Bänder verwenden diesen Trick ebenfalls, um nur auf die Flanke zu reagieren. Eine Flankenänderung passiert immer genau einmal, zu einem definierten Zeitpunkt. Die Codestücke dürfen keinesfalls so lange ausgeführt werden, wie der Eingang auf HIGH steht; wir benötigen genau einen Aufruf beim Auftreten eines Ereignisses.

Sobald eine der Lichtschranken zum Starten auslöst, speichert die entsprechende _timer-Variable den aktuellen Timestamp. Eine weitere If-Abfrage prüft, ob das Auftreten des Ereignisses schon mehr als 5000 Millisekunden zurückliegt (Zeilen 49, 58, 67), und startet nur dann das Förderband. Die Verzögerung dient dazu, dem Roboter genug Zeit zu verschaffen, um den Gegenstand abzulegen und sich wieder aus dem Bereich des Förderbands zu entfernen.

Das Abschalten eines Bands (Zeilen 52 und 61) benötigt keinen Flanken-Trigger – sobald die Lichtschranke auslöst, stoppt der Motor.

Interessant ist die Stelle, an der die Lichtschranke b4 auslöst (ab Zeile 70). Sie stoppt den Motor M3 und wertet gleichzeitig die Variable metal aus. Abhängig von deren Zustand bekommt der Roboter das Kommando, den Gegenstand entweder auf Band 1 oder Band 2 abzustellen.

Die letzten vier Anweisungen ab Zeile 83 speichern die aktuellen Variablen für den nächsten Schleifendurchlauf, um sie für die Flankenauswertung zu verwenden.

Listing 1

 

#include <Controllino.h>
#define B0 CONTROLLINO_A0
#define B1 CONTROLLINO_A1
#define B2 CONTROLLINO_A2
#define B3 CONTROLLINO_A3
#define B4 CONTROLLINO_A4
#define B5 CONTROLLINO_A5
#define B6 CONTROLLINO_A6
#define M1 CONTROLLINO_R1
#define M2 CONTROLLINO_R2
#define M3 CONTROLLINO_R3
#define ROBOTER1 CONTROLLINO_R4
#define ROBOTER2 CONTROLLINO_R5
bool b0,b1,b2,b3,b4,b5,b6;
bool b0_previous,b2_previous,b5_previous,b6_previous;
bool metal,roboter;
long b0_timer,b2_timer,b4_timer,b6_timer;
void setup() {
  pinMode(B0,INPUT);
  pinMode(B1,INPUT);
  pinMode(B2,INPUT);
  pinMode(B3,INPUT);
  pinMode(B4,INPUT);
  pinMode(B5,INPUT);
  pinMode(B6,INPUT);
  pinMode(M1,OUTPUT);
  pinMode(M2,OUTPUT);
  pinMode(M3,OUTPUT);
  pinMode(ROBOTER1,OUTPUT);
  pinMode(ROBOTER2,OUTPUT);
}
void loop() {
  b0 = analogRead(B0)<150?HIGH:LOW;
  b1 = analogRead(B1)<150?HIGH:LOW;
  b2 = analogRead(B2)<150?HIGH:LOW;
  b3 = analogRead(B3)<150?HIGH:LOW;
  b4 = analogRead(B4)<150?HIGH:LOW;
  b5 = analogRead(B5)>300?HIGH:LOW;
  b6 = analogRead(B6)<150?HIGH:LOW;
  if (b5&&!b5_previous){
    metal=HIGH;
  }
  if (b0&&!b0_previous){
    b0_timer=millis();
  }
  if ((b0_timer+5000 < millis())&&b0){
    digitalWrite(M1,HIGH);
  }
  if (b1){
    digitalWrite(M1,LOW);
  }
  if (b2&&!b2_previous){
    b2_timer=millis();
  }
  if ((b2_timer+5000 < millis())&&b2){
    digitalWrite(M2,HIGH);
  }
  if (b3){
    digitalWrite(M2,LOW);
  }
  if (b6&&!b6_previous){
    b6_timer=millis();
  }
  if ((b6_timer+5000 < millis())&&b6){
    digitalWrite(M3,HIGH);
  }
  if (b4){
    digitalWrite(M3,LOW);
    if (metal){
      digitalWrite(ROBOTER1,HIGH);
    } else{
      digitalWrite(ROBOTER2,HIGH);
    }
    b4_timer=millis();roboter=HIGH;
  }
  if ((b4_timer+5000<millis())&&roboter){
    digitalWrite(ROBOTER1,LOW);digitalWrite(ROBOTER2,LOW);metal=LOW;roboter=LOW;
  }
  b0_previous=b0;
  b2_previous=b2;
  b5_previous=b5;
  b6_previous=b6;
}

Fazit

Dieses Projekt bringt das Controllino-Modul noch lange nicht an seine Grenzen – es lässt weitaus komplexere Aufgaben zu. Das Beispielprogramm beleuchtet aber gut einige interessante Aspekte der hardwarenahen Programmierung. Wieder zeigt sich, wie leicht es ist, mit Fischertechnik gut funktionierende Industriemodelle aufzubauen. Sollten Sie sich an das Projekt heranwagen, würden wir uns über einen Leserbrief mit einem kurzen Feedback an mailto:[email protected] freuen. 

Der Autor

Martin Mohr entwickelte schon früh eine Vorliebe für alles, was blinkt. Nach einer Ausbildung zum Elektroniker und einem Informatikstudium programmierte er überwiegend Java-Applikationen. Mit dem RasPi erwachte die alte Liebe zur Elektronik wieder.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 5 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
€0,99 – Kaufen
RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS
Deutschland