Erste Quadratursignalauswertung sversuche
von
am 20.11.2011 um 10:30 (2318 Hits)
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 ##############################################