Luftzylinder von Festo


Google-Suche auf MEINE-SCHALTUNG.de :





Online Rechner

Chronik

Dauerkalender


Automatik Barkeeper
(Absolute Positionierung mit Schrittmotor)

In dem Versuch, den wir vielversprechend „Automatik Barkeeper“ nennen, befassen wir uns mit einem Schrittmotor und absoluter Positionierung. Anders als bei einer relativen Positionierung muss bei absoluter Positionierung das den Motor steuernde System stets wissen, welche Position der Motor zuletzt angenommen hat. Nur so kann das System bei der nächsten Aufgabe den notwendigen Weg berechnen und den Motor erneut richtig positionieren. Bei der absoluten Positionierung kommt noch ein weiterer Begriff hinzu: Referenzieren. Bei Problemen, Störungen, Komponentenausfall u.s.w. kann es notwendig sein, dem System von extern die aktuelle Position des Motors mitzuteilen. Das kann dadurch realisiert werden, dass der Motor auf eine feste Ausgangsposition gefahren wird. Sie kann z.B. mit einem Endschalter markiert werden. Diese Position, die als Nullpunkt oder Referenzpunkt bezeichnet wird, stellt dann den Ausgangswert für alle folgenden Berechnungen dar.
Unserer „Automatik Barkeeper“ besteht aus einem Teller, auf dem mehrere Flaschen angebracht sind. In jeder Flasche befindet sich eine flüssige Komponente, die bei Zusammenstellung von Drinks oder Cocktails verwendet werden kann. In dem Programm, das die Bewegungen des Motors steuert, sind drei Drinks-Kompositionen fest einprogrammiert. Diese Rezepturen können frei gestaltet und beliebig erweitert werden. Beim Aufruf einer Rezeptur muss der Motor den Teller so bewegen, dass jeweils die gewünschte Komponente-Flasche über den Abnahmebecher, der auf einer festen Position steht, positioniert wird. Die Flüssigkeit gelangt in dem Becher, indem ein Magnetventil eingeschaltet wird.
Auch hier vor dem ersten Start muss durch das Anfahren einer festen Ausgangsposition der Referenzpunkt dem System mitgeteilt werden. In dem Beispiel wird der Referenzpunkt dann erreicht, wenn die Station Nr. 2 über den Entnahmebecher positioniert wird.

Schrittmotor 17HS19-2004S1

Mit einem Schrittmotor kann man Positionierungsaufgaben sehr gut realisieren. Ansonsten sind weitere Komponenten wie z.B. Inkrementalgeber, um die Positionierung zu überwachen, notwendig.

Schrittmotor 17HS19-2004S1

Schrittmotor 17HS19-2004S1

Bei dem 17HS19-2004S1 handelt es sich um einen NEMA 17 Schrittmotor mit einer 1m langen Zuleitung. Er ist für Anwendungen im Bereich der 3D-Drucker oder CNC- und Robotertechnik konzipiert. Technische Daten:

Motorentyp: Bipolar
Widerstand / Phase: 1.4 Ohm (+/- 10%)
Stromaufnahme / Phase): 2.0A
Schrittwinkel: 1.8 °
Schrittgenauigkeit: +/- 5%
Haltemoment: 0,59 Nm
Induktivität: 3.0 mH ± 20% (1KHz)
Anzahl der Leiter: 4
Leitungslänge: 1 m
Gewicht: 390 g

Abmessungen

Abmessungen

Anschluss:
A1 – Schwarz
A2 – Grün
B1 – Rot
B2 - Blau

Schritt-Steuerung:
1 – A1+ / B1+ / A2- / B2-
2 – A1- / B1+ / A2+ / B2-
3 – A1- / B1- / A2+ / B2+
4 – A1+ / B1- / A2- / B2+

In unserem Versuch wird der Motor fest auf einem alten Küchenbrett montiert und mit einer Zahnscheibe ausgestattet. Auf diese wird zu späterem Zeitpunkt ein Teller, der aus einer alten Schaltplatte besteht, montiert.


Motortreiber DM420

Motortreiber

Der Motor wird mithilfe des Motortreibers DM420 gesteuert. Für die Ansteuerung des Treibers werden lediglich drei Signalleitungen benötigt.

Motortreiber DM420

ULN2003A

ULN2003A

Um die Ausgänge des Arduino nicht zu zerstören, verwenden wir für die Ansteuerung der Ventile den Verstärker IC ULN2003A. Er bietet uns sieben Ausgänge, die mit einem Strom bis 200 mA belastet werden können.

Ventil CJV23

Ventil CJV23

Bei dem Ventil CJV23 C24B1 handelt es sich um einen 24 VDC Ventil, das für Gas-, Wasser- und Luftversuche geeignet ist. Im spannungslosen Zustand ist das Ventil geschlossen. Die Anschlüsse eignen sich für 6mm breite Flachsteckhülsen.

Ventil CJV23 - Abmessungen

Technische Daten:
- Spannung: 24 VDC
- Spule Widerstand: 370 Ohm
- Stromaufnahme: 65 mA
- Durchfluss: 11 L/Min
- Betriebstemperatur: 0 - 50°C
- Gewicht: 52 g


Arduino

Arduino

Der Mikrocontroller spielt in der Schaltung die entscheidende Rolle. Er empfängt die Tastatureingaben, bestimmt anhand dessen, welche Stationen am Zusammenstellung des Drinks teilnehmen werden, bewegt den Motor und schaltet die Ventile.

Mehr über Arduino

Tastatur

Tastatur

Mithilfe der Tastatur wird bestimmt, welcher Drink als Nächster zusammengestellt wird. Die Tastatur könnte man auch dazu verwenden, die Rezepten für Drinks einzugeben. In solchem Fall müsste man für eine Datenspeicherung sorgen.

4x4 Tastatur

Spannungsregler

Spannungsregler

Da die Hauptversorgungsspannung von 24 VDC für Arduino zu hoch ist, kommt ein Spannungsregler zum Einsatz. Er regelt die Spannung auf 5 VDC runter.

Spannungsregler

Schaltplan

Schaltplan

Schaltplan

Testschaltung

Testschaltung

Testschaltung

Komplette Testeinrichtung

Komplette Testeinrichtung

Das Programm (Sketch)

// ***********************************************************************************
// Automatik Barkeeper
// Schrittmotor, absolute Positionierung
// Schrittmotor 16HS2404L14.5P1-X / Motor-Treiber DM420
// Arduino Mega2560
// Arduino IDE Version 2.0.3
// ----------------------------------------------------------
#include <Keypad.h>                                         // Bibliothek Tastatur einbinden

const byte ROWS = 4;                                        // 4 Reihen
const byte COLS = 4;                                        // 4 Spalten

char hexaKeys[ROWS][COLS] = {                               // Tastatur - Zeichen
    {'1','2','3','A'},
    {'4','5','6','B'},
    {'7','8','9','C'},
    {'*','0','#','D'} };
    
byte rowPins[ROWS] = {53, 51, 49, 47};                      // Arduino Pins - Tastatur-Reihen
byte colPins[COLS] = {45, 43, 41, 39};                      // Arduino Pins - Tastatur-Spalten

Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

int PUL = 5;                                                // Treiber DM420: Pulse Anschluss
int DIR = 4;                                                // Treiber DM420: Drehrichtung
int ENBL = 6;                                               // Treiber DM420: Freigabe
bool Drehrichtung;                                          // Motor Drehrichtung
                      
int Ventil [5] = {40, 42, 44, 46, 48};                      // Ventil Pins

int Taster_Referenzpunkt = 11;                              // Referenzieren abschließen      
int LED_Ausgabe_laeuft = 3;                                 // Meldeleuchte "IN ARBEIT"
int LED_Bereit = 2;                                         // Meldeleuchte "BEREIT"
int Rezept [5][2] = { {0,0}, {0,0}, {0,0}, {0,0}, {0,0} };  // Rezept [Station + Zeit in %]
bool Ausgabe_Start;                                         // True=Ausgabe wird gestartet

int Position_IST, Position_SOLL;                            // Positionswerte
String Eingabe_String;                                      // Tastatur Eingaben (String)
int Eingabezahl;                                            // Eingabe_String als INT
String Tastatur_Taste;                                      // Tastatur aktuelle Taste
int Grundzeit_Ventil_Auf = 20000;                           // Maximale Zeit bis Becher voll

// ................................................. SETUP
void setup() {
  
    pinMode (PUL, OUTPUT);                                  // PUL-Pin als Ausgang
    pinMode (DIR, OUTPUT);                                  // DIR-Pin als Ausgang
    pinMode (ENBL, OUTPUT);                                 // ENBL-Pin als Ausgang
    digitalWrite (ENBL, HIGH);                              // Freigabe sperren

    for (int i=0; i<5; i++)    {                            // Ventil-Pins als Ausgänge
        pinMode (Ventil [i], OUTPUT);  
    }

    pinMode (Taster_Referenzpunkt, INPUT_PULLUP);           // Eingang Referenzpunkt bestätigen
    pinMode (LED_Ausgabe_laeuft, OUTPUT);                   // Info-LED Ausgabe läuft
    pinMode (LED_Bereit, OUTPUT);                           // Info-LED Bereit
}

// ................................................. Unterprogramm Motor drehen
void Motor_drehen (int Schritte, int Pulslaenge, int Richtung, int Geschwindigkeit) {    

    if (Richtung) { digitalWrite(DIR,HIGH); }               // Motordrehrichtung bestimmen
        else 
        { digitalWrite(DIR,LOW); }
    for (int i = 0; i < Schritte; i++) {                    // Pulse erzeugen
        digitalWrite(PUL,HIGH);
        delayMicroseconds(Pulslaenge);
        digitalWrite(PUL,LOW);
        delayMicroseconds(Geschwindigkeit); }
}

