-         

Seite 1 von 5 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 42

Thema: Zielscheibensystem mit Zufall

  1. #1
    DjEKI
    Gast

    Zielscheibensystem mit Zufall

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    Moin,

    Ich hatte damals etwas Hilfe bekommen von jemandem, der sich mit Bascom auskennt und leider ist er jetzt sehr schwer zu erreichen, oder hat anschein keine Lust mehr ^^ Ich wollte das jetzt mal allein versuchen, aber mit etwas Hilfe von Euch.

    Ich habe erst vor kurzem den AVR- Einstieg leicht gemacht durchgearbeitet und ein paar Befehle in Basecom Language Reference angeschaut. Ich will nur damit sagen, dass ich ziehmlich neu bin in solchen Sachen, aber mich schon mal darauf vorbereitet habe.

    Mein Projekt ist ein Zielscheibensystem, dass automatisch aufleuchtet und während dessen getroffen werden kann, und danach eine andere Zielscheibe leuchtet. Alles soll mit Punkten bewertet werden. Natürlich soll dann eine Digitale Zahl zu sehen sein in typisch Roter leuchender Schrift.

    Klicke auf die Grafik für eine größere Ansicht

Name:	Zielscheibensystem.jpg
Hits:	45
Größe:	89,8 KB
ID:	24487

    Jetzt steh ich da mit einen Script von jemand anderem, den ich sogar zum Teil verstehe, aber irgendwie nicht so funktioniert wie vorgesehen.

    Dieser Script gehört zum ATtiny2313 auf dem ATMEL Evaluations-Board Version 2.0.1
    Code:
    $regfile = "m8def.dat"
    $crystal = 8000000
    
    
    '***********************************************************************'
    
    Config Adc = Single , Prescaler = Auto , Reference = Avcc
    Start Adc
    
    
    Dim Scheibe As Integer
    
    
    Config Portd.0 = Output
    Config Portd.1 = Output
    Config Portd.2 = Output
    Config Portd.3 = Output
    Config Portd.4 = Output
    
    
    Do
    
    If Scheibe > 204 Then
    Portd.0 = 1
    Else
    Portd.0 = 0
    End If
    If Scheibe > 408 Then
    Portd.1 = 1
    Portd.0 = 0
    Else
    Portd.1 = 0
    End If
    If Scheibe > 611 Then
    Portd.2 = 1
    Portd.1 = 0
    Portd.0 = 0
    Else
    Portd.2 = 0
    End If
    If Scheibe > 615 Then
    Portd.3 = 1
    Portd.2 = 0
    Portd.1 = 0
    Portd.0 = 0
    Else
    Portd.3 = 0
    End If
    If Scheibe > 819 Then
    Portd.4 = 1
    Portd.3 = 0
    Portd.2 = 0
    Portd.1 = 0
    Portd.0 = 0
    Else
    Portd.4 = 0
    End If
    
    Loop
    End
    '*************************************************************************
    
    Config Int0 = Rising
    Enable Int0
    On Int0 On_int0
    
    
    
    
     On_int0:
    
      Scheibe = Getadc(0)
    
     Return
    
    '
    Wir wollten das ADC ausnutzen.
    Er sagte da nur, alle Scheiben müssten an den INT0 Pin angelegt werden und die LEDs an die anderen Pins. Nur scheint mir das etwas unlogisch zu sein und wollte euch mal fragen, wie ich das weiter machen könnte.

    Ich möchte aber jetzt ein ATmega32 16PU 1218 verwenden und habe den Code umgeschrieben mit erstmal 3 Zielscheiben.
    Code:
    $regfile = "m8def.dat"
    $crystal = 8000000
    
    
    '***********************************************************************'
    
    Config Adc = Single , Prescaler = Auto , Reference = Avcc
    Start Adc
    
    
    Dim Scheibe As Integer
    
    
    Config Portd.0 = Output
    Config Portd.5 = Output
    Config Portd.6 = Output
    
    
    
    Do
    
    If Scheibe > 204 Then
    Portd.0 = 1
    Else
    Portd.0 = 0
    End If
    If Scheibe > 408 Then
    Portd.5 = 1
    Portd.0 = 0
    Else
    Portd.5 = 0
    End If
    If Scheibe > 611 Then
    Portd.6 = 1
    Portd.5 = 0
    Portd.0 = 0
    Else
    Portd.6 = 0
    End If
    
    
    Loop
    End
    '*************************************************************************
    
    Config Int0 = Rising
    Enable Int0
    On Int0 On_int0
    
    
    
    
     On_int0:
    
      Scheibe = Getadc(0)
    
     Return
    
    '
    Könntet Ihr mir bitte weiter helfen?
    Bis jetzt leuchtet keine LED

    mfg EKI
    Geändert von DjEKI (10.02.2013 um 18:07 Uhr)

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    705
    Als erstes solltest Du das Projekt mal so beschreiben, dass man wenigstens ansatzweise eine grobe Idee davon bekommen kann, worum es geht.

    Mein Projekt ist ein Zielscheibensystem, dass automatisch aufleuchtet und während dessen getroffen werden kann
    Von was wird es denn getroffen? Kugeln, Farbbeutel, Laserstrahlen? Was für Sensoren registrieren den Treffer? Was für Signale müssen ausgewertet werden?

    Und dann sehe ich auf den ersten Blick drei Bugs in Deinem Code:

    Erstens muss die Konfiguration des Interrupts VOR die Do-Loop-Schleife! Wenn sie dahinter steht, wird sie niemals ausgeführt - und somit gibt´s auch keinen Interrupt!

    Zweitens müssen die Interrupts auch global freigegeben werden, damit der einzelne Interrupt auch tatsächlich ausgeführt werden kann. D.h. als letzter Befehl der Interrupt-Konfiguration muss noch ein "Enable Interrupts" dazu.

    Drittens kann die Abfrage der Variablen Scheibe so wohl nicht funktionieren (auch wenn ich nicht verstehe, welche Bedeutung dieser Parameter hat).
    Stell Dir mal vor, der Wert wäre z.B. 820. Dann wären doch alle Bedingungen der einzelnen IF-Abfrage erfüllt:
    Scheibe > 204 ist wahr, d.h. PORTD.0 wird auf 1 gesetzt.
    Scheibe > 408 ist auch wahr, d.h. PORTD.1 wird auf 1 gesetzt, PORTD.0 wieder auf 0.
    Scheibe > 611 ist auch wahr, d.h. PORTD.2 wird auf 1 gesetzt, PORTD.1 wieder auf 0
    (usw)

    Du musst also schon den Bereich definieren, in dem der Wert liegen soll. Z.B. so:

    Code:
    If Scheibe > 204 AND Scheibe <= 408 then
    ...
    Else
    ...
    End if
    Oder Du nimmst den schönen Select Case-Befehl:

    Code:
    Select Case Scheibe
    
    Case 205 to 408:
    PORTD.2=0
    PORTD.1=0
    PORTD.0=1
    
    Case 409 to 610:
    PORTD.2=0
    PORTD.1=1
    PORTD.0=0
    
    Case is > 611:
    PORTD.2=1
    PORTD.1=0
    PORTD.0=0
    
    End select
    Im Übrigen gibt´s auch ein paar Methoden, um beliebig viele Bits eines Bytes (also z.B. PORTD-Ausgänge) mit wenigen Befehlen auf den gewünschten Wert zu setzen. Wenn Du jeden einzelnen Ausgang einzeln auf 1 oder 0 setzt, verbraucht das ´ne Menge Code.

    Die einfachste Lösung ist die, gleich das ganze PORTD-Byte zu setzen. Soll z.B. NUR D.4 1 sein, ginge das so:

    PORTD = &B00010000

    (&B signalisiert an Bascom, dass jetzt ´ne Binär-Zahl kommt. Das höchstwertige Bit (also PORTD.7) steht hierbei links, PORTD.0 ganz rechts)

    Damit beeinflusst Du natürlich aber auch diejenigen Bits vom PORTD-Byte, die nicht direkt mit den Zielscheiben zu tun haben, also PORTD.7 und D.6. Wenn diese Ausgänge keine Funktion haben, wäre das kein Problem, ansonsten könnte man das elegant mit AND- und OR-Funktionen lösen .

    Aber das vielleicht später??

  3. #3
    DjEKI
    Gast
    Ja, es sind Druckplatten die ich selber herstelle und es werden Plastikkugeln geschossen. (softair)
    Also praktisch ein Taster. In der Mitte gibt es 10 Punkte und Außen 5 Punkte. Eine Zielscheibe bleibt ca 2 Sekunden aktiv die dann getroffen werden muss. Danach passiert 2 Sekunden nichts, und dann leuchtet die andere Zielscheibe auf.

    Ich habe auch sehr viele Ideen wie ich das alles perfektionieren könnte, aber das sind dann wieder sachen die mir etwas zu Hoch sind und erstmal das einfachste zu schreiben. Später kann man das alles verbessern.

    Mit Punkt 1, ja, das kam mir auch Spanisch vor. Denn ich kenn mich mit PHP Sprache aus, und da ist es genauso.
    Mit Punkt 2, dass muss ich mir mal irgendwie genauer anschaun, aber heute nicht. Denn die Interrupts habe ich durchgelesen, aber überhaubt nicht verstanden was die zu tun haben.
    Mit Punkt 3, als ich mir die Bibliothek durchgelesen habe, ist mir das auch aufgefallen, dass logischerweise mehr als nur einer leuchten würde.

    Ich glaube, daher hab ich keine Antwort mehr von dem jenigen gehört, der diesen Script geschrieben hat ^^

    Besser ich bleibe bei den standard codes, denn PORTD = &B00010000 würde mir jetzt auf der Schnelle nix sagen ^^ Und dann sehe ich nacher gar nicht mehr durch.

    Mir ist auch wichtig, dass das Zufallsprinzip funktioniert. Mir ist es egal, ob esein echter Zufall ist oder nicht, hauptsache, es ist ein zufall Aber ich habe nur lesen können, dass ADC für sowas ideal wäre, aber wie man den Code schreibt, habe ich nichts brauchbare gefunden.

    Danke für den Hinweis mit dem Select, das werde ich morgen mal ausprobieren.

  4. #4
    Erfahrener Benutzer Roboter Genie Avatar von HeXPloreR
    Registriert seit
    08.07.2008
    Ort
    24558
    Alter
    39
    Beiträge
    1.356
    ...und viertens: Ist das erste Script nicht für einen ATtiny2313, sowie das zweite nicht für einen ATmega32 ist - obwohl schon umgschrieben wurde

    Viele Grüße
    "Es ist schwierig, jemanden dazu zu bringen, etwas zu verstehen, wenn er sein Gehalt dafür bekommt, dass er es nicht versteht" [Upton Sinclair] gez-boykott

  5. #5
    DjEKI
    Gast
    ui, da müsstest mich mal bitte aufklären. Die Ports sind jedenfals richtig.

    mfg EKI

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    705
    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.

  7. #7
    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

  8. #8
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    705
    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!

  9. #9
    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

  10. #10
    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'

Seite 1 von 5 123 ... LetzteLetzte

Ä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, 14:43
  2. Wie denn "Zufall" programmieren
    Von Cybrix im Forum C - Programmierung (GCC u.a.)
    Antworten: 16
    Letzter Beitrag: 11.06.2007, 10:10
  3. Zufall wirklich Zufall ???
    Von Speed im Forum Software, Algorithmen und KI
    Antworten: 3
    Letzter Beitrag: 03.08.2006, 13:03
  4. LED´s per Zufall leuchten lassen
    Von Hoomer im Forum Elektronik
    Antworten: 11
    Letzter Beitrag: 05.02.2006, 15:45

Berechtigungen

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