-         

Ergebnis 1 bis 8 von 8

Thema: HEX Codierschalter und If-Then-Elseif

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    08.06.2011
    Ort
    Ruhrgebiet
    Alter
    28
    Beiträge
    42

    HEX Codierschalter und If-Then-Elseif

    Anzeige

    Hallo miteinander,
    mein Problem schildert sich wiefolgt. Ich habe am PortD.7-D.4 einen Hexadezimalen Codierschalter angeschlossen. Also 1-2-4-8, die C Anschlüssen liegen auf VCC.
    Benutze übrigens das RN-Control 1.4. Zur optischen Kontrolle schalte ich die Leds am PortC durch, um den Schalterzustand zu erkennen.

    Nur leider passiert rein garnichts. Habs auf vielen Wegen probiert. Nichts hat zum Erfolg geführt.

    Liegt es evtl. an der Binärschreibweise wenn ich PortD lesen will? Aber so wie ich das verstehe kommt der obere Nibble doch als erstes. Also würde PortD=&B10000000 eine 1 an PortD.7 bewirken. Das nur zum Verständnis meinerseits. Eigentlich sollte man mit PINX= ... doch auch den ganzen Port abfragen können. Oder ist die If-then-Elseif-Verzweigung Mist?

    Nach zwei Tagen ausprobieren und I-Net Recherche find ich keinen Ansatz mehr.

    Achso... Schalter ist voll funktionsfähig und gibt die richtigen Zustände an PortD aus

    Hier der Code:

    Code:
    $regfile "m32def.dat"
    $crystal = 16000000
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    
    Config Portc = Output
    Config Portd = Input
    
    
    Do
    
    
    If Pind = &B00000000 Then
    Portc = &B11111111
    
    
    Elseif Pind = &B10000000 Then
    Portc = &B11111110
    
    
    Elseif Pind = &B01000000 Then
    Portc = &B11111100
    
    
    Elseif Pind = &B11000000 Then
    Portc = &B11111000
    
    
    Elseif Pind = &B00010000 Then
    Portc = &B11110000
    
    
    Elseif Pind = &B10010000 Then
    Portc = &B11100000
    
    
    Elseif Pind = &B01010000 Then
    Portc = &B11000000
    
    End If
    
    Loop
    
    End
    Danke für die Mühe


    Gruß 128er
    Geändert von 128er (19.12.2011 um 18:24 Uhr)

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Zitat Zitat von 128er Beitrag anzeigen
    Ich habe am PortA.7-A.4 einen Hexadezimalen Codierschalter angeschlossen.
    Config Portd = Input
    Wo sind sie jetzt dran, an A oder an D?


    Zitat Zitat von 128er Beitrag anzeigen
    Eigentlich sollte man mit PINX= ... doch auch den ganzen Port abfragen können.
    Du kannst schon mit
    Elseif Pind = &B10000000 Then
    den ganzen Port abfragen, aber dann müssen auch die unbenutzten Pins auf 0 liegen.
    Wenn du also nur 4 Schalter dran hast, dann ist so zunächst einmal nicht sicher, dass sie das auch tun.
    Wenn du pulldown Widerstände nach Masse an jeden Pin machst, auch an die mit Codierschalter dran, dann sollte die Abfrage funktionieren.

  3. #3
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    27
    Beiträge
    3.517
    Blog-Einträge
    9
    Mach das doch lieber mit einer Select-Case Abfrage. Das ist bischen bequemer als die ganzen Ifs
    Schaut ruhig mal auf meiner Homepage vorbei :
    http://kampis-elektroecke.de

    Oder folge mir auf Google+:
    Daniel Kampert

    Es gibt 10 Arten von Menschen. Die einen können Binär, die anderen nicht.

    Gruß
    Daniel

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    08.06.2011
    Ort
    Ruhrgebiet
    Alter
    28
    Beiträge
    42
    Danke for_ro für den Tip. Funktioniert nun einwandfrei.

    @Campi
    Da hast du wohl recht. Wofür ich das eigentlich nutzen will, ist ein Codeschloss. Im Programm ist ein 4-Stelliger Code hinterlegt. Zum Codierschalter gibt es noch einen Taster zum bestätigen. Also wählt man die erste Codestelle am Codierschalter und bestätigt. Das gleiche für die 3 weiteren Codestellen. Die Wertigkeit der einzelnen stellen soll dann (evtl. addiert?!) verglichen werden mit dem im Programm hinterlegten Code. Wenn Eingabe und Hinterlegter Code übereinstimmen soll irgendwas geschaltet werden. Eine elektromechanische Verriegelung oder sowas.

    Habe schon versucht den hier gezeigten Code für die beschriebene Anwendung weiter zu stricken. Aufgrund fehlender Programmiererfahrung ist es aber nicht immer so einfach den passenden Lösungsansatz zu finden. Der Gedanke mit der Select Case Anweisung kam mir beim lesen allerdings auch schon.

    Bin aber weiterhin für jede Idee offen.


    Gruß 128er

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    08.06.2011
    Ort
    Ruhrgebiet
    Alter
    28
    Beiträge
    42
    So sieht das Programm nun erstmal aus. Wenns logischer, einfacher, etc. geht dann ruhig meckern
    Code:
    $regfile "m32def.dat"
    $crystal = 16000000
    $framesize = 100
    $swstack = 100
    $hwstack = 100
    
    
    Config Portd.7 = Output                                     'Ports/Pins definieren
    Config Portc = Output
    Config Porta = Input
    Config Pinb.0 = Input
    
    
    Declare Sub Stelle1                                         'Subroutinen festlegen
    Declare Sub Stelle2
    Declare Sub Stelle3
    Declare Sub Stelle4
    Declare Sub Erfolg
    
    
    Led1 Alias Portc.7                                          'Alias
    Led2 Alias Portc.6
    Led3 Alias Portc.5
    Led4 Alias Portc.4
    Taster Alias Pinb.0
    
    
    
    Do
    
    If Taster = 0 Then                                          'Erste Stelle anwählen
    Gosub Stelle1
    Else
    Toggle Portc                                                '"Startsequenz"
    Waitms 500
    Toggle Portc
    Waitms 500
    End If
    
    Loop
    
    End                                                         'end program
    
    
    Sub Stelle1
     Do
     If Pina = 128 And Taster = 0 Then
     Gosub Stelle2                                              'Sprung zur nächsten Stelle wenn Eingabe richtig und bestätigung gedrückt wurde
    Else
     Toggle Led1
      Waitms 500
      Toggle Led1
      Waitms 500
      End If
     Loop
    End Sub
    
    Sub Stelle2
     Do
      If Pina = 16 And Taster = 0 Then
      Gosub Stelle3                                             'Sprung zur nächsten Stelle wenn Eingabe richtig und bestätigung gedrückt wurde
     Else
      Toggle Led2
      Waitms 500
      Toggle Led2
      Waitms 500
      End If
     Loop
    End Sub
    
    Sub Stelle3
     Do
      If Pina = 64 And Taster = 0 Then
      Gosub Stelle4                                             'Sprung zur nächsten Stelle wenn Eingabe richtig und bestätigung gedrückt wurde
     Else
      Toggle Led3
      Waitms 500
      Toggle Led3
      Waitms 500
      End If
     Loop
    End Sub
    
    Sub Stelle4
     Do
      If Pina = 224 And Taster = 0 Then
      Gosub Erfolg                                              'Hier kann der Sprung zum entsperren bzw. freigabe oder wie auch immer geschehen
     Else
      Toggle Led4
      Waitms 500
      Toggle Led4
      Waitms 500
      End If
     Loop
    End Sub
    
    Sub Erfolg
     Sound Portd.7 , 1000 , 500
    End Sub

    Die Grundlegende Funktion ist schonmal erfüllt. Die If-Then-Elsif Sache zur Schalterabfrage hat sich als suboptimal herausgestellt. Als das Programm in den Subroutinen werkelte war die Abfrage aus der Hauptschleife wohl nicht verfügbar. Bei der angesprochenen Select-Case Methode ist bei mir noch kein Licht aufgegangen wie das richtig funktioniert.
    Manipulationssicher ist das ganze auch noch nicht. Hält man den Taster gedrückt und dreht wild am Codierschalter, springt er natürlich von Stelle zu Stelle. Außerdem wäre dann auch noch ein Zähler notwendig, der die falschen Eingaben festhält und nach Eingabe X alles sperrt.


    Gruß 128er

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Hallo 128er,
    die Logik deines ersten Codes ist so:
    If Bedingung1 then
    ...
    Elseif Bedingung2 then
    ...
    Elseif Bedingung3 then
    ...
    Elseif Bedingung4 then
    ...
    Elseif Bedingung5 then
    ...
    Elseif Bedingung6 then
    ...
    Elseif Bedingung7 then
    ...
    End If

    Das zweite sieht so aus:

    If Bedingung1 then
    if Bedingung2 then
    If Bedingung3 then
    If Bedingung 4 then
    Else
    ...
    End If
    Else
    ...
    End If
    Else
    ...
    End If
    Else
    ...
    End If

    Du erkennst sicherlich den Unterschied. Im zweiten Fall kommt er nur weiter zur nächsten Stelle, wenn die Bedingung stimmt.
    Beides scheint für deine Überprüfung nicht ganz geeignet zu sein.
    Wenn du willst, dass der Taster zwischendurch auch wieder losgelassen wird, bevor es mit der Erkennung der nächsten Stelle weitergeht, dann kannst du das über ein Bitwait erreichen. Da der Taster in Ruhestellung eine 1 gibt, wäre das dann
    Biwait Taster, Set
    Dann bleibt die Ausführung solange stehen, bis der Taster losgelassen wird. Danach käme dann ein kurzes Wait, um ein Prellen zu übergehen und dann die nächste Abfrage. Oder du benutzt gleich den Debounce Befehl.
    Mit Bitwait sähe das dann so aus:
    Code:
    Bitwait Taster, Set                                      'Taster losgelassen
    Waitms 20                                                'Prellen abwarten
    Bitwait Taster, Reset                                    'Taster gedrückt
    Stelle1 = PinA
    
    Waitms 20
    Bitwait Taster, Set                                      'Taster losgelassen
    Waitms 20
    Bitwait Taster, Reset                                    'Taster gedrückt
    Stelle2  = PinA
    
    Waitms 20
    Bitwait Taster, Set                                      'Taster  losgelassen
    Waitms 20
    Bitwait Taster, Reset                                    'Taster  gedrückt
    Stelle3  = PinA
    
    Waitms 20
    Bitwait Taster, Set                                      'Taster  losgelassen
    Waitms 20
    Bitwait Taster, Reset                                    'Taster  gedrückt
    Stelle4  = PinA
    Hältst du den Taster gedrückt passiert gar nichts. Drückst du den Taster immer wieder, wird jeweils immer wieder der Wert am Codierschalter übernommen, auch wenn der sich nicht geändert hat.
    Nach 4-maligem Drücken werden die 4 Stellen mit der Vorgabe verglichen. Wenn falsch, geht es wieder von vorne los.

    Vielleicht hilft dir das ja weiter.

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    08.06.2011
    Ort
    Ruhrgebiet
    Alter
    28
    Beiträge
    42
    Die Bitwait-Abfrage wie du sie gepostet hast funktioniert von der Sache her sehr gut. Wie könnte ich denn parallel zum Bitwait noch die Leds für die Stellen blinken lassen? Ich habe versucht es folgendermaßen zu lösen

    Code:
    Do
    
    Do
    Toggle Led1
    Waitms 500
    Toggle Led1
    Waitms 500
    Loop Until Taster =  0
    
    
    Bitwait Taster, Set                                      'Taster losgelassen
    Waitms 20
    Bitwait Taster, Reset                                    'Taster gedrückt
    Stelle1 = Pina
    
    Do
    Toggle Led2
    Waitms 500
    Toggle Led2
    Waitms 500
    Loop Until Taster = 0
    
    
    
    Bitwait Taster, Set                                      'Taster losgelassen
    Waitms 20
    Bitwait Taster, Reset                                    'Taster gedrückt
    Stelle2  = PinA
    
     Do
    Toggle Led3
    Waitms 500
    Toggle Led3
    Waitms 500
    Loop Until Taster = 0
    
    
    Bitwait Taster, Set                                      'Taster losgelassen
    Waitms 20
    Bitwait Taster, Reset                                    'Taster gedrückt
    Stelle3 = Pina
    
    
    Do
    Toggle Led4
    Waitms 500
    Toggle Led4
    Waitms 500
    Loop Until Taster = 0
    
    
    Bitwait Taster, Set                                      'Taster losgelassen
    Waitms 20
    Bitwait Taster, Reset                                    'Taster gedrückt
    Stelle4 = Pina
    
    Gosub Vergleichen
    
    Loop
    
    End
    
    Sub Vergleichen
     Do
     If Stelle1 = &B10000000 And Stelle2 = &B00010000 And Stelle3 = &B01000000 And Stelle4 = &B11100000 Then
     Gosub Erfolg
     Else
     Gosub Misserfolg
     End If
     Loop
    End Sub
    Allerdings erfordert das ja einen zweimaligen Tastendruck zur Eingabe. Da erst die Blinkschleife verlassen wird und dann Bitwait kommt. Und ein einbinden des Bitwait in die Until-Bedingung war mir nicht möglich.

    Deshalb hab ich es dann so gestaltet:
    Code:
    Do
    
    Do
    Toggle Led1
    Waitms 500
    Toggle Led1
    Waitms 500
    Loop Until Taster = 0
    
    
                                       'Taster gedrückt
    Stelle1 = Pina
    
    Do
    Toggle Led2
    Waitms 500
    Toggle Led2
    Waitms 500
    Loop Until Taster = 0
    
    
    
                                       'Taster gedrückt
    Stelle2  = PinA
    
     Do
    Toggle Led3
    Waitms 500
    Toggle Led3
    Waitms 500
    Loop Until Taster = 0
    
    
                                        'Taster gedrückt
    Stelle3 = Pina
    
    
    Do
    Toggle Led4
    Waitms 500
    Toggle Led4
    Waitms 500
    Loop Until Taster = 0
    
    
                                       'Taster gedrückt
    Stelle4 = Pina
    
    Gosub Vergleichen
    
    Loop
    
    End
    
    Sub Vergleichen
     Do
     If Stelle1 = &B10000000 And Stelle2 = &B00010000 And Stelle3 = &B01000000 And Stelle4 = &B11100000 Then
     Gosub Erfolg
     Else
     Gosub Misserfolg
     End If
     Loop
    End Sub
    Da werden bei gehaltenem Taster zwar alle Stellen beschrieben. Aber ein manipulieren ist nicht möglich.

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.112
    Eigentlich eher so:

    Code:
    Do
    
    Do
    Toggle Led1
    Waitms 500
    Toggle Led1
    Waitms 500
    Loop Until Taster =  0
    
    
    Bitwait Taster, Set                                      'Taster losgelassen         == Taster = 1
    Waitms 20
    Bitwait Taster, Reset                                    'Taster gedrückt            == Taster = 0
    Stelle1 = Pina
    
    Do
    Toggle Led2
    Waitms 500
    Toggle Led2
    Waitms 500
    Loop Until Taster = 1                                 'Taster wieder losgelassen
    
    
    
    'Bitwait Taster, Set                                      'Taster losgelassen
    'Waitms 20
    Bitwait Taster, Reset                                    'Taster gedrückt
    Stelle2  = PinA
    
     Do
    Toggle Led3
    Waitms 500
    Toggle Led3
    Waitms 500
    Loop Until Taster = 0
    
    
    'Bitwait Taster, Set                                      'Taster losgelassen
    'Waitms 20
    Bitwait Taster, Reset                                    'Taster gedrückt
    Stelle3 = Pina
    
    
    Do
    Toggle Led4
    Waitms 500
    Toggle Led4
    Waitms 500
    Loop Until Taster = 0
    
    
    'Bitwait Taster, Set                                      'Taster losgelassen
    'Waitms 20
    Bitwait Taster, Reset                                    'Taster gedrückt
    Stelle4 = Pina
    
    Gosub Vergleichen
    
    Loop
    
    End

Ähnliche Themen

  1. ELSEIF als Fehler oder bessere Lösung
    Von alecs im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 07.11.2005, 15:16

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •