- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 10 von 42

Thema: Zielscheibensystem mit Zufall

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    706
    Ich glaube, daher hab ich keine Antwort mehr von dem jenigen gehört, der diesen Script geschrieben hat
    Na ja, hier wirst Du auch geholfen

    Ein Interrupt ist ein Ereignis, das den normalen Ablauf des Programmes unterbricht, damit eine bestimmte, verknüpfte Aktion ausgeführt werden kann. Dieses Ereignis kann z.B. eine fallende Flanke an einem Interrupt-Eingang sein.

    Wenn Du also z.B. möchtest, dass beim Schließen eines Tasters eine bestimmte Punktzahl addiert werden soll, könntest Du natürlich permanent die Taster abfragen. Da der Kontakt ja aber wahrscheinlich nur ziemlich kurz von der Kugel geschlossen wird könnte es passieren, dass der Abfrage ein kurzer Kontaktschluss quasi entgeht.

    Mit einem Interrupt geht´s aber einfacher und zuverlässiger: Sobald der Eingang einen Übergang von High auf Low detektiert (d.h. der Taster geschlossen wurde) wird das Hauptprogramm unterbrochen, und die dazugehörige Interrupt-Routine (auch ISR genannt) ausfgeführt. Ist sie abgearbeitet, geht´s an der Stelle im Hauptprogramm weiter, wo es kurz vorher unterbrochen wurde.

    Man muss dem Controller also erstmal sagen, was das auslösende Ereignis sein soll:
    Config INT0 = Risisng

    Der Taster muss also auf den Anschluss des Interrupts INT0 gelegt werden (beim Mega32 wäre das Pin Nr. 16 bzw. PD2), und ausgelöst wird der Interrupt bei einer steigenden Flanke (rising). Alternativ könnte man auch falling oder change nehmen - dann würde eine fallende Flanke bzw. jede Flanke den Interrupt auslösen.

    Dann muss man der auszuführenden Interrupt-Routine einen Namen geben (beliebig, müssen keiner Syntax entsprechen):
    On Int0 on_int0

    Im Klartext: Wenn das Interrupt-Ereignis eintritt, gehe nach on_int0. Etwas verwirrend ist hier, dass der Codeschreiber den Bascom-Befehl gleichzeitig auch als Namen für die ISR verwendet hat. Man könnte genausogut schreiben
    On Int0 5Punkte oder On Int0 10Punkte

    Dann muss der Interrupt aktiviert werden:
    Enable INT0

    Beim Einschalten des Controllers sind nämlich alle Interrupts erstmal deaktiviert - mit enable aktiviert man den einzelnen Interrupt.

    Und die "globale" Freigabe ist auch notwendig:
    Enable Interrupts

    Damit hat es folgendes auf sich: manchmal kann es ja sehr wichtig sein, dass das Hauptprogramm mal für eine Zeit NICHT von Interrupts unterbrochen wird. Damit man in diesem Fall nicht alle Interrupts einzeln deaktivieren muss (bei größeren Controllern können das schon mal 20 Stück sein), gibt es sozusagen eine Art "Hauptschalter" für alle Interrupts - die globale Aktivierung bzw. Deaktivierung.
    Und auch dieser "Schalter" steht erstmal auf aus, wenn der Controller hochfährt. Deshalb muss man die globale Interrupt-Freigabe auch noch ausführen.

    Das mit den Zufallszahlen ist nicht so ganz einfach - darüber wurde hier kürzlich schon eine Menge gepostet. Man könnte aber z.B. aus der Zeit zwischen zwei Schüssen eine Art Zufallszahl ableiten, denn da reichen schon Unterschiede von ein paar Millionstel Sekunden aus, um komplett andere Zahlen zu produzieren.

  2. #2
    DjEKI
    Gast
    Das mit den Interrupts habe ich warscheinlich verstanden. Aber mit der Globale Freigabe ist mir noch etwas Fragwürdig. Also, wenn ich ein Schalter aktiviere der auf Int0 oder Int1 liegt, dann wird automatisch das Programm unterbrochen. Wenn ein Programm unterbrochen wurde, was läuft dann ? Irgendwie muss doch was weiter gehen. Oder ist es so, so lange wie ich auf den Taster drücke, wird auch das Programm unterbrochen?

    also, würde es mit den ADC als Zufall nicht so einfach funktionieren.
    An solche Zahlenrotation habe ich schon gedacht, dass die Zahlen als Variabel sehr schnell rotieren und die Zeitverzögerung als Zufall zu nutzen. Da der Script aber nur in einer Richtung ausgeführt werden kann, wird das doch ohne einen 2. Chip gar nicht möglich, oder?

    mfg EKI

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    706
    Wen ein Interrupt-Eeignis auftritt (also z.B. die steigende Flanke am Eingang D2 bzw. INT0) passiert folgendes:
    1. alle Register-Inhalte werden gesichert
    2. das Hauptprogramm bleibt an der Stelle stehen, an der es gerade ist
    3. die Interrupt-Routine wird ausgeführt (und weil sie das Programm tatsächlich unterbricht, sollte sie so kurz wie möglich sein!!)
    4. nach Abarbeiten der Interrupt-Routine werden alle "gerretteten" Register-Inhalte wieder zurückkgeschrieben, und
    5. das Hauptprogramm an der Stelle fortgeführt, an der es unterbrochen wurde

    Wie gesagt - es gibt haufenweise Ereignisse, die einen Interrupt auslösen können (!), z.B. wenn ein Timer seinen maximalwert erreicht und "überläuft", wenn ein AD-Wandler fertig gewandelt hat, wenn über die UART-Schnittstelle Daten reinkommen usw., usw.
    Damit das Hauptprogramm nicht alle Nase lang von diesen Interrupts unterbrochen wird, sind ALLE Interrupts erstmal AUS und müssen bei Bedarf aktiviert werden.

    Du kannst das mit ´nem Sicherungskasten eines Hauses vergleichen (nur mit dem Unterschied, dass der Normalzustand dort "Ein" ist):
    Wenn Du einzelne Zimmer stromlos machen möchtest um z.B. Lampen zu wechseln, kannst Du gezielt einzelne Sicherungen rausdrehen (entspricht dem enablen bzw. disablen einzelner Interrupts, also z.B. enable INT0).

    Wenn Du aber ganz sicher und in ALLEN Zimmern keinen Strom mehr haben möchtest, brauchst Du nicht alle 17 Einzelsicherungen rauszudrehen, sondern drehst einfach die Hauptsicherung raus. Das wäre dann das globale Ein- und Ausschalten der Interrupts (enable bzw. disable Interrupts).

    Wenn Du also einen Interrupt ausführen lassen möchtest, musst Du sowohl den Interrupt selber, als auch die globale Freigabe aktivieren.

    Und wenn die Aufgabe nur die ist, "zufällig" jeweils eine der 6 Zielscheiben zu aktivieren, für 2 Sekunden die beiden Taster zu überwachen und ggf. 5 bzw. 10 Punkte zu verbuchen, dann kann das ein einzelner Mikrocontroller alleine!

  4. #4
    DjEKI
    Gast
    Ohja, jetzt habe ich das voll verstanden, danke

    Gut, dann werde ich mich mal rann setzen und das irgendwie umsetzen. Ich mache das jetzt nicht mehr per ADC, sondern lasse halt die Zeitverzögerung entscheiden. Kann man 2 Abläufe gleichzeitig durchlaufen kassen? zB ein Hauptprogramm und den Zufallsgenerator (ein Ablauf bestimmter Zahlen mit Loop Effekt). Sonbst habe ich schon andere Ideen.

    Ansonsten muss ich noch die Variabeln kennen lernen. Dass die Punkte addiert werden.

    Und später auch die LCD anzeige (stinknormale Rote leuchtende Zahlen)

    Normalerweise habe ich mir ein Konzept gedacht, wie es wirklich Fertig aussehen sollte:
    1.er Modus: Normales schießen mit Zufall der Ziele und 2 Sekunden Aufblinkzeit. 5-10 Punkte.
    2.er Modus: schnelles schießen, Zufall der Ziele, Punkte ergeben sich durch den Zeitraum. Umso schneller man trifft, umso mehr Punkte.
    3.er Modus: Man bekommt 500 Punkte, beim Treffer werden sie abgezogen bis wirklich nur Null erreicht worden ist, die Zeit ist dann das Ergebnis

    Und? Scheint es machbar zu sein ? ^^

    mfg EKI

  5. #5
    DjEKI
    Gast

    Erstes Programm:

    Moin, mein erstes Programm ist fertig, und da stoße ich schon mal auf ein Problem.
    Erstmal will ich dazu was sagen, dass ist meine 1 Variante, die evtl durch Profis besser und kürzer geht, aber mein Wissen ist leider nur so weit wie in diesem Programm zusehen ist.
    Aber leider stoße ich da auf ein Problem. Ganz unten darf kein GOTO im Interrupt sein, aber ich hätte dort zugern eins. Nur wie Löse ich das Problem?

    Code:
    $regfile = "m8def.dat"
    $crystal = 1000000
    
    
    '***********************************************************************'
    
    
    Dim Scheibe As Integer
    Dim 5punkte As Integer
    Dim 10punkte As Integer
    Dim Punkte As Integer
    Dim A As Byte
    
    A = 0
    Scheibe = 0
    Punkte = 0
    
    
    Config Portd.0 = Output
    Config Portd.5 = Output
    Config Portd.6 = Output
    Config Int0 = Rising
    Config Int1 = Rising
    Enable Interrupts
    Enable Int0
    Enable Int1
    On Int0 Int0_5punkte
    On Int1 Int1_10punkte
    
    Anfang:
    Do
    
    If Scheibe = 1 Then
       Goto Scheibe1
    Else
       Portd.0 = 0
    End If
    
    If Scheibe = 2 Then
       Goto Scheibe2
    Else
       Portd.5 = 0
    End If
    
    If Scheibe = 3 Then
       Goto Scheibe3
    Else
       Portd.6 = 0
    End If
    
    Incr A
    Loop Until A = 20
    End                                                         'hier erscheint ein Ton und zeigt das Ende mit Ergebnis.
    
    '*************************************************************************'
    Scheibe1:
    Portd.0 = 1
    Set Scheibe = 1
    Waitms 250
    Set Scheibe = 2
    Waitms 250
    Set Scheibe = 3
    Waitms 250
    Set Scheibe = 1
    Waitms 250
    Set Scheibe = 2
    Waitms 250                                                  'wenn hier getroffen wurde, ist die variable 2, also die 2. Scheibe ist aktiv'
    Set Scheibe = 3
    Waitms 250
    Set Scheibe = 1
    Waitms 250
    Set Scheibe = 2
    Waitms 250
    Set Scheibe = 3
    Portd.0 = 0
    Goto Anfang
    
    Scheibe2:
    Portd.0 = 1
    Set Scheibe = 1
    Waitms 250
    Set Scheibe = 2
    Waitms 250
    Set Scheibe = 3
    Waitms 250
    Set Scheibe = 1
    Waitms 250
    Set Scheibe = 2
    Waitms 250
    Set Scheibe = 3
    Waitms 250
    Set Scheibe = 1
    Waitms 250
    Set Scheibe = 2
    Waitms 250
    Set Scheibe = 2
    Portd.0 = 0
    Goto Anfang
    
    Scheibe3:
    Portd.0 = 1
    Set Scheibe = 1
    Waitms 250
    Set Scheibe = 2
    Waitms 250
    Set Scheibe = 3
    Waitms 250
    Set Scheibe = 1
    Waitms 250
    Set Scheibe = 2
    Waitms 250
    Set Scheibe = 3
    Waitms 250
    Set Scheibe = 1
    Waitms 250
    Set Scheibe = 2
    Waitms 250
    Set Scheibe = 1
    Portd.0 = 0
    Goto ANFANG
    
    '*************************************************************************'
    Int0_5punkte:
    5punkte = Punkte + 5
    Goto Anfang                                                 'mein größtes Problem, der hier wäre sehr wichtig, geht aber nicht... Interrupt braucht ein Return'
    
    
    Int1_10punkte:
    10punkte = Punkte + 10
    Goto Anfang                                                 'mein größtes Problem, der hier wäre sehr wichtig, geht aber nicht... Interrupt braucht ein Return'

  6. #6
    Erfahrener Benutzer Roboter Genie Avatar von HeXPloreR
    Registriert seit
    08.07.2008
    Ort
    Soltau - Niedersachsen
    Alter
    46
    Beiträge
    1.369
    Du schreibst immer noch für einen Atmega8 - ist Dir das schon aufgefallen?

    Was soll man jetzt zu diesem Programm sagen?? - fang nochmal an oder das ist es wohl noch nicht.

    Also cih verstehe nichts von dem was Du hier codest.

    Wozu änderst Du alle 250ms den Wert von Scheibe? Da kanst Du doch auch gleich den letzten Wert im Block nehmen.
    Wofür sind die Interrups überhaupt angegeben? - Die machen doch nichts wenn ich das richtig sehe.
    A wird nicht zurückgesetzt.
    Die Scheife wird vermutlich auch schneller durchlaufen sein, als Du blinzeln kannst.


    Viele Grüße

  7. #7
    DjEKI
    Gast
    Du hattest mir keine Antwort geschrieben, warum du meinst, dass es nicht für den ATmega32 ist und hast mich schon wieder nur darauf hingewiesen, dass dieser Script nicht für den ATmega32 ist, sondern für den mega8. Könntest du mir denn jetzt bitte sagen, warum dass so ist?

    Meine Idee war, die 250ms so auf zu teilen, dass es am Ende 2 Sekunden ergibt. Und fals ein Interrupt auftreten sollte, genau in der MilliSekunde stehen bleibt, dann ist der letzte vergebene Wert für die Aktivierung der nächsten Zielscheibe.
    Dann wollte ich: Der letzte Wert am ende des Layers, hat bei Scheibe1 den Wert 3, Scheibe2 den Wert 2 und Scheib3 den Wert 1. Die sind desshalb unterschiedlich, fals man die Zielscheibe nicht getroffen hat, dann kommt die nächste Zielscheibe und nicht nochmal die Selbe.

    -EDIT-
    Ich habe sowieso eben bemergt:
    Line:58 "und" 60 Variable can not be used with SET [SCHEIBE = 1 "und" 2]

    mfg EKI
    Geändert von DjEKI (11.02.2013 um 20:04 Uhr)

Ähnliche Themen

  1. 4 Led´s unabhängig per Zufall blinken lassen?
    Von DanielSan im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 22
    Letzter Beitrag: 20.07.2011, 13:43
  2. Wie denn "Zufall" programmieren
    Von Cybrix im Forum C - Programmierung (GCC u.a.)
    Antworten: 16
    Letzter Beitrag: 11.06.2007, 09:10
  3. Zufall wirklich Zufall ???
    Von Speed im Forum Software, Algorithmen und KI
    Antworten: 3
    Letzter Beitrag: 03.08.2006, 12:03
  4. LED´s per Zufall leuchten lassen
    Von Hoomer im Forum Elektronik
    Antworten: 11
    Letzter Beitrag: 05.02.2006, 14:45

Berechtigungen

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

12V Akku bauen