| Weitere Artikel aus dem Elo-Magazin |
Rundenzähler für Slotracer
von Wolfram Herzog
Literatur: Lernpaket Mikrocontroller - Technik mit Bascom
Das Mitzählen der gefahrenen Runden beim Slotrace ist eine mühselige und fehlerträchtige Angelegenheit. Daher wurde auf der Basis des BASCOM Lernpaketes ein Rundenzähler für Slot-Racer-Bahnen umgesetzt. Dieser zählt nicht nur die Runden und ermittelt den Sieger sondern gibt auch ein akustisches Startsignal.
Um die gefahrenen Runden zu ermitteln, wurden Reedkontakte in die Fahrbahn eingesetzt. Diese haben den Vorteil der einfachen Montage. Sie werden einfach mit Heißkleber unter die Fahrbahn geklebt und die Anschlüsse über einen Stecker nach Außen geführt. Der hier verwendete Steckverbinder ist ein vierpoliger Stecker (Stromversorgung eines 3,5" Diskettenlaufwerks) von einem alten PC-Netzteil. Es empfiehlt sich, zum Schluss ein Klebeband zur Isolierung darüber zu kleben.
| Ganzen Artikel lesen... | ![]() |

Die Hardware für den Rundenzähler besteht aus der Experimentierplatine des BASCOM Lernpaketes und einem daran angeschlossenen LCD-Display. So kann die Experimentierplatine auch ohne PC benutzt werden. Als Stromversorgung dient im Rennbetrieb ein Steckernetzteil eines MP3 Players mit USB-Buchse, in die das mitgelieferte USB-Kabel eingesteckt wird. Der Mini-USB Stecker wird wie gewohnt mit der Experimentierplatine verbunden.
Näheres zum Anschluss eines LCD Displays an die Experimentierplatine finden Sie in dem Beitrag „LCD Display für BASCOM Lernpaket". Weiterhin wird an der Experimentierplatine ein Piezo-Piepser angeschlossen. Da es beim Slotrace schon mal ein wenig laut hergehen kann wurde hier ein Murata-Piepser angeschlossen, der aus einem alten Siemens Telefon stammt. Natürlich kann auch das Piezoelement aus dem Lernpakte verwendet werden, es ist nur nicht so laut. Alle Bauteile wurden auf ein Sperrholzbrett geschraubt, um die Handhabung zu vereinfachen. Die Verbindung zum Slotcar-Fahrbahn erfolgt über ein dreipoliges Kabel und eine vierpolige 2,54-mm-Stiftleiste. Die Anschlüsse der Experimentierplatine sind nun wie folgt belegt:
PB0 RS Pin des LCD Display
PB1 DB4 Pin des LCD Display
PB2 DB5 Pin des LCD Display
PB3 DB6 Pin des LCD Display
PB4 DB7 Pin des LCD Display
PB5 ENABLE Pin des LCD Display
PD6 Reedkontakt Spur1
PD7 Reedkontakt Spur 2
ADC0 Anschluß rot Piezo
GND Anschluß schwarz Piezo
GND Anschluß Reedkontakt Spur1
GND Anschluß Reedkontakt Spur2
Da die internen Pull-Up-Widerstände des MEGA88 von PD6 un dPD7 aktiviert sind, ist eigentlich ein Draht vom Port zum Reedkontakt und dann an GND ausreichend. Wir hatten allerdings hin und wieder merkwürdige Störungen und daher einen externen 2,2 k Pull-up-Widerstand von PD6 und PD7 nach Vcc hinzugefügt. Danach waren die Probleme beseitigt.
Das Programm ist in der üblichen Art und Weise aufgebaut. Es werden zuerst die Anschlüsse für das LCD Display definiert, anschließend die verwendeten Ports konfiguriert. Um die Lesbarkeit des Programms zu verbessern werden mit dem Befehl ALIAS den verschiedenen Ports verständliche Namen zugewiesen, so wird z.B. der PortC.0 an den der Piezo-Piepser angeschlossen wird mit dem Name „Buzzer" versehen. Die Software benutzt zwei der drei Timer des MEGA88 - es sind die beiden 8-Bit Timer Timer0 und Timer2. Der 16Bit Timer1 bleibt frei und könnte für künftige Programmerweiterungen - z.B. eine Zeitmessung der Rundenzeiten - genutzt werden.
Es werden drei Interrupts genutzt, die dann entsprechende Interruptroutinen aufrufen. Zum einen der flankengetriggerte PCINT0, der bei einer fallenden Flanke am Port ausgelöst wird. Damit wird das Schließen der Reedschalter durch das darüberfahrende Slotcar erkannt. Zum anderen die beiden Timer-Overflow-Interrupts für die Timer0 und Timer2, mit denen ein Entprellen der Reedkontakte erfolgt. Da manche Slotcar-Autos nicht nur einen sondern auch zwei oder drei Magnete an der Unterseite haben, muss neben dem Entprellen der Reedkontakte auch die Mehrfachauslösung durch die verschiedenen Magnete ausgewertet werden. Daher wird eine Runde erst dann gezählt, wenn das Auto ganz sicher vollständig darüber gefahren ist, d.h. der Reedkontakt für mindestens 0,2 Sekunden wieder geöffnet ist. Dies wird durch die Timer überwacht. Dieser Zeitintervall kann mit der Abfrage der Variablen Fz1 und Fz2 eingestellt werden (Zeile 186 bzw. Zeile 201). Das Programm ist mit BASCOM Version 1.11.9.5 erstellt und umfassend kommentiert.
Download: Quelltext und Hexfile
Die Bedienung der Funktionen erfolgt mit den beiden Tastern auf der Experimentierplatine. Nach dem Start des Programms erscheint ein Auswahlmenü mit zwei Optionen: Rennen und Setup. Mit Setup kann die Anzahl der zu fahrenden Runden eingestellt werden, mit Rennen wird ein Wettrennen gestartet.
Nach dem Drücken des INT1 Tasters wird die Anzahl der zu fahrenden Runden angezeigt, nach nochmaligem Drücken des Tasters ertönt das Startsignal und der Rundenzähler erscheint. Mit jeder gefahrenen Runde wird der Zähler erhöht, außerdem werden die LED1 und LED2 bei jedem Auslösen des Reedkontaktes umgeschaltet. Sobald der erste Fahrer die Zahl der zu fahrenden Runden erreicht hat, ertönt wieder ein Signal und der Sieger wird angezeigt. Durch Drücken der Taste INT1 kann ein neues Rennen gestartet werden. Während eines Rennes kann der Zählvorgang durch Drücken der Taste jederzeit abgebrochen werden.
Wurde im Auswahlmenü der Taster INT0 gedrückt wird in das Eingabemenü der Runden verzweigt. Hier kann durch mehrmaliges Drücken von INT0 die gewünschte Rundenzahl eingestellt werden. Mit der Taste INT1 wird die Eingabe beendet und die Anzahl der Runden im EEPROM des MEGA88 gespeichert. So steht beim nächsten Mal sofort wieder die gewünschte Rundenzahl zur Verfügung.
Viel Spaß beim Slotracing!
Cls ' B'*****************************************
' Rundenzähler für Slotcar-Racing
' Wolfram Herzog 13.1.2010
'
' für Franzis BASCOM Lernpaket mit MEGA88
' erstellt mit BASCOM 1.11.9.5
'
' Taster INT0 und INT1 als Eingabe
' Reedkontakte an PD6 und 7
'
' Timer0 und 2 wird als Entpreller auf fallende Flanke benutzt
'
' Version 1.1.11
'******************************************
$regfile = "m88def.dat"
$crystal = 8000000
$baud = 19200
$hwstack = 32 ' default use 32 for the hardware stack
$swstack = 10 ' default use 10 for the SW stack
$framesize = 40 ' default use 40 for the frame space
Config Lcd = 16 * 2
Config Lcdpin = Pin , Rs = Portb.0 , E = Portb.5 , Db4 = Portb.1 , Db5 = Portb.2 , Db6 = Portb.3 , Db7 = Portb.4
Config Pind.2 = Input ' Taster auf dem Board
Config Pind.3 = Input
Config Pind.6 = Input ' Reedkontakte
Config Pind.7 = Input
Config Portb.7 = Output ' LED zu Kontrollzwecken
Config Portb.6 = Output
Config Timer0 = Timer , Prescale = 1024 '8-64-256-1024
Config Timer2 = Timer , Prescale = 1024 '8-32-64-128-256-1024
Portd.2 = 1 ' Interne Pull-ups aktivieren
Portd.3 = 1
Portd.6 = 1
Portd.7 = 1
Taster0 Alias Pind.2 'Für bessere Lesbarkeit des Programmes
Taster1 Alias Pind.3
Kontakt1 Alias Pind.6
Kontakt2 Alias Pind.7
Buzzer Alias Portc.0 'Piezo Summer
Enable Interrupts 'enable global ints
Enable Pcint0 'we enable pcint0 as this has pcint0-pcint7
On Pcint0 Isr_pcint0 'we jump to this label when one of the pins is changed
Pcmsk0 = &B11001100 'enable pcint6-pcint7 (portb.0-portb.3)
Enable Timer0 ' Timer freigeben
Enable Timer2
On Timer0 Isr_timer0 ' Timer Interrupt freigeben
On Timer2 Isr_timer2 ' für Timer0 und Timer2
Config Debounce = 30 ' Wartezeit in ms für taster
Dim S1 As Byte 'Flag ob steigende Flanke erkannt
Dim S2 As Byte
Dim Z1aehler As Byte 'Gefahrene Runden
Dim Z2aehler As Byte
Dim Fz1 As Byte 'Debounce Zähler
Dim Fz2 As Byte
Dim Runden As Byte ' Anzahl der Runden
Dim Fertig As Byte ' Flag ob Rundenzahl erreicht
Dim Erunden As Eram Byte 'Rundenzahl im EEPROM gespeichert
Sstart:
Cls ' Begrüßungsbildschirm
Cursor Off
Upperline
Lcd "SLOTRACE V1.1.11"
Lowerline
Lcd "1=Rennen 2=Setup"
Tastenwart: ' Verzweigung Setup
Debounce Taster1 , 0 , Pstarten 'int1 Taste gedrückt
Debounce Taster0 , 0 , Setuprunden , Sub 'INT0 Taste gedrückt
Goto Tastenwart
Pstarten: 'Beginn des Hauptteils
S1 = 0 ' Alle Variablen initialisieren
S2 = 0
Fertig = 0
Z1aehler = 0
Z2aehler = 0
Runden = Erunden ' Anzahl der zu fahrenden Runden aus EEPROM holen
Stop Timer0 ' Timer erst anhalten sonst stimmt der Zähler nicht
Stop Timer2
Cls ' Startbildschirm
Cursor Off
Upperline
Lcd "START " ; Runden ; " Runden"
Lowerline
Lcd "* Taste druecken"
Tast2wart:
Debounce Taster1 , 0 , Losgehts 'int1 Taste gedrückt
Debounce Taster0 , 0 , Sstart 'INT0 Taste gedrückt
Goto Tast2wart
Losgehts: 'Akustisches Startsignal
Sound Buzzer , 400 , 450
Waitms 600
Sound Buzzer , 400 , 450
Waitms 600
Sound Buzzer , 400 , 450
Waitms 600
Sound Buzzer , 800 , 350
Cls
'----------- Zählschleife --------------------
Do
Upperline
Lcd "Spur1: " ; Z1aehler
Lowerline
Lcd "Spur2: " ; Z2aehler
Debounce Taster1 , 0 , Zfertig ' Taste für Abbruch gedrückt
Loop Until Fertig = 1
' ---------- Platzierung ----------------------
Sieger: 'Anzeige der Platzierung
Cls
Lcd "Erster "
Gosub Winner
If Z1aehler >= Runden Then
Lcd " Spur1 " ; Z1aehler
Locate 2 , 1
Lcd "Zweiter Spur2 " ; Z2aehler
End If
If Z2aehler >= Runden Then
Lcd " Spur2 " ; Z2aehler
Locate 2 , 1
Lcd "Zweiter Spur1 " ; Z1aehler
End If
Gosub Winner
Gosub Wtaste 'Auf Taste warten
Goto Pstarten 'Nächstes Rennen
End 'end program
' -- Vorzeitiger Abbruch -------------------------
Zfertig:
Sound Buzzer , 400 , 450
Cls
Lcd "### Abbruch! ###"
Lowerline
Lcd "Spur1 " ; Z1aehler ; " Spur2 " ; Z2aehler
Gosub Wtaste
Goto Pstarten 'Nächstes Rennen
' --------------- Unterprogramme -----------------
' -----------Flanke am Zähleingang ---------------
Isr_pcint0:
If Pind.6 = 0 Then 'Fallende Flanke erkannt
If S1 = 0 Then 'Prüfung ob erste Flanke
S1 = 1 'Timerflag setzen
Fz1 = 0 'Flankenzähler auf Null
Start Timer0 'Timer starten
End If
End If
If Pind.7 = 0 Then
If S2 = 0 Then
S2 = 1
Fz2 = 0
Start Timer2
End If
End If
Return
'----------- Timer 0 abgelaufen -----------------
Isr_timer0:
' Toggle Portb.6
If Pind.6 = 1 Then ' Ist Pin wieder high?
Incr Fz1 'Flankenzähler plus 1
If Fz1 = 20 Then 'ca. 30ms Vergangen
Incr Z1aehler 'Runde zählen
S1 = 0 'Flankenerkennung auf Null
Stop Timer0 'Timer anhalten
Toggle Portb.6 ' Kontroll LED umschalten
End If
End If
If Z1aehler = Runden Then Fertig = 1 ' maximale Runden erreicht
Return
'----------- Timer 2 angelaufen ------------------
Isr_timer2:
' Toggle Portb.7
If Pind.7 = 1 Then
Incr Fz2
If Fz2 = 20 Then
Incr Z2aehler
S2 = 0
Stop Timer2
Toggle Portb.7 ' Kontroll LED schalten
End If
End If
If Z2aehler = Runden Then Fertig = 1 ' maximale Runden erreicht
Return
'--- INT1 Taster abfragen zum Warten ----
Wtaste:
Debounce Taster1 , 0 , Wfertig 'Warten bis INT1 Taster gedrückt
Goto Wtaste
Wfertig:
Return
'----- Setup Rundenzahl ----
Setuprunden:
Runden = Erunden ' Wert aus EEPROM Holen
Cls
Lcd "Runden: " ; Runden
Lowerline
Lcd "Neuer Wert:"
Cursor On Blink
Fz1 = 1
Setuploop:
Locate 2 , 12
Lcd Fz1
Shiftcursor Left
Do
Debounce Taster0 , 0 , Splus 'Warten bis INT1 Taster gedrückt
Debounce Taster1 , 0 , Setupfertig 'Warten bis INT1 Taster gedrückt
Loop
Splus:
Incr Fz1 'Rundenzahl erhöhen
Goto Setuploop
Setupfertig:
Erunden = Fz1 'Neuer Wert ins EEPROM schreiben
Cursor Off
Return
'---- Sound für Renn-Ende ----------
Winner:
Sound Buzzer , 500 , 450
Waitms 400
Sound Buzzer , 800 , 350
Waitms 300
Sound Buzzer , 500 , 450
Waitms 200
Sound Buzzer , 800 , 350
Return