// ................................................... Hauptprogramm
void loop() {

    digitalWrite (ENBL, LOW);                               // Motor-Treiber deaktivieren
    if (digitalRead(Taster_Referenzpunkt) == LOW) {         // Referenzposition markieren
        Position_IST = 2;
    }
    digitalWrite(LED_Ausgabe_laeuft, LOW);                  // Meldeleuchte Ausgabe läuft AUS
    digitalWrite (LED_Bereit, HIGH);                        // Meldeleuchte Bereit EIN
    
    Tastatur_Taste = customKeypad.getKey();                 // Tastaturabfrage
    delay(50);                                              // Kurze Pause
  
    if (Tastatur_Taste == "#") {                            // mit "#" wird Eingabe übernommen
        digitalWrite(LED_Ausgabe_laeuft, HIGH);             // Meldeleuchte Ausgabe läuft EIN
        digitalWrite (LED_Bereit, LOW);                     // Meldeleuchte Bereit AUS
        Eingabezahl = Eingabe_String.toInt();               // Eingabe in int-Format wandeln
        switch (Eingabezahl) {                              // Rezepturauswahl
            case 2: {                                       // Beispiel-Rezepturen 2,8 und 12
                Rezept [0][0] = 1;  Rezept [0][1] = 10;     // Station Nr + Füllzeit in %
                Rezept [1][0] = 2;  Rezept [1][1] = 30;  
                Rezept [2][0] = 4;  Rezept [2][1] = 30;
                Rezept [3][0] = 3;  Rezept [3][1] = 10;
                Rezept [4][0] = 5;  Rezept [4][1] = 20;
                break;
            }
            case 8: {
                Rezept [0][0] = 4;  Rezept [0][1] = 10;      // Station 4 = Coca-Cola
                Rezept [1][0] = 5;  Rezept [1][1] = 50;      // Station 5 = Bacardi
                Rezept [2][0] = 1;  Rezept [2][1] = 30;      // Station 1 = Orangensaft
                Rezept [3][0] = 3;  Rezept [3][1] = 10;      // Station 3 = Whisky
                Rezept [4][0] = 0;  Rezept [4][1] = 0;       // Station 2 = Campari
                break;
            }    
            case 12: {
                Rezept [0][0] = 1;  Rezept [0][1] = 10;      
                Rezept [1][0] = 5;  Rezept [1][1] = 30;
                Rezept [2][0] = 2;  Rezept [2][1] = 30;
                Rezept [3][0] = 3;  Rezept [3][1] = 10;
                Rezept [4][0] = 4;  Rezept [4][1] = 20;            
                break;
            }                    
        }
        Eingabe_String = Tastatur_Taste = "";                // Beide Variablen löschen       
        Ausgabe_Start = true;                                // Ausgabe kann gestartet werden
     }

    if (Tastatur_Taste) {                                    // Tastatureingaben zusammenfassen
        Eingabe_String = Eingabe_String + Tastatur_Taste;       
    }  
                                                                      // Automatik Start
    if (Ausgabe_Start) {
      
          digitalWrite (ENBL, HIGH);                                  // Motor-Treiber freigeben
          for (int i=0; i<5; i++) {                                   // Alle Rezeptur-Sätze abarbeiten
              if (Rezept [i][0] > 0) {                                // nur wenn Aufgabe vorhanden
                  Position_SOLL = Rezept [i][0];                      // Neue Position (Stattion) bestimmen
                  int Strecke = Position_SOLL - Position_IST;         // Aktuelle Position berücksichtigen
                  bool Richtung = true;                               // Drehrichtung bestimmen
                  if (Position_IST > Position_SOLL) {
                     Richtung = false;
                     Strecke = Position_IST - Position_SOLL;
                  }
                  Position_IST = Position_SOLL;                       // Neue Zielposution
                  int Schritte = Strecke * 5120;                      // Pulse-Anzahl berechnen
                  Motor_drehen (Schritte, 650, Richtung, 350);        // Motor drehen
                  digitalWrite (Ventil [Position_IST - 1], HIGH);     // Ausgabe-Ventil EIN
                  int Zeit_Ventil_Auf = Grundzeit_Ventil_Auf / 100 * Rezept [i][1];   // Ventil-An-Zeit 
                  delay(Zeit_Ventil_Auf);                             // berechnete Wartezeit abwarten
                  digitalWrite (Ventil [Position_IST - 1], LOW);      // Ventil wieder Aus
              }              
         }
         Ausgabe_Start = false;                              // Ausgabe abgeschlossen
         delay (1000);                                       // Wartezeit                         
    }

}
// ***********************************************************************************        

Kurzvideo

Kurzvideo


Weitere Themen:


Google-Suche auf MEINE-SCHALTUNG.de :


Home Impressum Datenschutz