Coil mit Metallband und Andrücksrolle


Google-Suche auf MEINE-SCHALTUNG.de :





Online Rechner

Chronik

Dauerkalender


Geschwindigkeitstafel
mit einer Lichtschranke und zwei Reflektoren


Der folgende Versuch basiert auf dem Beispiel einer Geschwindigkeitstafel mit zwei Lichtschranken. Das Beispiel ist unter folgendem Link zu erreichen:

Geschwindigkeitstafel mit zwei Lichtschranken

Bei einer Lösung mit zwei Lichtschranken weiß der Mikrocontroller, welche Lichtschranke gerade angefahren wurde. Das ist möglich, da das System mit zwei Eingängen jeweils für eine Lichtschranke arbeitet. So ist die Berechnung der Geschwindigkeit deutlich einfacher. Bei Verwendung von nur einer Lichtschranke hat der Mikrocontroller ein Problem, da er nicht weiß, ob das Fahrzeug gerade in den Messbereich reinfährt oder ihn gerade verlässt. Für die beiden sehr wichtigen Erkennungsmomente (Messpunkte) steht lediglich ein Eingang zur Verfügung. Das Prinzip:

Versuchsanordnung


Der Infrarotstrahl wird von der Lichtschranke zum ersten Reflektor (im Beispiel ein Spiegel) gesendet. Hier wird sein Lauf gebrochen und er erreicht den zweiten Reflektor. Von dem zweiten Reflektor wird er komplett reflektiert. Über den ersten Reflektor erreicht er dann auf dem Rückweg den Empfänger der Lichtschranke. Bei solchem Aufbau entstehen zwei Messpunkte, die sich in einem bestimmten Abstand zueinander befinden. Die Lichtschranke sendet dann ein Signal zu dem Mikrocontroller, wenn der Lichtstrahl am ersten oder zweiten Messpunkt unterbrochen wird.
Der Abstand zwischen beiden Messpunkten muss vor der Inbetriebnahme der Schaltung ermittelt werden und als Konstante im Programm eingegeben werden. Die Aufgabe der Schaltung ist es dann, die Zeit, die ein Fahrzeug benötigt, um die Strecke zwischen den beiden Messpunkten zu passieren, zu ermitteln. Die anschließend berechnete Geschwindigkeit des Fahrzeugs wird auf der Geschwindigkeitstafel angezeigt.

Schaltplan

Schaltplan


Testschaltung

Testschaltung

Damit unsere Geschwindigkeitstafel richtig funktioniert und die Geschwindigkeitsanzeige der tatsächlichen Geschwindigkeit eines Fahrzeugs entspricht, führen wir in das Programm eine weitere Variable „Messintervall_in_micros“ ein. In dem Beispiel hat die Variable den Wert 1000000. Damit wird die minimale Geschwindigkeit eines Fahrzeugs festgelegt. Sie beträgt in dem Fall ca. 17 km/h. Das bedeutet, dass Geschwindigkeiten, die darunter liegen, nicht berücksichtigt werden.
Damit schließen wir Fehler, die entstehen könnten, wenn bei neuer Messung zuerst der zweite Messpunkt angefahren wäre, aus. Ohne diese Einschränkung könnte folgendes passieren: Zuerst wird der zweite Messpunkt angefahren. Das Programm registriert diese Tatsache, als ob der erste Messpunkt angefahren wäre. Erst nach einiger Zeit wird von einem anderen Fahrzeug der erste Messpunkt angefahren. Das Programm würde daraufhin die Geschwindigkeit berechnen, die möglicherweise sehr klein ausfallen würde. Obwohl das zweite Fahrzeug möglicherweise in Wirklichkeit mit z.B. 50 km/h durch die Tempo-30-Zone rast.

Programm (Sketch)

// ****************************************************************************************************
// Geschwindigkeitstafel mit einer Lichtschranke und zwei Reflektoren
// Eine Schaltung mit Arduino Mega
// Arduino IDE 2.2.1
// ****************************************************************************************************

#include "RGBmatrixPanel.h"

#define CLK 11                                      // Matrix Anschlüsse
#define OE   9
#define LAT 10
#define A   A0
#define B   A1
#define C   A2
#define D   A3
#define E   A4

