- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 10 von 15

Thema: Drehzahl- und Geschwindigkeitsmessung ATMEGA88 BASCOM

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Benutzer Stammmitglied
    Registriert seit
    15.08.2013
    Ort
    Güstrow
    Beiträge
    31

    Frage Drehzahl- und Geschwindigkeitsmessung ATMEGA88 BASCOM

    Hallo an das Forum,

    Ich weiß, hier verwenden die meisten Leute C oder Assembler.
    Ich würde aber gerne weiter in Bascom Programmieren, da es VB ähnelt und ich damit beruflich zu tun habe.

    Ich würde gern für eine Fahrende Bierkiste Drehzahl und Geschwindigkeit auslesen.
    Der Bau der Geber stellt kein Problem dar. Die Zündung und die Antriebswelle sollen pro Umlauf nur ein Signal abgeben, aber ich verstehe die Funktionsweise der Timer nicht.

    Mein Plan ist den Timer1 laufen zu lassen, die Drehzahl aus der Differenz eines alten und neuen Wertes zu errechnen und bei Erreichen des Geschwindigkeitssensor den Timer auf null zu setzen.

    Der Timer läuft hoch, aber die Interrupts lösen anscheinend nicht aus

    hier der Code:
    Code:
    $regfile = "m88def.dat"
    $crystal = 16000000
    $hwstack = 40
    $swstack = 40
    $framesize = 40
    
    'Display Einrichten
    Config Lcdpin = Pin , _
           Db4 = Portb.0 , Db5 = Portd.7 , Db6 = Portd.1 , Db7 = Portd.0 , E = Portb.4 , Rs = Portb.5
    
    Config Lcd = 16 * 2
    
    Dim Drehzahl As Word
    Dim Geschwindigkeit As Word
    Dim D_timer_1 As Single
    Dim D_timer_2 As Single
    Dim G_timer As Single
    Dim Timer_multi As Single
    
    Config Pind.2 = Input                             'drehzahl
    Config Pind.3 = Input                             'Geschwindigkeit
    
    Portd.2 = 1
    Portd.3 = 1
    
    On Int0 Dreh_route
    On Int1 Gesw_route
    On Timer1 Timer_over
    
    Config Int0 = Rising
    Enable Int0
    Config Int1 = Rising
    Enable Int1
    Enable Interrupts
    
    Enable Timer1
    Start Timer1
    
    Config Timer1 = Timer , Edge = Rising , Prescale = 1024       'so niedrig, dass erlangsam zählt
    
    Timer_multi = 1
    
    Do
            Cls
            Upperline : Lcd Drehzahl ; "  " ; Geschwindigkeit
            Lowerline : Lcd D_timer_1 ; " " ; Timer1
            Waitms 20
    Loop
    
    End
    
    Dreh_route:
            D_timer_2 = Tcnt1 * Timer_multi
            If D_timer_2 > D_timer_1 Then Drehzahl = D_timer_2 - D_timer_1
            D_timer_1 = D_timer_2
    Return
    
    Gesw_route:
            G_timer = Timer1 * Timer_multi
            Geschwindigkeit = G_timer
            Timer1 = 0
            Timer_multi = 0
    Return
    
    Timer_over:
            Timer_multi = Timer_multi + 1
            If Timer_multi > 100 Then Timer_multi = 1
    Return
    
    End
    Geändert von therealosram (31.07.2014 um 23:48 Uhr)

  2. #2
    Erfahrener Benutzer Roboter Genie Avatar von Michael
    Registriert seit
    17.01.2004
    Ort
    Karlstadt
    Alter
    54
    Beiträge
    1.258
    Die Edge-Option solltest du beim Timer weglassen, wenn du ihn nicht als Counter benutzt.
    Die Berechnung der Drehzahl sieht mir auch nicht gut aus. Hier willst du den Timerwert erfassen (Periodendauer) und daraus den Kehrwert errechnen (Frequenz = Drehzahl) Der Überlauf kommt nur, wenn die Drehzahl zu niedrig ist.

    Gruß, Michael

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    15.08.2013
    Ort
    Güstrow
    Beiträge
    31
    Nochmals hallo an das Forum.

    Ich verzweifel hier echt und versteht die Timer irgendwie nicht. Auch die verschiedenen Tutorials zu den Timer raff ich nicht. Vielleicht denk ich auch nicht genug um die Ecke.

    Ich möchte nur gleichzeitig die Drehzahl von Motor 500-8000 (0,002-0,000125sec/puls) und der Achse 1-20 (1-0,05sec/puls) auslesen.
    Nehm ich dann alle drei Timer und lasse einen bis zum Überlauf zählen und zähle dann die anderen zusammen?
    Zu was würdet ihr mir raten, unabhängig in welcher Sprache ihr arbeitet. Ich möchte nur das System verstehen.

    Grüße

  4. #4
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die Drehzahlen werden üblicherweise in Umdrehungen pro Minute angegeben, je Sekunde ist das dann nur 1/60 der Umdrehungen bzw. Pulse. Ggf. kann aber der Aufnehmer mehr als 1 Puls je Umdrehung geben.

    Der Übliche weg ist es einen Timer durchlaufen zu lassen, und dann jeweils die Zeiten auszulesen und die Differenzen zu bilden. Den Timer sollte man dabei nicht zurücksetzen, sondern besser den Überlauf richtig berücksichtigen - das ist nicht so schwer, aber ggf. je nach Compiler / Sprache etwas verschieden. Wie das in C geht sieht man etwa in Wissens Artikel unter Timer(AVR) - Input Capture. Wegen der recht verschiedenen Drehzahlen wird bei nur einem 16 Bit timer die Auflösung für die hohe Drehzahl eher klein. Da wäre es schon hilfreich die Auflösung des Timers in Software zu erweitern (zählen der Überläufe) oder ggf. alternativ die Zeit für mehr als 1 Periode zu Messen.

    Wenn der µC 2 16 Bit Timer hätte, könnte man auch je Drehzahl einen Timer nutzen und so ohne die Erweiterung der Auflösung auskommen. Ein 8 bit Timer hilft aber nicht weiter, denn da kann man auch gleich den 16 Bit timer auf 32 Bit erweitern und damit alle erledigen.

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    15.08.2013
    Ort
    Güstrow
    Beiträge
    31
    Hier jetzt mal der aktuelle Code.

    Code:
    $regfile = "m88def.dat"
    $prog &HFF , &HE2 , &HDF , &HF9                   ' generated. Take care that the chip supports all fuse bytes.
    $hwstack = 128
    $framesize = 128
    $swstack = 128
    
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portd.0 , _
           Db7 = Portd.1 , E = Portb.4 , Rs = Portb.5
    Config Lcd = 16 * 2
    Cursor Off
    
    Config Timer1 = Timer , Prescale = 64
    
    Config Int0 = Falling
    Config Int1 = Falling
    
    On Int0 Ges                                       'Geschwindigkeit
    On Int1 Dre                                       'Drehzahl
    On Timer1 Timer_irq
    
    Enable Int0
    Enable Int1
    Enable Timer1
    
    Config Sda = Portc.4
    Config Scl = Portc.5
    Config Portd.2 = Input
    Config Portd.3 = Input
    Config Portd.0 = Output
    
    Pind.2 = 1
    Pind.3 = 1
    
    Dim G_pre As Long
    Dim G_set As Word
    Dim G_calc As Single
    Dim G_out As Integer
    
    Dim D_pre As Long
    Dim D_set As Word
    Dim D_out As Integer
    
    Do
          Upperline : Lcd " " ; D_out ; "  " ; G_calc ; "                   "
          Lowerline : Lcd " " ; Timer1 ; "                   "
          Waitms 1000
    Loop
    
    Ges:
        G_calc = G_set - G_pre
        G_pre = G_set
        G_set = Timer1
    Return
    
    Dre:
        D_out = D_set - D_pre
        D_pre = D_set
        D_set = Timer1
    Return
    
    Timer_irq:
       D_pre = D_pre - 65535
       G_pre = G_pre - 65535
    Return
    
    
    End
    Was mach ich falsch, dass er die Trigger INT0/1 gegen Masse nicht erkennt und die Differenz zwischen den 'pre" und 'set' nicht ausgibt?

  6. #6
    Erfahrener Benutzer Roboter Genie Avatar von malthy
    Registriert seit
    19.04.2004
    Ort
    Oldenburg
    Beiträge
    1.379
    Hi,

    unabhängig von allem anderen: Du musst die Interrupts noch global einschalten

    Code:
    Enable Interrupts
    Gruß
    Malte

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.703
    Blog-Einträge
    133
    Hallo,

    Zitat Zitat von therealosram Beitrag anzeigen
    Was mach ich falsch, dass er die Trigger INT0/1 gegen Masse nicht erkennt und die Differenz zwischen den 'pre" und 'set' nicht ausgibt?
    Gibt er nichts aus oder nur das falsche? Auf jeden Fall fehlt das "Enable Interrupts". Ob der Rest paßt habe ich nicht überprüft.

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    15.08.2013
    Ort
    Güstrow
    Beiträge
    31
    Die Kiste ist schon fertig. Läuft ca 50. Reicht auch, jetzt brauch ich nur noch Tacho und Drehzahlmesser. Mit welcher Seite sollte man hier Bilder Posten?

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    15.08.2013
    Ort
    Güstrow
    Beiträge
    31
    Hallo ans Forum.
    Da ich mir das auch selber immer wünsche hier der fertige und vor allem laufende Code mit Anmerkungen

    Code:
    $regfile = "m88def.dat"
    $hwstack = 128
    $framesize = 128
    $swstack = 128
    
    Config Timer1 = Timer , Prescale = 8
    Config Timer0 = Timer , Prescale = 1024
    
    'Die Sensoren sollen auf Masse-Kontakt auslösen
    Config Int0 = Falling
    Config Int1 = Falling
    
    'Auf Sensoren anspringen
    On Int0 Ges                                       'Geschwindigkeit
    On Int1 Dre                                       'Drehzahl
    
    'Auf Timer-Überläufe anspringen
    On Timer1 Timer1_irq
    On Timer0 Timer0_irq
    
    'Den ganzen Kram anschalten
    Enable Int0
    Enable Int1
    Enable Timer1
    Enable Timer0
    Enable Interrupts
    
    'Ports configurieren
    Config Sda = Portc.4
    Config Scl = Portc.5
    Config Portd.2 = Input
    Config Portd.3 = Input
    Config Portd.5 = Output
    Config Portd.6 = Output
    Config Portd.7 = Output
    Config Portb = Output
    
    Pind.2 = 1
    Pind.3 = 1
    
    'Variablen festlegen
    Dim C1 As Byte
    Dim C0 As Byte
    Dim G_pre As Long
    Dim G_set As Long
    Dim G_out As Long
    Dim G_out_2 As Long
    Dim G_out_3 As Long
    Dim G_out_calc As Single
    
    Dim D_pre As Long
    Dim D_set As Long
    Dim D_out As Long
    Dim D_out_2 As Long
    
    Dim Zehner As Byte
    Dim Einer As Byte
    
    
    C1 = 0
    C0 = 0
    Do
          'Abwägung, wieviele LED's je nach Drehzahl leuchten sollen
          Select Case D_out_2
             Case Is < 146                            '>7000
                  Portb = &B111111XX
                  Portd.7 = 1
                  Portd.6 = 1
                  Portd.5 = 1
    
             Case Is < 170                            '>6000
                  Portb = &B111111XX
                  Portd.7 = 1
                  Portd.6 = 1
                  Portd.5 = 0
    
             Case Is < 205                            '>5000
                  Portb = &B111111XX
                  Portd.7 = 1
                  Portd.6 = 0
                  Portd.5 = 0
    
             Case Is < 255                            '>4000
                  Portb = &B111111XX
                  Portd.7 = 0
                  Portd.6 = 0
                  Portd.5 = 0
    
             Case Is < 340                            '>3000
                  Portb = &B111110XX
                  Portd.7 = 0
                  Portd.6 = 0
                  Portd.5 = 0
    
             Case Is < 510                            '>2000
                  Portb = &B111100XX
                  Portd.7 = 0
                  Portd.6 = 0
                  Portd.5 = 0
    
             Case Is < 1020                           '>1000
                  Portb = &B111000XX
                  Portd.7 = 0
                  Portd.6 = 0
                  Portd.5 = 0
    
             Case Is < 1360                           '>750
                  Portb = &B110000XX
                  Portd.7 = 0
                  Portd.6 = 0
                  Portd.5 = 0
    
             Case Is < 2030                           '>500
                  Portb = &B100000XX
                  Portd.7 = 0
                  Portd.6 = 0
                  Portd.5 = 0
    
             Case Else
                  Portb = &B000000XX
                  Portd.7 = 0
                  Portd.6 = 0
                  Portd.5 = 0
    
           End Select
    
    
          'Berechnungen der Geschwindigkeit und Ausgabe über I2C
          'an einen MAX6958.
    
          If G_out_2 < 1000000 Then
             G_out_calc = 1 / G_out_2
             G_out_calc = G_out_calc * 1473081
             G_out_3 = G_out_calc
          Else
              G_out_3 = 0
          End If
    
          Zehner = G_out_3 / 10
          Zehner = Zehner Mod 10
          Einer = G_out_3 Mod 10
    
          I2cstart
          I2cwbyte &B01110000                         'Chip-Adresse
          I2cwbyte &B00000001                         'Erste Adresse (Autoincr.)
          I2cwbyte &B00000011                         'decode
          I2cwbyte &B00001000                         'helligkeit
          I2cwbyte &B00000011                         'scan limit
          I2cwbyte &B00000001                         'nomal Operation
          I2cstop
    
          I2cstart
          I2cwbyte &B01110000
          I2cwbyte &B00100000                         'Adresse
          I2cwbyte Zehner                             'Zehner
          I2cwbyte Einer                              'Einer
          I2cstop
    
          'Um bei den langen Intervallen der Geschwindigkeitsmessung
          'auch geringe messen zu können, lass ich den 16bit Timer ziemlich
          'schnell durchlaufen und dafür mehrmals (100x) durchlaufen
          'und multipiziere mit C1.
    
          'Der 8bit Timer sorgt in regelmäßigen Abständen dafür, dass bei
          'Ergebnislosigkeit der Interupts die Zehler wieder als Ergebnis 0
          'anzeigen
    
          If C1 = 100 Then C1 = 0
          If C0 = 50 Then
             G_out_2 = 1000000
             D_out_2 = 2500
             C0 = 0
          End If
    
    Loop
    
    'Geschwindigkeit INT
    Ges:
        G_out = G_set - G_pre
        G_pre = G_set
        G_set = C1 * 65535
        G_set = G_set + Timer1
        If G_out > 0 Then G_out_2 = G_out
    Return
    
    'Drehzahl INT
    Dre:
        D_out = D_set - D_pre
        D_pre = D_set
        D_set = C1 * 65535
        D_set = D_set + Timer1
        If D_out > 0 Then D_out_2 = D_out
    Return
    
    'Überlauf 16bit Timer
    Timer1_irq:
       C1 = C1 + 1
    Return
    
    'Überlauf 8bit Timer
    Timer0_irq:
       C0 = C0 + 1
    Return
    
    
    End

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von Searcher
    Registriert seit
    07.06.2009
    Ort
    NRW
    Beiträge
    1.703
    Blog-Einträge
    133
    Zitat Zitat von therealosram Beitrag anzeigen
    Da ich mir das auch selber immer wünsche hier der fertige und vor allem laufende Code mit Anmerkungen
    Super, Danke!


    Zitat Zitat von therealosram Beitrag anzeigen
    Mit welcher Seite sollte man hier Bilder Posten?
    Beim Antworten auf einen Beitrag gibt es rechts unten einen Button "Erweitert". Beim Aktivieren bekommt man eine Vorschau auf das schon verfasste und verschiedene Icons. Mit einem Icon davon kann man Grafik einfügen und beim Klick darauf bekommt man die Auswahl zum Link einfügen oder "vom Computer hochladen". Bei letzterem braucht man also keinen externen Provider. Hat den Vorteil, daß die Bilder durch externe Einflüsse praktisch nicht verloren gehen.

    Hab noch nicht durchgeblick, wann die Bilder vom Forum automatisch verkleinert werden und begrenze meine Bilder immer auf 600 Pixel maximale Seitenlänge und 100kB Dateigröße.

    Gruß
    Searcher
    Hoffentlich liegt das Ziel auch am Weg
    ..................................................................Der Weg zu einigen meiner Konstruktionen

Ähnliche Themen

  1. Atmega88 wird in bascom nicht erkannt
    Von nrg_mario im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 09.07.2011, 18:19
  2. MCS-Bootloader für ATmega8 und ATmega88 compilieren
    Von felack im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 24.09.2008, 14:47
  3. IR-Empfänger an ATMega88 und Timer2
    Von Schokohoernl im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 1
    Letzter Beitrag: 21.02.2007, 00:23
  4. 4 x PWM mit ATMega88 und BASCOM
    Von Trabukh im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 04.08.2006, 09:35
  5. Atmega88 und rc5 codes
    Von Furtion im Forum AVR Hardwarethemen
    Antworten: 19
    Letzter Beitrag: 30.12.2005, 22:21

Stichworte

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad