Die Digitalanzeige

Wer kennt das nicht, man hat eine Drehbank oder Fräsmaschine mit einer "komischen" Spindelsteigung von z.B 0,8mm/Umdrehung. Wieviele Umdrehungen muss man doch gleich für einen Verfahrweg von 5,5mm machen??? Um lästigen Rechnereien ein Ende zu bereiten, wurde diese Anzeige entwickelt.


Schaltplan

Die Anzeige besteht aus einer Displayplatine und drei identischen Controllerplatinen. Die Steuerung für je eine Zeile übernimmt ein Mikrocontroller aus dem Hause Atmel. Eingaben sind über eine Zifferntastatur möglich. Um auswählen zu können welche Zeile über die Tastatur bedient werden soll, ist ein zusätzlicher Schalter auf der Displayplatine angebracht. Die Tastatur wird über 4066 ICs an die entsprechende Controllerplatine durchgeschaltet. Die einzelnen Anoden der Siebensegmentanzeigen sind zu einem Bussystem zusammengefasst und werden über die Kathoden gemultiplext. Das spart Ausgänge am Controller und senkt den Stromverbrauch.

Schaltplan der Displayplatine
Schaltplan der Displayplatine
Zum Vergrößern auf das Bild klicken

Schaltplan der Controllerplatine
Schaltplan der Controllerplatine
Zum Vergrößern auf das Bild klicken

Platine

Die Platine wurde mit dem Layoutprogramm EAGLE erstellt. Mit dem, für die private Nutzung kostenfreien, ULP von www.matwei.de ist es möglich 3D-Bilder der Platine zu erzeugen. Dieses ULP erzeugt eine Datei, welche mit dem ebenfalls kostenfreien Programm POV-Ray in ein 3D-Bild gerendert werden kann. Die 3D-Marcos für die Siebensegmentanzeigen, die Tastatur und den Schalter wurden von mir erstellt.



Displayplatine
Displayplatine Bestückungsseite Displayplatine Leiterseite



Controllerplatine
Controllerplatine Bestückungsseite Controllerplatine Leiterseite

Die Ätzvorlagen gibts hier. (Achtung: Diese sind bereits gespiegelt, sodass sie direkt auf eine Folie gedruckt werden können!!!)
Die Platine für das Display ist mit einer Menge Drahtbrücken zu bestücken. Für den der sich diese Arbeit ersparen will, habe ich auch die Ätzvorlage für eine Doppelseitige Platine generiert. Die Vorlagen sind schon gespiegelt, sodass jeweils die bedruckte Seite direkt auf dem Platinenmaterial liegen muss.

Da man auf den Bildern die Drahtbrücken nicht alle erkennen kann, hier noch eine Bestückungshilfe:

Controllerplatine Bestückungshilfe

Displayplatine Bestückungshilfe

Bilder der realen Digitalanzeige

fertige Digitalanzeige fertige Digitalanzeige

Sensoren

Die Controllerplatinen haben einen vierpoligen Anschluss für verschiedene Sensoren (+5V, Masse, Eingang1, Eingang2).
Bisher wurde der Prototyp mit einem optischen Inkremental-Impulsgeber (Wegerfassung) und einem Hall-Sensor(Drehzahlerfassung) getestet.

1. Inkremental-Impulsgeber (Encoder)

Funktionsweise:

Encoderprinzip

Dreht man die Schlitzscheibe nach rechts, so wird zuerst Sensor 1 beleuchtet und nach einer gewissen Zeit erst Sensor 2. Sensor 1 wird auch zuerst wieder im Schatten sein, während Sensor 2 noch eine Zeit weiterbeleuchtet wird. Dreht man die Schlitzscheibe nach links kehrt sich der Prozess um. Mit diesen Informationen kommt man zu folgenden Signaldiagrammen:

Linkslauf:

Linkslauf

Rechtslauf:

Rechtslauf

Um eine ausreichende Auflösung zu erreichen, sollte ein Sensor mit mindestens 500 Impulsen/Umdrehung verwendet werden (besser 1000 oder 2000).
Mit 500 Impulsen meint der Hersteller 500 Löcher in der Schlitzscheibe. Bei diesem Projekt werden die steigende und die fallende Flanke der Sensoren ausgewertet, bei zwei Sensoren sind das in diesem Beispiel 2000 Flanken/Umdrehung also eine "Vervierfachung" der Auflösung.
Der Encoder wird nicht, wie man vermuten könnte mit der Spindel verbunden, sondern direkt mit dem Schlitten.
Das ganze muss jetzt "nur" noch spielfrei sein.smile

2. Hall-Sensor

Der hier verwendete Sensor TLE4905L ist eigentlich nicht nur ein reiner Hall-Sensor, er beinhaltet zusätzlich einen Verstärker und eine Schmitt-Trigger-Stufe für den Ausgang. Es steht also ein digitales Signal zur Verfügung. Der Sensor wurde nach dem Applikationsvorschlag im Datenblatt angeschlossen, der Lastwiderstand RL wird als Pullup im Controller programmiert. Für die Drehzahlmessung ist ein Eingang an der Controllerplatine ausreichend, der andere wird einfach offen gelassen. Zur Abnahme der Drehzahl wird ein Magnet an die Welle der Maschine angebracht. Der Sensor wird in geringem Abstand zum Magnet an der Maschine fixiert.

Programmierung

!!! Die Programme befinden sich im Moment noch in der Testphase !!!

Quellcode für die Wegerfassung: (Syntax highlighted mit
G
e
S
H
i
mit Anpassungen für BascomAVR von mir)
 
      '        *****************************************
      '        *     Wegerfassung für eine Drehbank    *
      '        *              mit ATMega 16            *
      '        *              Version 1.1a             *
      '        *          © by Stefan Weigert          *
      '        *****************************************
 
      '     Beschaltung
      '        PortA.0...A.7     Ansteuerung der Anoden der 7-Segmentanzeigen über 100R A.0=a A.1=b ... A.7=dp
      '        PortC.0...C.7     Ansteuerung der gemeinsamen Kathoden der Anzeigen C.0=MSB C.7=LSB über Transistor
      '        PortB.0...B.7     über 4066 an Tastaturmatrix
      '        PortD.0...D.1     frei
      '        PortD.2 (INT0)    Inkrementalgeber
      '        PortD.3 (INT1)    Inkrementalgeber
      '        PortD.4...D.6     frei
 
      $regfile = "m16def.dat"                               'Dem Compiler vorgeben welcher Controller benutzt wird
      $crystal = 16000000                                   'Taktfrequenz in Hz vorgeben
      Ddra = &B11111111                                     'PortA alles Ausgänge
      Ddrb = &B00000000                                     'PortB alles Eingänge
      Ddrc = &B11111111                                     'PortC alles Ausgänge
      Ddrd = &B00000000                                     'PortD alles Eingänge
 
      Portd = &B00001100                                    'Pullups für INT0 und INT1 setzen
 
      Mcucr = &B00000101                                    'INT0 und INT1 auf steigende UND fallende Flanke einstellen
      Gicr = &B11000000                                     'INT0 und INT1 aktivieren
 
      On Int0 Interrupt0                                    'Sprungadresse für INT0 definieren
      On Int1 Interrupt1                                    'Sprungadresse für INT1 definieren
 
      Config Kbd = Portb , Debounce = 30                    'Tastaturmatrix mit Entprellzeit definieren
 
      Dim Eeprom_dummybyte As Eram Byte At &H00             'Das erste Byte im EEProm könnte bei einem Reset verfälscht werden
      Dim Eeprom_durchmesserflag As Eram Byte At &H01       'Speichervariable im EEProm = 1 wenn Durchmesser angezeigt werden sollen
      Dim Eeprom_richtungsflag As Eram Byte At &H02         'Speichervariable im EEprom rechts/links addieren/subtrahieren
      Dim Eeprom_schrittwert As Eram Long At &H03           'Speichervariable im EEprom für Wert für einen Schritt des Inkrementalgebers
 
      $eepromhex                                            'den Compiler anweisen den EEProminhalt im Intel-Hex-Format auszugeben
      $eeprom                                               'die folgenden Daten werden im EEProm gespeichert
         Data 0 , 0 , 0 , 1000&                             'Daten für das EEprom (Byte , Byte, Byte , Long) Grundeinstellungen
      $data                                                 'den Compiler anweisen, dass weitere Daten in den
                                                            'Flash-Speicher abgelegt werden sollen
 
      Dim N As Word At &H60                                 'n = allgemeine Zählvariable
      Dim Stelle As Byte At &H62                            'Schleifenvariable für die Stellenauswahl
      Dim Encoderstatusalt As Byte At &H63                  'Variable für den "alten" Encoderstatus
      Dim Encoderstatusneu As Byte At &H64                  'Variable für den "neuen" Encoderstatus
      Dim Schrittwert As Long At &H65                       'Variable für den Encoderschritt in Nanometer
      Dim Taste As Byte At &H69                             'Variable für die Tastenauswahl
      Dim Menuepunkt As Byte At &H70
      Dim Messwert As Long At &H71                          'angezuzeigender Wert
      Dim Anzeigewert As Long At &H75
      Dim Anzeigewertascii As String * 8 At &H79            'Zeichenkette des anzuzeigenden Wertes (Textes)
      Dim Asciizeichen(8) As Byte At &H79 Overlay           'Byteweise Ausgabe ermöglichen
      Dim Kommaflag As Bit At &H88                          'Flag bei 1 wird das Komma dargestellt
 
Displaytest:
      For Encoderstatusalt = 0 To 3
         Anzeigewertascii = Lookupstr(encoderstatusalt , Testwerte)
         For N = 1 To 1500
            Gosub Anzeigen
         Next N
      Next Encoderstatusalt
 
Init:
         Encoderstatusalt = Pind And 12                     'INT0 und INT1 ausmaskieren
         Schrittwert = Eeprom_schrittwert                   '0 .. +32767 in Nanometer
         If Eeprom_durchmesserflag = 1 Then
            Schrittwert = Schrittwert * 2
         End If
         If Eeprom_richtungsflag = 1 Then
            Schrittwert = Schrittwert * -1
         End If
         Messwert = 0                                       'Startwert
         Enable Interrupts                                  'Interrupts global feischalten
 
