Jedem Autofahrer ist eine Geschwindigkeitstafel bestens bekannt. Sie wird vorzugsweise an den Zufahrten zu Siedlungen oder kleinen Orten
positioniert und informiert die Autofahrer an die dort herrschende oder erwünschte Fahrgeschwindigkeit. Sie ist auch oft in der Nähe von Schulen oder Kindergärten
anzutreffen.
Eine Geschwindigkeitstafel zeigt die aktuelle Geschwindigkeit des Fahrzeugs. Um die Attraktivität der Anzeige zu erhöhen, wird die Geschwindigkeitsanzeige oft mit einem
Smiley kombiniert.
Genau eine solche Geschwindigkeitstafel werden wir in diesem Versuch konstruieren. Das Problem der Geschwindigkeitsmessung wird mithilfe zwei Lichtschranken gelöst.
Als Geschwindigkeitstafel kommt die 64x64 LED-Matrix zum Einsatz. Hier kann man problemlos so die Geschwindigkeitswerte als auch Smileys darstellen. Mit einem
Getriebe-Gleichstrommotor wird auf einem Zahnriemen Imitation eines Fahrzeugs bewegt. Sobald das Fahrzeug die Lichtschranken passiert, wird seine Geschwindigkeit
errechnet und angezeigt. Gleich danach gibt es ein Smiley. Die notwendigen Berechnungen und Steuerung der Matrix erledigt für uns
Arduino Mega.
Bei der Lichtschranke handelt sich um ein „Made in China“ Produkt. Sie kann zu günstigen Konditionen erworben werden und ist für einfache Experimente
bestens geeignet. Bei der Infrarotlichtschranke sind der Sender und Empfänger in einem Gehäuse untergebracht. Um den Infrarotlichtstrahl zu reflektieren, wird ein
Spiegelreflektor verwendet. Die Lichtschranke verfügt auf dem Gehäuse über zwei Drehschalter. Mit dem oberen Schalter kann die Empfindlichkeit der Lichtschranke
eingestellt werden. Der untere Schalter bestimmt die Art des Ausgangs. Der Ausgang kann nach Bedarf als Schließer oder Öffner benutzt werden. In beiden Fällen handelt
es sich um einen NPN – Ausgang. Die Lichtschranke reagiert, sobald der Lichtstrahl unterbrochen wird.
Technische Daten:
Versorgungsspannung: 12 ~ 24 VDC.
Erfassungswinkel: 2 ~ 10°
Reichweite: bis 2 m
Stromaufnahme: bis 30mA
Ausgang Belastbarkeit: max. 100 mA
Ausgang: NPN
Anschluss: 3-adrige Leitung (Braun +/ Blau -/ Schwarz Out)
Arbeitstemperatur: -25℃~+75℃
Abmessungen:
Schaltbild
RGB Matrix (64x64)
Die errechnete Geschwindigkeit und die dazugehörigen Smileys werden auf einer LED-Matrix (64x64) mit 4096 RGB-Leuchtdioden angezeigt. Die grüne Anzeige ist
dabei für Autofahrer, die 30 km/h nicht überschreiten, vorgesehen. Beim Überschreiten der zulässigen Geschwindigkeit von 30 km/h erfolgt die
Anzeige in rot.
Ein Mikrocontroller, der die Steuerung unserer kleinen Geschwindigkeit-Messanlage übernehmen soll, muss über mindestens 16 I/Os verfügen. Zur Steuerung der
Matrix werden 14 Steueranschlüsse benötigt. Zwei weitere werden von den Lichtschranken in Anspruch genommen. Mit Arduino Mega steht man auf der
sicheren Seite. Mit dem Microcontroller stehen noch genügen weitere Ein/Ausgänge für eventuelle Erweiterungen
zur Verfügung.
Die Hauptkomponente der Schaltung, die für die Imitation eines fahrenden Fahrzeuges dient, stellt der Gleichstrommotor JGB37 dar. Mit seiner Hilfe wird eine
einfache, aus zwei Zahnrädern und einem Zahnriemen bestehende Einrichtung in Bewegung gesetzt. Ein aus Papier herausgeschnittenes Bild eines Pkws ist auf dem
Zahnriemen befestigt. Nach dem Start passiert das Fahrzeug die Lichtschranken und generiert so die Signale, die zur Berechnung der Geschwindigkeit
verwendet werden.
Die notwendige Motorspannung liefert in der Schaltung ein PWM-Motortreiber. Er ist mit einem Potentiometer für Drehzahlregelung ausgestattet. Dank dessen
können, um die Schaltung zu testen, unterschiedliche Geschwindigkeiten des Fahrzeugs eingestellt werden. Intern wird die Ausgangsspannung mithilfe der PWM-Technik
eingestellt. Mit dem Treiber können Spannungen bis zu 48V verarbeitet werden. In der Schaltung arbeitet der
Geschwindigkeitsregler mit 12 VDC.
Spannungsregler
Die Schaltung arbeitet mit mehreren Spannungen. Das hängt jeweils damit zusammen, welche Komponenten gerade zur Verfügung stehen. Mit dem LM2596-Spannungsregler
wird die 12 VDC-Spannung, die für den
Motor und Lichtschranken notwendig ist, bereitgestellt.
// ****************************************************************************************************
// Geschwindigkeitstafel mit Lichtschranken und RGB 64x64 Matrix
// Eine Schaltung mit Arduino Mega
// Arduino IDE 2.2.1
// ****************************************************************************************************
#include "RGBmatrixPanel.h"
#define CLK 11
#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 r, g, b;
int Interrupt_Start = 2; // Eingang Interrupt 1 (Zeitmessung Anfang)
int Interrupt_Ende = 3; // Eingang Interrupt 2 (Zeitmessung 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
float Lichtschranken_Abstand_in_mm = 130.0; // tatsächlicher Lichtschranken-Abstand
int Smiley_Nr; // 1- neutral, 2 - happy, 3 - traurig
// ****************************************************************************************************
void setup() {
matrix.begin();
delay(500);
pinMode(Interrupt_Start, INPUT);
attachInterrupt(digitalPinToInterrupt(Interrupt_Start), Erste_Lichtschranke_angefahren, RISING);
pinMode(Interrupt_Ende, INPUT);
attachInterrupt(digitalPinToInterrupt(Interrupt_Ende), Zweite_Lichtschranke_angefahren, RISING);
Erste_Messung_erlaubt = true;
Smiley_neutral ();
}
// ****************************************************************************************************
void loop() {
if (Geschwindigkeit_km_h < 30 && Geschwindigkeit_km_h > 0) { // Tempo OK
Geschwindigkeitsanzeige ();
Smiley_happy ();
Smiley_Nr = 2;
Geschwindigkeit_km_h = 0;
Erste_Messung_erlaubt = true;
}
if (Geschwindigkeit_km_h > 30) { // Tempo zu hoch
Geschwindigkeitsanzeige ();
Smiley_traurig ();
Smiley_Nr = 3;
Geschwindigkeit_km_h = 0;
Erste_Messung_erlaubt = true;
}
int Verzoegerung = millis () - Anzeige_neutral_verzoegerung;
if (Verzoegerung > 8000) {
if (Geschwindigkeit_km_h == 0) { // keine Bewegung
if (Smiley_Nr != 1) {
Smiley_neutral ();
Erste_Messung_erlaubt = true;
Smiley_Nr = 1;
}
}
}
}
// ****************************************************************************************************
// Interrupt (2) Messung erste Lichtschranke wurde passiert -------------------------------------------
void Erste_Lichtschranke_angefahren () {
if (Erste_Messung_erlaubt) {
Zeit_Messung_Anfang = micros(); // Zeit festhalten in Microsekunden
Zweite_Messung_erlaubt = true; // Zweite Zeitmessung kann folgen
}
}
// Interrupt (3) Messung zweite Lichtschranke ---------------------------------------------------------
void Zweite_Lichtschranke_angefahren () {
Anzeige_neutral_verzoegerung = millis();
if (Zweite_Messung_erlaubt) {
Erste_Messung_erlaubt = false; // Neue Messungen blockieren
Zweite_Messung_erlaubt = false;
Zeit_Messung_Ende = micros();
float Zeit = Zeit_Messung_Ende - Zeit_Messung_Anfang;
Geschwindigkeit_km_h = (Lichtschranken_Abstand_in_mm * 1000) / Zeit;
Geschwindigkeit_km_h = Geschwindigkeit_km_h * 3.6;
Geschwindigkeit_km_h = Geschwindigkeit_km_h * 50;
Geschwindigkeit_km_h = abs(Geschwindigkeit_km_h);
}
}
// Anzeige grün smiley happy --------------------------------------------------------------------------
void Smiley_happy () {
screen_clear();
Kreis (32,32,25,0,7,0);
Kreis (21,24,6,0,7,0);
Kreis (43,24,6,0,7,0);
Halbkreis_unten (32,38,10,0,7,0);
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 (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));
}
}
}
}
// ****************************************************************************************************
Die Funktionalität der Schaltung kann schnell erklärt werden. Nachdem alle Komponenten mit Spannung versorgt sind, kanns losgehen. Mit dem Potentiometer
R1 wird der Motor in Bewegung gesetzt, das Auto fährt. Der Einsatz des Potentiometers macht es möglich, die Drehzahl des Motors beliebig einzustellen. Damit kann man
unterschiedliche Geschwindigkeiten des Autos einstellen. Die Lichtschranken und die jeweiligen Reflektoren sind so positioniert, dass das Auto im Vorbeifahren die
infrarotlichtstrahlen unterbricht. Bei jeder Unterbrechung wird von der jeweiligen Lichtschranke ein Signal generiert, das zu dem Mikrocontroller geführt wird. Damit
der Mikrocontroller nicht beschädigt wird (er kann nur mit 5V-Signalen arbeiten), werden die Signale (12VDC) mit den Spannungsteilern R2/R3 und R4/R5 entsprechend
angepasst.
Im Programm werden zwei Interrupts aktiviert, die auf diese Signale reagieren. Mit ihrer Hilfe wird die Zeitspanne, die das Auto benötigt, um von einer
Lichtschranke bis zu der anderen zu fahren, ermittelt. Bei bekanntem Abstand der Lichtschranken kann dann anschließend die aktuelle Geschwindigkeit des Autos
berechnet werden.
Das Ergebnis wird dann auf der Matrix angezeigt. Um die Verwaltung der Matrix-Signale zu vereinfachen, kommt in dem Programm die Bibliothek "RGBmatrixPanel.h"
zum Einsatz. Sie muss vor dem Start des Programms installiert werden.
In der Testschaltung bewegt sich das Auto sehr langsam, Geschwindigkeiten um die 30 km/h sind hier nicht zu erreichen. Deswegen wird die errechnete Geschwindigkeit
mit einem extra Faktor (*50) multipliziert. Dank dessen erscheinen auf der Anzeige höhere Geschwindigkeiten, was den Eindruck der
Echtheit erhöht.