Rundenzähler für Slotracer

von Wolfram Herzog
ELO 2010
Elektronik-Labor  Labortagebuch  ELO  

 


 


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.


Erfassen der gefahrenen Runden
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.

Der Hardwareaufbau
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 Anschluß 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,54mm 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,2K Pull-up-Widerstand von PD6 und PD7 nach Vcc hinzugefügt. Danach waren die Probleme beseitigt.

Die Software
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
 
'*****************************************
' 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

' Ende des Listings



Elektronik-Labor  Labortagebuch  ELO