Main:
         Do
            Kommaflag = 1                                   'Flag = 1 wenn ein Komma angezeigt werden soll
            Gosub Messwerttest
            Gosub Anzeigen
            Taste = Getkbd()
            If Taste = 13 Then
               Gosub Hauptmenue
            End If
         Loop
 
Messwerttest:
         Anzeigewert = Messwert
         If Anzeigewert > 2145000000 Or Anzeigewert < -2145000000 Then
            Disable Interrupts
            Kommaflag = 0
            Anzeigewertascii = "FLoAtEd "
            For N = 0 To 2500
               Gosub Anzeigen
            Next N
            Messwert = 0
            Enable Interrupts
         Elseif Anzeigewert > 2100000000 Or Anzeigewert < -2100000000 Then
            Kommaflag = 0
            Anzeigewertascii = "FLoAtinG"
         Elseif Anzeigewert > 0 Then
            Anzeigewertascii = Str(anzeigewert)
            Gosub Ruecken
         Elseif Anzeigewert < 0 Then
            Anzeigewert = Anzeigewert * -1
            Anzeigewertascii = Str(anzeigewert)
            Gosub Ruecken
            Asciizeichen(1) = 45                            'negatives Vorzeichen
         Else
            Anzeigewertascii = "    0000"
         End If
      Return
 
Anzeigen:                                                   'Anzeige in Abhängigkeit der gespeicherten Asciizeichen die Segmente schalten
         For Stelle = 0 To 7
            Select Case Asciizeichen(stelle + 1)
               Case 45 : Porta = 64                         '-
 
               Case 48 : Porta = 63                         '0
               Case 49 : Porta = 6                          '1
               Case 50 : Porta = 91                         '2
               Case 51 : Porta = 79                         '3
               Case 52 : Porta = 102                        '4
               Case 53 : Porta = 109                        '5
               Case 54 : Porta = 125                        '6
               Case 55 : Porta = 39                         '7
               Case 56 : Porta = 127                        '8
               Case 57 : Porta = 111                        '9
 
               Case 65 : Porta = 119                        'A
 
               Case 67 : Porta = 57                         'C
 
               Case 69 : Porta = 121                        'E
               Case 70 : Porta = 113                        'F
               Case 71 : Porta = 125                        'G
               Case 72 : Porta = 118                        'H
               Case 73 : Porta = 6                          'I
 
               Case 76 : Porta = 56                         'L
 
               Case 80 : Porta = 115                        'P
 
               Case 83 : Porta = 109                        'S
 
               Case 85 : Porta = 62                         'U
 
               Case 98 : Porta = 124                        'b
               Case 99 : Porta = 88                         'c
               Case 100 : Porta = 94                        'd
 
               Case 104 : Porta = 116                       'h
               Case 105 : Porta = 4                         'i
 
               Case 110 : Porta = 84                        'n
               Case 111 : Porta = 92                        'o
 
               Case 114 : Porta = 80                        'r
 
               Case 116 : Porta = 120                       't
               Case 117 : Porta = 28                        'u
 
               Case 121 : Porta = 110                       'y
               Case Else : Porta = 0
            End Select
            If Stelle = 4 And Kommaflag = 1 Then
               Porta = Porta + 128
            End If
            Portc.stelle = 1
            Waitus 100
            Portc.stelle = 0
         Next Stelle
      Return
 
Ruecken:
         Asciizeichen(8) = Asciizeichen(7)                  'einmal auf jeden Fall Rücken (Vorzeichenstelle)
         Asciizeichen(7) = Asciizeichen(6)
         Asciizeichen(6) = Asciizeichen(5)
         Asciizeichen(5) = Asciizeichen(4)
         Asciizeichen(4) = Asciizeichen(3)
         Asciizeichen(3) = Asciizeichen(2)
         Asciizeichen(2) = Asciizeichen(1)
         Asciizeichen(1) = 0
 
         If Anzeigewert < 1000000000 Then
            Asciizeichen(8) = Asciizeichen(7)
            Asciizeichen(7) = Asciizeichen(6)
            Asciizeichen(6) = Asciizeichen(5)
            Asciizeichen(5) = Asciizeichen(4)
            Asciizeichen(4) = Asciizeichen(3)
            Asciizeichen(3) = Asciizeichen(2)
            Asciizeichen(2) = 0
         End If
 
         If Anzeigewert < 100000000 Then
            Asciizeichen(8) = Asciizeichen(7)
            Asciizeichen(7) = Asciizeichen(6)
            Asciizeichen(6) = Asciizeichen(5)
            Asciizeichen(5) = Asciizeichen(4)
            Asciizeichen(4) = Asciizeichen(3)
            Asciizeichen(3) = 0
         End If
 
         If Anzeigewert < 10000000 Then
            Asciizeichen(8) = Asciizeichen(7)
            Asciizeichen(7) = Asciizeichen(6)
            Asciizeichen(6) = Asciizeichen(5)
            Asciizeichen(5) = Asciizeichen(4)
            Asciizeichen(4) = 0
         End If
         If Anzeigewert < 1000000 Then
            Asciizeichen(8) = Asciizeichen(7)
            Asciizeichen(7) = Asciizeichen(6)
            Asciizeichen(6) = Asciizeichen(5)
            Asciizeichen(5) = 48
         End If
         If Anzeigewert < 100000 Then
            Asciizeichen(8) = Asciizeichen(7)
            Asciizeichen(7) = Asciizeichen(6)
            Asciizeichen(6) = 48
         End If
         If Anzeigewert < 10000 Then
            Asciizeichen(8) = Asciizeichen(7)
            Asciizeichen(7) = 48
         End If
      Return
 
Hauptmenue:
         Kommaflag = 0
         Menuepunkt = 0
         Do
            Taste = Getkbd()
            Select Case Taste
               Case 12 : Exit Do
               Case 13 :
                           If Menuepunkt < 7 Then Incr Menuepunkt Else Menuepunkt = 1
                           Select Case Menuepunkt
                              Case 1 : Anzeigewertascii = "nuLL    "
                              Case 2 : Anzeigewertascii = "PrESEt  "
                              Case 3 : Anzeigewertascii = "diA  on "
                              Case 4 : Anzeigewertascii = "diA oFF "
                              Case 5 : Anzeigewertascii = "StEP SEt"
                              Case 6 : Anzeigewertascii = "StEP UP "
                              Case 7 : Anzeigewertascii = "StEP dn "
                           End Select
               Case 14:
                           Select Case Menuepunkt
                              Case 1 :
                                          Messwert = 0
                                          Gosub Done
                                          Kommaflag = 1
                                          Return
                              Case 2 :
                                          Gosub Preset
                                          Kommaflag = 1
                                          Return
                              Case 3 :
                                          Eeprom_durchmesserflag = 1
                                          Schrittwert = Eeprom_schrittwert
                                          Schrittwert = Schrittwert * 2
                                          If Eeprom_richtungsflag = 1 Then
                                             Schrittwert = Schrittwert * -1
                                          End If
                                          Gosub Done
                                          Kommaflag = 1
                                          Return
                              Case 4 :
                                          Eeprom_durchmesserflag = 0
                                          Schrittwert = Eeprom_schrittwert
                                          If Eeprom_richtungsflag = 1 Then
                                             Schrittwert = Schrittwert * -1
                                          End If
                                          Gosub Done
                                          Kommaflag = 1
                                          Return
                              Case 5 :
                                          Gosub Stepset
                                          Kommaflag = 1
                                          Return
 
                              Case 6 :
                                          Eeprom_richtungsflag = 0
                                          Schrittwert = Eeprom_schrittwert
                                          If Eeprom_durchmesserflag = 1 Then
                                             Schrittwert = Schrittwert * 2
                                          End If
                                          Gosub Done
                                          Kommaflag = 1
                                          Return
 
                              Case 7 :
                                          Eeprom_richtungsflag = 1
                                          Schrittwert = Eeprom_schrittwert
                                          Schrittwert = Schrittwert * -1
                                          If Eeprom_durchmesserflag = 1 Then
                                             Schrittwert = Schrittwert * 2
                                          End If
                                          Gosub Done
                                          Kommaflag = 1
                                          Return
                           End Select
            End Select
            Gosub Nokey
            Gosub Anzeigen
         Loop
      Return
 
Preset:
         Disable Interrupts
         Messwert = 0
         Gosub Messwerttest
         Gosub Anzeigen
         Gosub Nokey
         Do
            Taste = Getkbd()
            Select Case Taste
               Case 0 :                                     '1
                           If Messwert <= 214499900 And Messwert >= -214499900 Then
                              Messwert = Messwert * 10
                              If Messwert < 0 Then Messwert = Messwert - 1000 Else Messwert = Messwert + 1000
                           Else
                              Gosub Error
                           End If
               Case 1 :                                     '2
                           If Messwert <= 214499800 And Messwert >= -214499800 Then
                              Messwert = Messwert * 10
                              If Messwert < 0 Then Messwert = Messwert - 2000 Else Messwert = Messwert + 2000
                           Else
                              Gosub Error
                           End If
               Case 2 :                                     '3
                           If Messwert <= 214499700 And Messwert >= -214499700 Then
                              Messwert = Messwert * 10
                              If Messwert < 0 Then Messwert = Messwert - 3000 Else Messwert = Messwert + 3000
                           Else
                              Gosub Error
                           End If
               Case 4 :                                     '4
                           If Messwert <= 214499600 And Messwert >= -214499600 Then
                              Messwert = Messwert * 10
                              If Messwert < 0 Then Messwert = Messwert - 4000 Else Messwert = Messwert + 4000
                           Else
                              Gosub Error
                           End If
               Case 5 :                                     '5
                           If Messwert <= 214499500 And Messwert >= -214499500 Then
                              Messwert = Messwert * 10
                              If Messwert < 0 Then Messwert = Messwert - 5000 Else Messwert = Messwert + 5000
                           Else
                              Gosub Error
                           End If
               Case 6 :                                     '6
                           If Messwert <= 214499400 And Messwert >= -214499400 Then
                              Messwert = Messwert * 10
                              If Messwert < 0 Then Messwert = Messwert - 6000 Else Messwert = Messwert + 6000
                           Else
                              Gosub Error
                           End If
               Case 8 :                                     '7
                           If Messwert <= 214499300 And Messwert >= -214499300 Then
                              Messwert = Messwert * 10
                              If Messwert < 0 Then Messwert = Messwert - 7000 Else Messwert = Messwert + 7000
                           Else
                              Gosub Error
                           End If
               Case 9 :                                     '8
                           If Messwert <= 214499200 And Messwert >= -214499200 Then
                              Messwert = Messwert * 10
                              If Messwert < 0 Then Messwert = Messwert - 8000 Else Messwert = Messwert + 8000
                           Else
                              Gosub Error
                           End If
               Case 10 :                                    '9
                           If Messwert <= 214499100 And Messwert >= -214499100 Then
                              Messwert = Messwert * 10
                              If Messwert < 0 Then Messwert = Messwert - 9000 Else Messwert = Messwert + 9000
                           Else
                              Gosub Error
                           End If
               Case 12 :                                    '+/-
                           Messwert = Messwert * -1
 
               Case 13 :                                    '0
                           If Messwert <= 214500000 And Messwert >= -214500000 Then
                              Messwert = Messwert * 10
                           Else
                              Gosub Error
                           End If
               Case 14 : Exit Do                            'Enter
            End Select
            Gosub Messwerttest
            Gosub Nokey
            Gosub Anzeigen
         Loop
         Gosub Done
         Enable Interrupts
      Return
 
