-
        

Ergebnis 1 bis 8 von 8

Thema: Geschwindigkeitsmessung via 2 Lichtschranken

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    24.06.2008
    Beiträge
    158

    Geschwindigkeitsmessung via 2 Lichtschranken

    Anzeige

    Hallo!

    Bin gerade dabei eine Geschwindigkeitsmessung für Luftgewehre etc aufzubauen. Soweit so gut, ich habe nun 2 Lichtschranken im Abstand von 6cm aufgebaut. Der Mikrocontroller (Atmega8 ) soll die Zeit in us messen und die Geschwindigkeit in m/s auf einem Display wiedergeben.
    Mein Aufbau funktioniert ganz gut, nur bei der Programmierung sitzt warscheinlich ein Fehler...
    Denn bei einem ersten richtigen Test wo die Projektilgeschwindigkeit knappe 20m/s betrug zeigt er mir etwa 150m/s an .

    Zur Funktion:
    Das Projektil passiert Lichtschranke 1 und setzt Variable X = 1. Bei jedem Interrupt des Timers wird Y erhöht, solange bis Lichtschranke 2 unterbrochen und X auf 0 gesetzt wurde. Folglich wird die Geschwindigkeit ausgerechnet und auf dem Display für 30ms angezeigt. Durch den Timer ist es aber wesentlich länger als 30ms...
    Die ADC-Werte von Licht1, Licht2, Licht3 und Licht4 werden verglichen damit X erst ab einem Wert unter 1022 verändert wird.

    Das ganze wurde mit Bascom programmiert:

    $regfile = "m8def.dat"
    $crystal = 8000000
    $hwstack = 100
    $swstack = 100
    $framesize = 100

    Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , _
    Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
    Config Lcd = 16 * 2

    Config Adc = Single , Prescaler = Auto , Reference = Avcc
    Start Adc

    Config Timer1 = Timer , Prescale = 8
    Enable Timer1
    On Timer1 Takt
    Enable Interrupts
    Timer1 = 65534

    Dim Licht1 As Integer
    Dim Licht2 As Integer
    Dim Licht3 As Integer
    Dim Licht4 As Integer

    Dim X As Bit
    Dim Y As Word
    Config Single = Scientific , Digits = 4
    Dim Geschwindigkeit As Single

    Licht3 = Getadc(4)
    Licht4 = Getadc(5)

    Cls

    Do
    Licht1 = Getadc(4) + 2
    If Licht1 < Licht3 Then X = 0

    Licht2 = Getadc(5) + 2
    If Licht2 < Licht4 Then X = 1

    If X = 0 And Y > 0 Then
    Geschwindigkeit = 60000 / Y
    Locate 2 , 2
    Lcd Geschwindigkeit ; "m/S"
    Y = 0
    Waitms 30
    Cls
    End If
    Loop
    End

    Takt:
    Timer1 = 65534
    If X = 1 Then Incr Y
    Return
    Durch den Timer verlangsamt sich die Ausgabe auf dem Display extrem....könnte man da was machen?
    Findet ihr einen Fehler bzw einen Verbesserungsvorschlag?
    Wieso stimmt die Ausgabe auf dem Display nicht?

    Vielen Dank im vorraus!
    Gruß

    D35troy3r

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied Avatar von masasibe
    Registriert seit
    21.01.2011
    Beiträge
    181
    Hallo,
    ähm könnte es sein, dass das Problem auftritt, weil du den Timer immer von 65534 wegzählen lässt. Dann muss der Timer ja nach 2 durch den Prescaler geteilten Takten einen Interrupt auslösen. Ich glaube, Bascom kann da keinen so effektiven Maschinencode generieren. Und wenn der Timer etwas langsamer tickt würde das die zu hohe angezeigte Geschwindigkeit erklären.

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    24.06.2008
    Beiträge
    158
    Ich hab den Wert mal auf 65535 geändert, nun sollte er einen Durchlauf wie gewünscht haben. Die Geschwindigkeiten die angezeigt werden liegen jetzt endlich nichtmehr bei 120m/s sondern viel niedriger bei 5,8m/s.
    In Wirklichkeit sind es aberrund 16m/s....
    Am Atmega ist noch kein Quarz oder ähnliches angeschlossen (kommt noch), ich benutze also den internen RC-Oszi. Doch der hat doch nicht eine solch riesige Toleranz das es 10m/s unterschied ergibt?

  4. #4
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Von der Hardware-anbindung ist schon mal die Auswertung über den AD ein Problem: Der ADC ist relativ langsam. Schon da hat man ein Unsicherheit von vielleicht 0,1 ms - eventuell auch noch mehr. Bei einer gesamten Zeit von rund 3 ms ist das schon reichlich. Wenn die Lichtschranken das hergeben würde ich die Signal lieber Digital auswerten, also über Pina. Wenn es weiter mit dem ADC sein soll, kann man vermutlich die geschwindigkeit des AD-Taktes etwas höher wählen, z.B. ein Teiler von 16 oder gar 8.

    Die Schleife ist auch recht lang und fragt alles mögliche ab - da kann man lieber 2 Schleifen haben: eine zum Warten auf Start und eine zum Warten aus Stop. Mehr sollte in den Schleifen nicht drin sein.

    Die Zeitmessung sollte man auch nicht mit der ISR machen, sondern einfach den Timer das hochzählen überlassen. Man startet den Timer, wenn man die Startbedingung erkannt hat, und ließt dann beim Stop den Timer aus. So wie eingestellt zählt der Timer µs - das reicht also schon bis 65 ms oder für eine Geschwindigkeit bis 1 m/s runter. So wie das Programm jetzt ist braucht die ISR viel zu lange, und es kommt schon längst der Nächste Interrupt, bis die ISR fertig ist. Der µC macht dann einmal die 1 ISR (ca. 50-80 ASM Befehle) und dann einen ASM Befehl des Programm. Entsprechend läuft das Programm nur mit etwa 1-3 Prozent der normalen Geschwindigkeit.

    Die genauste Lösung wäre die Benutzung der ICP Funktion - da muss dann aber das Signal der Lichtschranke mitspielen.

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied Avatar von masasibe
    Registriert seit
    21.01.2011
    Beiträge
    181
    Du hast beim Bascom ja eine Taktfrequenz von 8MHz eingestellt (Das hat zwar auf den Timer keine direkte Auwirkung) aber bei den ATmegas ist glaube ich standardmäßig der interne Taktteiler aktiviert, somit hätte der ATmega nur einen Takt von 1Mhz und wenn du aber für die Berechnung des Timers von 8Mhz ausgegangen bist ist das Ergebnis natürlich nicht richtig.

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    24.06.2008
    Beiträge
    158
    Das Programm sieht nun folgendermaßen aus:
    $regfile = "m8def.dat"
    $crystal = 8000000
    $hwstack = 100
    $swstack = 100
    $framesize = 100

    Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , _
    Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
    Config Lcd = 16 * 2

    Config Timer1 = Timer , Prescale = 8

    Config Pinc.5 = Input
    Config Pinc.4 = Input

    Config Single = Scientific , Digits = 4
    Dim Geschwindigkeit As Single

    Cls

    Do
    If Pinc.5 = 0 Then
    Enable Timer1
    Exit Do
    End If
    Loop

    Do
    If Pinc.4 = 0 Then
    Disable Timer1
    Exit Do
    End If
    Loop

    Cls

    Locate 1 , 1
    Lcd Timer1
    Geschwindigkeit = 60000 / Timer1
    Locate 2 , 2
    Lcd Geschwindigkeit ; "m/S"

    End
    Ich lasse mir gerade die gemessene Zeit und die Geschwindigkeit anzeigen.
    Funktioniert ganz gut bis jetzt...doch die Rechnung haut nicht ganz hin?! Ein beispiel: auf dem Display steht 5401us aber eine eine Geschwindigkeit von 5,6m/s lol...

    Das verwirrt mich jetzt etwas -.-

    Taktteiler ist aus bei meinem Atmega


    P.s: gut Problem mit den Berechnungen behoben...Timer1 musste ich in eine variable packen..erst dann waren die Ergebnisse richtig. Ich teste mal weiter
    Geändert von D35troy3r (28.01.2012 um 15:19 Uhr)

  7. #7
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die Befehle Enable Timer und Disable Timer steuern nur die Erzeugung von Interrupts - der Timer läuft trotzdem weiter. Ob Bascom da extra Befehle zum Starten und anhalten des Timers hat, weiss ich nicht. Es geht aber auch beim Start einfach mit Timer1= 0 den Wert zurückzusetzen. Am Ende ließt man den Timer dann einmal aus und speichert die Zahl in einer Variable.

    Damit wäre auch schon mal geklärt, wieso man nicht direkt mit der Größe Timer rechnen kann.

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    24.06.2008
    Beiträge
    158
    Ich danke dir! Jetzt funktionierts auch richtig
    Bis 30m/s hab ich eben gemessen...werde mir mal morgen das Luftgewehr suchen und damit eine Messung durchführen
    Ich hoffe das es messbar ist da ichs ja nun nurnoch über einen digitalen port machen.

    Hier noch der Code falls das Thema jemand aufsucht:

    $regfile = "m8def.dat"
    $crystal = 8000000
    $hwstack = 100
    $swstack = 100
    $framesize = 100

    Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 , Db6 = Portd.6 , _
    Db7 = Portd.7 , E = Portd.3 , Rs = Portd.2
    Config Lcd = 16 * 2

    Config Timer1 = Timer , Prescale = 8


    Config Pinc.5 = Input
    Config Pinc.4 = Input

    Config Single = Scientific , Digits = 4
    Dim Geschwindigkeit As Single
    Dim Y As Word
    Cls

    Do
    If Pinc.5 = 0 Then
    Timer1 = 0
    Exit Do
    End If
    Loop

    Do
    If Pinc.4 = 0 Then
    Y = Timer1
    Exit Do
    End If
    Loop

    Cls
    Locate 1 , 1
    Lcd Y
    Geschwindigkeit = 60000 / Y
    Locate 2 , 2
    Lcd Geschwindigkeit ; "m/S"

    End

Ähnliche Themen

  1. Geschwindigkeitsmessung mit 2 Lichtschranken
    Von Zwerwelfliescher im Forum Elektronik
    Antworten: 9
    Letzter Beitrag: 15.01.2012, 22:31
  2. ADC und Lichtschranken
    Von zappel76 im Forum Sensoren / Sensorik
    Antworten: 12
    Letzter Beitrag: 19.08.2010, 21:12
  3. Lichtschranken
    Von Veljko im Forum Sensoren / Sensorik
    Antworten: 6
    Letzter Beitrag: 25.05.2007, 08:15
  4. Lichtschranken Verriegelung
    Von Laguna im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 20.12.2006, 09:45
  5. Lichtschranken und 5V
    Von Vaterssohn im Forum Elektronik
    Antworten: 11
    Letzter Beitrag: 30.07.2005, 22:22

Berechtigungen

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