RGBmatrixPanel matrix(A, B, C, D, E, CLK, LAT, OE, false, 64);
 
  int Interrupt_Start = 2;                          // Eingang Interrupt (Zeitmessung Anfang+Ende)
  bool Erste_Messung_erlaubt;                       // Neue Messung erst, wenn Anzeige zu Ende
  bool Zweite_Messung_erlaubt;                      // Reihenfolge der Zeitmessung beachten
  unsigned long Zeit_Messung_Anfang;                // Zeit Anfang festhalten
  unsigned long Zeit_Messung_Ende;                  // Zeit Ende festhalten
  unsigned long Anzeige_neutral_verzoegerung;       // Keine Messungen = Smiley neutral
  float Geschwindigkeit_km_h;                       // Ergebnis Geschwindigkeit in km/h
  bool Anzeige_Smiley_neutral;                      // true - Anzeige Smiley neutral aktiv
  int Verzoegerung;                                 // Anzeige Verzögerung

  float Lichtschranken_Abstand_in_mm = 95.0;        // tatsächlicher Lichtschranken-Abstand
  unsigned long Messintervall_in_micros = 1000000;  // Zeitspanne, in der Messung akzeptiert wird

// ****************************************************************************************************
void setup()  {

    matrix.begin();
    delay(500);
    pinMode(Interrupt_Start, INPUT);
    attachInterrupt(digitalPinToInterrupt(Interrupt_Start), Lichtschranke_angefahren, RISING);    
    Erste_Messung_erlaubt = true;
    Smiley_neutral ();
}

// ****************************************************************************************************
void loop()  {  
    
    if (abs(Geschwindigkeit_km_h) <= 30 && Geschwindigkeit_km_h > 0) {            // Tempo OK
        Geschwindigkeitsanzeige ();
        Smiley_happy ();
        Anzeige_Smiley_neutral = false;
        Geschwindigkeit_km_h = 0;
        Erste_Messung_erlaubt = true;
        Anzeige_neutral_verzoegerung = millis();
    } 

    if (Geschwindigkeit_km_h > 30) {                                              // Tempo zu hoch
        Geschwindigkeitsanzeige ();
        Smiley_traurig ();
        Anzeige_Smiley_neutral = false;
        Geschwindigkeit_km_h = 0;
        Erste_Messung_erlaubt = true;
        Anzeige_neutral_verzoegerung = millis();
    } 

    Verzoegerung = millis () - Anzeige_neutral_verzoegerung;              
    if (Verzoegerung > 8000) {
        if (Geschwindigkeit_km_h == 0) {                                          // keine Bewegung
            Erste_Messung_erlaubt = true;
            if (not Anzeige_Smiley_neutral) {
                Smiley_neutral ();                
                Anzeige_Smiley_neutral = true;
            }
        }
    }
}
// ****************************************************************************************************

// Interrupt - Programm  ------------------------------------------------------------------------------
void Lichtschranke_angefahren () {
    
    if (Zweite_Messung_erlaubt) {                                    // 2. Messpunkt
        Zeit_Messung_Ende = micros();
        float Zeit = Zeit_Messung_Ende - Zeit_Messung_Anfang;        // Ermittelte Zeit
        Erste_Messung_erlaubt = true;
        if (Zeit < Messintervall_in_micros) {                        // Geschwindigkeitsberechnung
            Geschwindigkeit_km_h = (Lichtschranken_Abstand_in_mm * 1000) / Zeit; 
            Geschwindigkeit_km_h = Geschwindigkeit_km_h * 3.6; 
            Geschwindigkeit_km_h = Geschwindigkeit_km_h * 50;        // *50 Wert in Bereich um 30 km/h
            Geschwindigkeit_km_h = abs(Geschwindigkeit_km_h);        // Anzeige ohne Komma
            Erste_Messung_erlaubt = false;                           // Neue Messungen blockieren
            Zweite_Messung_erlaubt = false;                          // bis Anzeige angeschlossen
        }
    }
    
    if (Erste_Messung_erlaubt) {                                     // 1. Messpunkt
        Zeit_Messung_Anfang = micros();                              // Zeit festhalten in Microsekunden
        Zweite_Messung_erlaubt = true;                               // Zweite Zeitmessung kann folgen
    }
}

// Anzeige grün smiley happy --------------------------------------------------------------------------
void Smiley_happy () {
  
    screen_clear();                            // Matrix löschen
    Kreis (32,32,25,0,7,0);                    // Kopf
    Kreis (21,24,6,0,7,0);                     // Auge links
    Kreis (43,24,6,0,7,0);                     // Auge rechts
    Halbkreis_unten (32,38,10,0,7,0);          // Mund
    delay (1000);
}

// Anzeige rot smiley traurig -------------------------------------------------------------------------
void Smiley_traurig () {
  
    screen_clear();
    Kreis (32,32,25,7,0,0);
    Kreis (21,24,6,7,0,0);
    Kreis (43,24,6,7,0,0);
    Halbkreis_oben (32,48,10,7,0,0);
    delay (1000);
}

// Anzeige gelb smiley neutral ------------------------------------------------------------------------
void Smiley_neutral () {
  
    screen_clear();
    Kreis (32,32,25,7,7,0);
    Kreis (21,24,6,7,7,0);
    Kreis (43,24,6,7,7,0);
    matrix.drawLine(25, 44, 38, 44, matrix.Color333(7, 7, 0));
}

// Aktuelle Geschwindigkeit anzeigen ------------------------------------------------------------------
void Geschwindigkeitsanzeige () {

    screen_clear();                                                       // Matrix löschen    
    matrix.setTextSize(1);                                                // Textgröße
    matrix.setCursor(3, 5);                                               // Cursor Position
    matrix.setTextColor(matrix.Color333(7,7,0));                          // Textfarbe
    matrix.println("Sie fahren");                                         // Textausgabe

    matrix.setTextSize(2);
    matrix.setCursor(19, 25);
    matrix.setTextColor(matrix.Color333(0,7,0));
    if (abs(Geschwindigkeit_km_h) > 30) {
        matrix.setTextColor(matrix.Color333(7,0,0));
    }
    String Anzeige = String (Geschwindigkeit_km_h,0);
    matrix.println(Anzeige);   

    matrix.setTextSize(1);
    matrix.setCursor(33, 50);
    matrix.setTextColor(matrix.Color333(7,7,0));
    matrix.println("km/h");
    delay(1000);
}

// Matrix Löschen -------------------------------------------------------------------------------------
void screen_clear() {
  
    matrix.fillRect(0, 0, matrix.width(), matrix.height(), matrix.Color333(0, 0, 0));
} 

// Kreis zeichnen -------------------------------------------------------------------------------------
void Kreis (int X, int Y, int r, int R, int G, int B) {
  
    for (int i=X-r; i <= X+r; i++) {
        for (int j=Y-r; j <= Y+r; j++) {
            int a = abs (X-i);
            int b = abs (Y-j);
            float R_Ist = sqrt (sq(a) + sq(b));
            float R_Soll = r;
            if (R_Ist < (R_Soll + 0.5) and R_Ist > (R_Soll - 0.5)) {
                matrix.drawPixel(i, j, matrix.Color333(R, G, B));
            }
        }
    }
}

// Halb-Kreis unten zeichnen --------------------------------------------------------------------------
void Halbkreis_unten (int X, int Y, int r, int R, int G, int B) {
  
    for (int i=X-r; i <= X+r; i++) {
        for (int j=Y+2; j <= Y+r; j++) {
            int a = abs (X-i);
            int b = abs (Y-j);
            float R_Ist = sqrt (sq(a) + sq(b));
            float R_Soll = r;
            if (R_Ist < (R_Soll + 0.5) and R_Ist > (R_Soll - 0.5)) {
                matrix.drawPixel(i, j, matrix.Color333(R, G, B));
            }
        }
    }
}

// Halb-Kreis oben zeichnen ---------------------------------------------------------------------------
void Halbkreis_oben (int X, int Y, int r, int R, int G, int B) {
  
    for (int i=X-r; i <= X+r; i++) {
        for (int j=Y-r; j <= Y-2; j++) {
            int a = abs (X-i);
            int b = abs (Y-j);
            float R_Ist = sqrt (sq(a) + sq(b));
            float R_Soll = r;
            if (R_Ist < (R_Soll + 0.5) and R_Ist > (R_Soll - 0.5)) {
                matrix.drawPixel(i, j, matrix.Color333(R, G, B));
            }
        }
    }
}

// ****************************************************************************************************  

Kurzvideo zur Schaltung

Kurzvideo


Weitere Themen:


Google-Suche auf MEINE-SCHALTUNG.de :


Home Impressum Datenschutz