Stepset:
         Disable Interrupts
         Messwert = 0
         Gosub Messwerttest
         Gosub Anzeigen
         Gosub Nokey
         Do
            Taste = Getkbd()
            Select Case Taste
               Case 0 :                                     '1
                           If Messwert <= 3276000 Then
                              Messwert = Messwert * 10
                              Messwert = Messwert + 1000
                           Else
                              Gosub Error
                           End If
               Case 1 :                                     '2
                           If Messwert <= 3276000 Then
                              Messwert = Messwert * 10
                              Messwert = Messwert + 2000
                           Else
                              Gosub Error
                           End If
               Case 2 :                                     '3
                           If Messwert <= 3276000 Then
                              Messwert = Messwert * 10
                              Messwert = Messwert + 3000
                           Else
                              Gosub Error
                           End If
               Case 4 :                                     '4
                           If Messwert <= 3276000 Then
                              Messwert = Messwert * 10
                              Messwert = Messwert + 4000
                           Else
                              Gosub Error
                           End If
               Case 5 :                                     '5
                           If Messwert <= 3276000 Then
                              Messwert = Messwert * 10
                              Messwert = Messwert + 5000
                           Else
                              Gosub Error
                           End If
               Case 6 :                                     '6
                           If Messwert <= 3276000 Then
                              Messwert = Messwert * 10
                              Messwert = Messwert + 6000
                           Else
                              Gosub Error
                           End If
               Case 8 :                                     '7
                           If Messwert <= 3276000 Then
                              Messwert = Messwert * 10
                              Messwert = Messwert + 7000
                           Else
                              Gosub Error
                           End If
               Case 9 :                                     '8
                           If Messwert <= 3275000 Then
                              Messwert = Messwert * 10
                              Messwert = Messwert + 8000
                           Else
                              Gosub Error
                           End If
               Case 10 :                                    '9
                           If Messwert <= 3275000 Then
                              Messwert = Messwert * 10
                              Messwert = Messwert + 9000
                           Else
                              Gosub Error
                           End If
               Case 12 : Exit Do
               Case 13 :                                    '0
                           If Messwert <= 3276000 Then
                              Messwert = Messwert * 10
                           Else
                              Gosub Error
                           End If
               Case 14 : Exit Do                            'Enter
            End Select
            Gosub Messwerttest
            Gosub Nokey
            Gosub Anzeigen
         Loop
         If Taste = 14 Then
            Messwert = Messwert / 1000
            Eeprom_schrittwert = Messwert
            Schrittwert = Eeprom_schrittwert
            If Eeprom_durchmesserflag = 1 Then
               Schrittwert = Schrittwert * 2
            End If
            If Eeprom_richtungsflag = 1 Then
               Schrittwert = Schrittwert * -1
            End If
            Gosub Done
         End If
         Messwert = 0
         Enable Interrupts
      Return
 
Nokey:
         Do
            Taste = Getkbd()
            Gosub Anzeigen
         Loop Until Taste = 16
      Return
 
Error:
         Anzeigewertascii = "Error   "
         For N = 0 To 600
            Gosub Anzeigen
         Next N
      Return
 
Done:
         Anzeigewertascii = "    donE"
         For N = 0 To 600
            Gosub Anzeigen
         Next N
      Return
 
Interrupt0:
         Disable Interrupts
         Encoderstatusneu = Pind And 12
         Select Case Encoderstatusalt
            Case 0 : Messwert = Messwert + Schrittwert
            Case 4 : Messwert = Messwert - Schrittwert
            Case 8 : Messwert = Messwert - Schrittwert
            Case 12 : Messwert = Messwert + Schrittwert
         End Select
         Encoderstatusalt = Encoderstatusneu
         Enable Interrupts
      Return
 
Interrupt1:
         Disable Interrupts
         Encoderstatusneu = Pind And 12
         Select Case Encoderstatusalt
            Case 0 : Messwert = Messwert - Schrittwert
            Case 4 : Messwert = Messwert + Schrittwert
            Case 8 : Messwert = Messwert + Schrittwert
            Case 12 : Messwert = Messwert - Schrittwert
         End Select
         Encoderstatusalt = Encoderstatusneu
         Enable Interrupts
      Return
 
Testwerte:
Data "diSPLAy " , "tESt    " , "88888888" , "LEnGth  "


Quellcode für die Drehzahlerfassung: (Syntax highlighted mit
G
e
S
H
i
mit Anpassungen für BascomAVR von mir)
      '        **********************************************
      '        *     Drehzahlerfassung an einer Drehbank    *
      '        *                 mit ATMega 16              *
      '        *                 Version 1.1a               *
      '        *             © by Stefan Weigert            *
      '        **********************************************
 
      '     Beschaltung
      '        PortA.0...A.7     Ansteuerung der Anoden der 7-Segmentanzeigen über 82R A.0=a A.1=b ... A.7=dp
      '        PortC.0...C.7     Ansteuerung der gemeinsamen Kathoden der Anzeigen C.0=MSB C.7=LSB über Transistor
      '        PortB.0...B.7     über 4066 an Tastaturmatrix
      '        PortD.0...D.1     frei
      '        PortD.2 (INT0)    Drehzahlsensor (z.B.Hallsensor) mit 1Impuls pro Umdrehung
      '        PortD.3...D.6     frei
 
      $regfile = "m16def.dat"                               'Dem Compiler vorgeben welcher Controller benutzt wird
      $crystal = 16000000                                   'Taktfrequenz in Hz vorgeben
      Ddra = &B11111111                                     'PortA alles Ausgänge
      Ddrb = &B00000000                                     'PortB alles Eingänge
      Ddrc = &B11111111                                     'PortC alles Ausgänge
      Ddrd = &B00000000                                     'PortD alles Eingänge
 
      Portd.2 = 1                                           'Pullup für INT0 setzen
 
      Mcucr = &B00000011                                    'INT0 auf steigende Flanke einstellen
 
      Dim Zeitwert As Long At &H60                          'Zeitwert zwischen zwei Sensorimpulsen
      Dim Zeitwertlow As Word At &H60 Overlay               'HighWord des Zeitwertes wird durch Timerüberlauf erhöht
      Dim Zeitwerthigh As Word At &H62 Overlay              'LowWord des Zeitwertes ist der Timerstand selbst
      Dim Drehzahlascii As String * 8 At &H64               'Zeichenkette des anzuzeigenden Wertes (Textes)
      Dim Asciizeichen(8) As Byte At &H64 Overlay           'Byteweise Ausgabe ermöglichen
      Dim Drehzahl As Long At &H72                          'Variable für die Drehzahl
      Dim N As Word At &H76                                 'n = allgemeine Zählvariable
      Dim Stelle As Byte At &H78                            'Schleifenvariable für die Stellenauswahl
      Dim Anzeigewert As Long At &H79
 
      Config Timer1 = Timer , Prescale = 8                  'Timer1 (16Bit) als Timer konfigurieren und mit 1/8 des Systemtaktes betreiben
      On Ovf1 Timerueberlauf1                               'Bei Timerüberlauf (alle 500µs) zur Subroutine 'Timerueberlauf1' springen
      On Int0 Interrupt0                                    'Sprungadresse für INT0 definieren
      Enable Ovf1                                           'TimerInterrupt1 aktivieren
      Enable Int0
 
 
Displaytest:
      For Zeitwert = 0 To 3
         Drehzahlascii = Lookupstr(zeitwert , Testwerte)
         For N = 1 To 1500
            Gosub Anzeigen
         Next N
      Next Zeitwert
      Enable Interrupts                                     'Interrupts global feischalten
 
Init:
      Zeitwert = 0
      Anzeigewert = 0
      Drehzahl = 0
      Stop Timer1
      Timer1 = 0
      Start Timer1
 
 
Main:
      Do
         Anzeigewert = Drehzahl
         If Anzeigewert > 99999 Then
            Drehzahlascii = "to HiGh "
         Else
            Drehzahlascii = Str(anzeigewert)
            Gosub Ruecken
         End If
         For N = 1 To 400
            Gosub Anzeigen
         Next N
      Loop
 
