-
RSS-Feed anzeigen

Searcher

Erste Quadratursignalauswertung sversuche

Bewerten
Bin mitten in Versuchen (Deshalb Irrtümer, wie sonst auch , im Folgenden nicht ausgeschlossen) und kümmere mich um die Auswertung der Quadratursignale erstmal nur eines Encoders.

Hier mal einige Überlegungen:
Messungen an der HW haben gezeigt, daß es reicht das Programm auf eine maximale Quadratursignalfrequenz von 2kHz und einen minimalen Phasenversatz von 30° (ca 40µs bei 2kHz) auszulegen. 2kHz entsprechen bei mir der Maximaldrehzahl von 100 U/s des Motors im Leerlauf und würde eine Endgeschwindigkeit des Vehikels von ca 80 bis 100cm/s bedeuten, also reichlich Sicherheit, da die schwachen Motoren unter Last sicher stark einbrechen und ich nicht immer mit 100% PWM fahre.

Das Programm zum Zählen benutzt einen Algorithmus aus RN-Wissen, allerdings wird das Signal nicht in festen Zeitintervallen abgetastet, sondern wertet das Signal in einer ISR aus, die per Pin Change Interrupt des Tiny24 aufgerufen wird und zwar jedesmal wenn ein Flankenwechsel an einem der beiden Quadratursignaleingänge auftritt.

Zur Kontrolle der Meßergebnisse wollte ich erst eine weitere Lichtschranke am Encoder anbringen und mit einem anderen µC mitzählen. War mir zu umständlich und habe deshalb aus einem Tiny25 einen Simulator gemacht, der ein Quadratursignal mit 2kHz erzeugt und wo der Phasenversatz mit Poti einstellbar ist.

Sieht aus, als wenn die Meßergebnisse sehr plausibel sind. Sie schwanken innerhalb einer Meßserie um maximal 3 Einheiten. Größenordnung zB 4041..4043. Mit Oszi kontrollierte Frequenz vom Tiny25-Simulator mit internem Oszillator ist etwas höher als 2kHz und es wird gezählt wenn beide Quadratureingänge 0 oder 1 sind.

Intressant wird es, wenn der zweite Encoder angeschlossen wird (Soll über den zweiten PCINT des Tiny24 an PortB laufen). Die ISR benötigt knapp 30µs und es könnte dann arg knapp mit der Zeit werden. Vielleicht doch Zeit, um ein bißchen Inline Assembler zu lernen?

Gruß
Searcher

Meßprogramm
Code:
'###################################################
'Testprogramm zur Quadratursignalauswertung
'Getestet bei 2kHz und nicht weniger als 20µs (ca 15 Grad) Phasenversatz
'
'File: drehzahl_04_tiny24.bas
'IDE: BASCOM-AVR DEMO Version 2.0.5.0
'
'ATtiny24
'PA1 : Eingang Quadratursignal A
'PA2 : Eingang Quadratursignal B
'PB0 : SW UART #1 , für Ausgabe der Meßwerte an 4 fach 7-Segmentanzeige
'#######################################################

$regfile = "attiny24.dat"
$framesize = 24
$swstack = 24
$hwstack = 36
$crystal = 8000000                      'interner Oszillator
Osccal = &H8E                           'trim internal oscillator close to real 8MHz

Config Porta = Input
Config Portb = Input
Porta = &B11111111                      'Pullups ein
Portb = &B11111110                      'Pullups ein, Ausnahme PB0 (TX SW-UART)

'##### Definitionen und Initialisierung für 7segment ausgabe ######
Dim Number_string As String * 6
Dim Digits(5) As Byte
Dim X As Byte
Dim Y As Byte
Dim Idx As Byte
Dim Num_to_disp As Word
Declare Sub Display_value(num_to_disp As Word)
Open "comb.0:115200,8,n,1" For Output As #1       'comb.0 -> TX ist Pin PB0
Y = &B11111101                          'segment g
For X = 1 To 5 : Put #1 , Y : Next      '7 segment initialisieren
'#### Ende Definitionen und Initialisierung für 7 Segmentausgabe #######

Dim Encoder_right As Byte
Dim Encoder_right_value As Word
Dim Encoder_diff As Byte

Dim Result(4) As Word
Dim I As Byte
Dim K As Byte

'16 Bit Timer1 für Meßzeitnahme und Ausgabe der Meßergebnisse im Sekundentakt
Set Tccr1b.wgm12                        'clear timer1 on compare ocr1a
Ocr1a = 31249                           'Comparewert für eine Sekunde
Set Tccr1b.cs12                         'switch on timer1, prescale = 256
On Compare1a Isr_store_and_show_sample
Enable Compare1a                        'Comparematch interrupt enable

Set Pcmsk0.pcint1 : Set Pcmsk0.pcint2   'Pin Change Interrupt 0 auf PA1 und PA2 möglich
On Pcint0 Isr_pcie0
Enable Pcint0                           'Enable Pin Change Interrupt auf PortA

Enable Interrupts

Do
'Haupschleife - nichts zu tun
Loop

Isr_pcie0:                              'Hier läuft der Algorithmus zur Quadratursignalauswertung
  Shift Encoder_right , Left , 2
  Encoder_right.0 = Pina.1
  Encoder_right.1 = Pina.2
  Encoder_right = Encoder_right And &B00001111
  Encoder_diff = Lookup(encoder_right , Encoder_table)
  Encoder_right_value = Encoder_right_value + Encoder_diff
Return

Encoder_table:
'Orginaltabelle
'  Data 0 , 0 , 1 , 0 , 0 , 0 , 0 , 255 , 255 , 0 , 0 , 0 , 0 , 1 , 0 , 0 'original Tabell

'angepaßte Tabelle addiert auch bei umgekehrter Drehrichtung
  Data 0 , 0 , 1 , 0 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 1 , 0 , 0


'Isr_store_and_show_sample speichert 4 Meßwerte und gibt sie danach aus
Isr_store_and_show_sample:              'wird jede Sekunde einmal aufgerufen
  I = I + 1
  If I < 5 Then                         '4 mal
      Result(i) = Encoder_right_value   'Meßwert zwischenspeichern
      Encoder_right_value = 0
    Else
      K = K + 1
      If K < 5 Then
          Call Display_value(result(k)) 'Meßwerte anzeigen, VORSICHT - zeitfressend
        Else                            'Ausgabe zuende
         I = 0
         K = 0
         Y = &B11111101                 'segment g
         For X = 1 To 4 : Put #1 , Y : Next       'Anzeige für neue Messung läuft
         Encoder_right_value = 0
      End If
  End If
Return

'############ Folgende Zeilen bis zum Ende nur zur Datenausgabe über 7 Segmentanzeige #############
Sub Display_value(num_to_disp As Word)  'gibt Dezimalzahlen bis 9999 aus
   Number_string = Str(num_to_disp)     'Zahl in String geben
   Str2digits Number_string , Digits(1) 'Ziffern im String in Byte Array geben
   X = Digits(1) + 1                    'in Digits(1) befindet sich Anzahl der Ziffern der Zahl
   For Idx = 5 To 2 Step -1
     If X < Idx Then
         Put #1 , &HFF                  'Leerstellen dunkel schalten
       Else
         Y = Lookup(digits(idx) , Pattern)       'Segmentpattern aus Tabelle fischen
         Put #1 , Y                     'Segmentpattern senden
     End If
   Next
End Sub

Pattern:                                'darzustellende Zeichen (hex 0..F...)
'Segmente abcdefg:                      ' ":" = Doppelpunkt in der Mitte
   Data &B00000011                      'Ziffer "0", 0 = segment ein, 1 = aus
   Data &B10011111                      'Ziffer "1"
   Data &B00100101                      'Ziffer "2"
   Data &B00001101
   Data &B10011001
   Data &B01001001
   Data &B01000001
   Data &B00011111
   Data &B00000001
   Data &B00001001
   Data &B00010001
   Data &B11000001
   Data &B01100011
   Data &B10000101
   Data &B01100001                      'Ziffer "E"
   Data &B01110001                      'Ziffer "F"
   Data &B11111111                      'dunkel
   Data &B11111101                      'nur Segment g eingeschaltet (-)

'########### ENDE Programm  ##############################################

"Erste Quadratursignalauswertung sversuche" bei Twitter speichern "Erste Quadratursignalauswertung sversuche" bei Facebook speichern "Erste Quadratursignalauswertung sversuche" bei Mister Wong speichern "Erste Quadratursignalauswertung sversuche" bei YiGG.de speichern "Erste Quadratursignalauswertung sversuche" bei Google speichern "Erste Quadratursignalauswertung sversuche" bei del.icio.us speichern "Erste Quadratursignalauswertung sversuche" bei Webnews speichern "Erste Quadratursignalauswertung sversuche" bei My Yahoo speichern

Stichworte: - Stichworte bearbeiten
Kategorien
Projekte , Root , ATtiny44 , Drehzahlregelung

Kommentare