Anzeigen:
         For Stelle = 0 To 7
            Select Case Asciizeichen(stelle + 1)            'Anzeige in Abhängigkeit der gespeicherten Asciizeichen die Segmente schalten
               Case 45 : Porta = 64                         '-
 
               Case 48 : Porta = 63                         '0
               Case 49 : Porta = 6                          '1
               Case 50 : Porta = 91                         '2
               Case 51 : Porta = 79                         '3
               Case 52 : Porta = 102                        '4
               Case 53 : Porta = 109                        '5
               Case 54 : Porta = 125                        '6
               Case 55 : Porta = 39                         '7
               Case 56 : Porta = 127                        '8
               Case 57 : Porta = 111                        '9
 
               Case 65 : Porta = 119                        'A
 
               Case 67 : Porta = 57                         'C
 
               Case 69 : Porta = 121                        'E
               Case 70 : Porta = 113                        'F
               Case 71 : Porta = 125                        'G
               Case 72 : Porta = 118                        'H
               Case 73 : Porta = 6                          'I
 
               Case 76 : Porta = 56                         'L
 
               Case 80 : Porta = 115                        'P
 
               Case 83 : Porta = 109                        'S
 
               Case 85 : Porta = 62                         'U
 
               Case 98 : Porta = 124                        'b
               Case 99 : Porta = 88                         'c
               Case 100 : Porta = 94                        'd
 
               Case 104 : Porta = 116                       'h
               Case 105 : Porta = 4                         'i
 
               Case 110 : Porta = 84                        'n
               Case 111 : Porta = 92                        'o
 
               Case 114 : Porta = 80                        'r
 
               Case 116 : Porta = 120                       't
               Case 117 : Porta = 28                        'u
 
               Case 121 : Porta = 110                       'y
               Case Else : Porta = 0
            End Select
            Portc.stelle = 1
            Waitus 100
            Portc.stelle = 0
         Next Stelle
      Return
 
Ruecken:
         If Anzeigewert = 0 Then
            Drehzahlascii = "     0 U"
            Return
         End If
 
         Asciizeichen(8) = 85
         Asciizeichen(7) = 0
 
         If Anzeigewert < 100000 Then
            Asciizeichen(6) = Asciizeichen(5)
            Asciizeichen(5) = Asciizeichen(4)
            Asciizeichen(4) = Asciizeichen(3)
            Asciizeichen(3) = Asciizeichen(2)
            Asciizeichen(2) = Asciizeichen(1)
            Asciizeichen(1) = 0
         End If
 
         If Anzeigewert < 10000 Then
            Asciizeichen(6) = Asciizeichen(5)
            Asciizeichen(5) = Asciizeichen(4)
            Asciizeichen(4) = Asciizeichen(3)
            Asciizeichen(3) = Asciizeichen(2)
            Asciizeichen(2) = 0
         End If
 
         If Anzeigewert < 1000 Then
            Asciizeichen(6) = Asciizeichen(5)
            Asciizeichen(5) = Asciizeichen(4)
            Asciizeichen(4) = Asciizeichen(3)
            Asciizeichen(3) = 0
         End If
 
         If Anzeigewert < 100 Then
            Asciizeichen(6) = Asciizeichen(5)
            Asciizeichen(5) = Asciizeichen(4)
            Asciizeichen(4) = 0
         End If
 
         If Anzeigewert < 10 Then
            Asciizeichen(6) = Asciizeichen(5)
            Asciizeichen(5) = 0
         End If
 
      Return
 
Interrupt0:
         Zeitwertlow = Timer1
         Timer1 = 0
         Drehzahl = 120000000 / Zeitwert
         Zeitwert = 0
      Return
 
Timerueberlauf1:
         Incr Zeitwerthigh
         If Zeitwert > 4000000 Then
            Disable Int0
            Zeitwert = 0
            Drehzahl = 0
            Enable Int0
         End If
      Return
 
Testwerte:
Data "diSPLAy " , "tESt    " , "88888888" , "rotAtion"


Die fertigen Hexfiles: Wegerfassung Drehzahlerfassung

Für die Wegerfasung können und sollten noch die Grundeinstellungen ins EEProm geladen werden: Grundeinstellungen


Kurzanleitung für den Normalbetrieb (der Wegerfassung):

1. Nach dem Einschalten
- es wird ein Displaytest ausgeführt
- diverse Einstellungen werden geladen
- Anzeige wird genullt
- die Digitalanzeige geht in den Normalbetrieb und würde auf Bewegungen des Encoders reagieren

Im Normalbetrieb können außer dem Verfahrweg zwei Meldungen auf dem Display erscheinen:
- die Digitalanzeige zeigt "FLoAtinG" an
Ist der Anzeigewert größer als 2100mm bzw. kleiner als -2100mm besteht die Gefahr eines internen Variablenüberlaufes.
Solange "FLoAtinG" im Display steht kann man den Messwert durch Richtungsumkehr "retten".

- die Digitalanzeige zeigt "FLoAtEd"
Der Messwert lag über 2145mm bzw. unter -2145mm.
Der Messwert ist auch nach Richtungsumkehr unbrauchbar.

2. Bedienung
- über den Schiebeschalter (3 Stufen) wird ausgewählt, welche Achse bedient werden soll
- aus dem Normalbetrieb heraus ist zunächst nur die Taste "0" der Tastatur aktiv, mit dieser gelangt man ins Menü
- Das Menü besitzt 7 Menüpunkte, welche mit der "0" durchgetoggelt werden können (nach dem letzten Menüpunkt wird wieder der erste angezeigt usw.)
Im Display werden je nach Menüpunkt unterschiedliche Texte angezeigt (rudimentär soweit es halt mit einer 7-Segmentanzeige möglich ist)
- mit der Taste "*" gelangt man zurück ins Hauptmenü

Menüpunkt 1 die Digitalanzeige zeigt "nuLL"
- wird jetzt die Taste "#" gedrückt, wird die Anzeige für diese Achse genullt
- die Digitalanzeige zeigt kurz "donE"
- die Digitalanzeige ist wieder in der Hauptmenüebene

Menüpunkt 2 die Digitalanzeige zeigt "PrESEt"
- wird jetzt die Taste "#" gedrückt, kann man einen beliebigen Wert voreinstellen (mit 1μm Genauigkeit)
- mit der Taste "*" wird das Vorzeichen getauscht
- die Ziffern sind eben die Ziffern
- Fehleingaben werden durch "Error" angezeigt und ignoriert (Wert zu groß/klein)
- mit "#" wird die Eingabe abgeschlossen
- die Digitalanzeige zeigt kurz "donE"
- die Digitalanzeige ist wieder in der Hauptmenüebene

Menüpunkt 3 die Digitalanzeige zeigt "diA on"
- wird jetzt die Taste "#" gedrückt, wird die eingestellte Schrittweite des Encoders verdoppelt (diA = Diameter = Durchmesser)
- Diese Funktion ist eigentlich nur für die Stichachse einer Drehbank sinnvoll.
- (z.B. bei einen Fahrweg von 1mm verringert den Bauteildurchmesser um 2mm ... usw.)
- die Digitalanzeige zeigt kurz "donE"
- Die Einstellung wird im EEProm gespeichert und bleibt so auch nach Ausschalten erhalten!!!
- die Digitalanzeige ist wieder in der Hauptmenüebene

Menüpunkt 4 die Digitalanzeige zeigt "diA oFF"
- wird jetzt die Taste "#" gedrückt, wird die einfache eingestellte Schrittweite des Encoders verwendet
- die Digitalanzeige zeigt kurz "donE"
- Die Einstellung wird im EEProm gespeichert und bleibt so auch nach Ausschalten erhalten!!!
- die Digitalanzeige ist wieder in der Hauptmenüebene

Menüpunkt 5 die Digitalanzeige zeigt "StEP SEt"
- wird jetzt die Taste "#" gedrückt, wird die Schrittweite des Encoders eingestellt (in nm -> ja nano!!!)
Das ist die wichtigste Einstellung an der ganzen die Digitalanzeige.
Diese Schrittweite gibt an, was eine Flanke des Encoders an Weg entspricht
(mit einem Trick kann man den Wert mittels der Digitalanzeige selbst ermitteln -> kommt später)
Fehleingaben werden durch "Error" angezeigt und ignoriert (Wert zu groß/klein)
Der Wert ist immer positiv
- Die Ziffern sind wieder die Ziffern
- mit "#" wird die Eingabe abgeschlossen
- die Digitalanzeige zeigt kurz "donE"
- Die Einstellung wird im EEProm gespeichert und bleibt so auch nach Ausschalten erhalten!!!
- die Digitalanzeige ist wieder in der Hauptmenüebene

Menüpunkt 6 die Digitalanzeige zeigt "StEP UP"
- wird jetzt die Taste "#" gedrückt, kann die Zählrichtung der die Digitalanzeige verändert werden
- was hier welcher Logik entspricht hängt auch davon ab, wo welcher Encoderkanal an der Platine angeschlossen ist.
- Sagen wir mal: beim Drehen des Enoders im Urzeigersinn zählt die Anzeige jetzt vorwärts -> entgegen rückwärts
- die Digitalanzeige zeigt kurz "donE"
- Die Einstellung wird im EEProm gespeichert und bleibt so auch nach Ausschalten erhalten!!!
- die Digitalanzeige ist wieder in der Hauptmenüebene

Menüpunkt 7 die Digitalanzeige zeigt "StEP dn"
- wird jetzt die Taste "#" gedrückt, kann die Zählrichtung der die Digitalanzeige verändert werden
- was hier welcher Logik entspricht hängt auch davon ab, wo welcher Encoderkanal an der Platine angeschlossen ist.
- Sagen wir mal: beim Drehen des Enoders im Urzeigersinn zählt die Anzeige jetzt rückwärts -> entgegen vorwärts
- die Digitalanzeige zeigt kurz "donE"
- Die Einstellung wird im EEProm gespeichert und bleibt so auch nach Ausschalten erhalten!!!
- die Digitalanzeige ist wieder in der Hauptmenüebene

3. Ermittlung und Einstellung der Encoderschrittweite
- folgende Schritte sind für jede Achse einzeln durchzuführen
- sicherstellen, dass "diA oFF" ausgewählt ist
- im Menü Stepset den Wert 1000 Einstellen (1000nm)
- den toten Gang für eine Richtung aus der Maschine fahren
- Anzeige nullen
- einen längeren (ganz genau bekannten) Weg in die gleiche Richtung fahren (10cm Lehre ?! je weiter desto besser)
- die Digitalanzeige zeigt jetzt die Schitte an, die für diesen Weg nötig waren.
Rechnen:
"ganz genau bekannter Weg" / Anzeigewert = Weite pro Schritt
Weite pro Schritt in nm umrechnen und bei "StEP SEt" einstellen -> fertig