Aus RN-Wissen.de
Wechseln zu: Navigation, Suche
LiFePO4 Speicher Test

(Messen der Drehzahl durch zählen der Impulse)
 
(21 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt)
Zeile 4: Zeile 4:
  
  
Beispiele zum Messen der Drehzahl in Abhängigkeit einer zurückgelegten Strecke oder einer Abgelaufenen Zeit
+
Ermitteln der Drehzahl und Wegstrecke in Abhängigkeit einer Winkeländerung oder Impulsfolge in einer Abgelaufenen Zeit
  
* Messen der Drehzahl nach jedem Impuls, also in Abhängigkeit einer zurückgelegten Strecke.
+
* Messen der Drehzahl nach jedem Impuls, also in Abhängigkeit einer Winkeländerung.
 
* Messen der Drehzahl durch Zählen der Impulse nach Ablauf einer bestimmten Zeit.  
 
* Messen der Drehzahl durch Zählen der Impulse nach Ablauf einer bestimmten Zeit.  
* Drehrichtung mit Doppellichtschranke ermitteln
+
* Richtung, Geschwindigkeit und Position mit Doppellichtschranke ermitteln
 
{{Ausbauwunsch|Mehr Grundlagen und vor allem mal praktische Programmbeispiele / Algorithmen etc.}}
 
{{Ausbauwunsch|Mehr Grundlagen und vor allem mal praktische Programmbeispiele / Algorithmen etc.}}
 
= Messen der Drehzahl nach jedem Impuls =
 
= Messen der Drehzahl nach jedem Impuls =
  
Dieser Teil beschäftigt sich mit der Optischen Drehzahlmessung mit Hilfe einer Lochscheibe und [[Gabellichtschranke]] berechnet über die Periodendauer ohne Drehrichtungserkennung.
+
Dieser Teil beschäftigt sich vor allem mit der Optischen Drehzahlmessung mit Hilfe einer Lochscheibe und [[Gabellichtschranke]] berechnet über die Periodendauer ohne Drehrichtungserkennung.
 
[[Bild:GP1S23 Testaufbau.JPG|thumb| Testaufbau mit einer 32er Lochscheibe ]]
 
[[Bild:GP1S23 Testaufbau.JPG|thumb| Testaufbau mit einer 32er Lochscheibe ]]
 
[[Bild:183015_LB_00_FB.EPS_250.jpg|thumb|GP1S23 Gabellichtschranke Bild: Conrad Electronic ]]
 
[[Bild:183015_LB_00_FB.EPS_250.jpg|thumb|GP1S23 Gabellichtschranke Bild: Conrad Electronic ]]
Zeile 18: Zeile 18:
  
 
== Einführung ==
 
== Einführung ==
 +
 +
Am einfachsten ist Impulse direkt an einer Bürste eines Motors zu zählen. Siehe dazu: http://www.roboternetz.de/community/...einem-DC-Motor .
  
 
Die [http://de.wikipedia.org/wiki/Winkelgeschwindigkeit Winkelgeschwindigkeit] ist die Winkeländerung pro Zeiteinheit. Mit der Lichtschranke und den geometrischen Daten der Lochscheibe kann man nun relativ einfach die Zeit für eine bestimmte Winkeländerung messen.  
 
Die [http://de.wikipedia.org/wiki/Winkelgeschwindigkeit Winkelgeschwindigkeit] ist die Winkeländerung pro Zeiteinheit. Mit der Lichtschranke und den geometrischen Daten der Lochscheibe kann man nun relativ einfach die Zeit für eine bestimmte Winkeländerung messen.  
Zeile 31: Zeile 33:
 
== Auslegen der Lochscheibe ==
 
== Auslegen der Lochscheibe ==
  
In den meisten fällen definiert der mechanische Aufbau den Durchmesser der Lochscheibe und die Drehzahl die Anzahl der Löcher, der µC muss und die Gabellichtschranke müssen die Impulse auch erfassen können. Wenn man das Drehzahlband abschätzen kann ist es hilfreich sich schon Gedanken um die Programmierung zu machen, denn bei hohen Drehzahlen springt der µC jedes mal in die Interrupt Service Routine rein wenn man es so programmiert wie im Beispiel. Bei hohen Drehzahlen sollte die Auflösung somit gröber sein, bei niedriger feiner.  
+
In den meisten Fällen definieren der mechanische Aufbau den Durchmesser der Lochscheibe und die Drehzahl die Teilung (Anzahl der Löcher). Der µContoller und die Gabellichtschranke müssen die Impulse auch erfassen und verarbeiten können. Wenn man das Drehzahlband abschätzen kann ist es hilfreich, sich schon Gedanken um die Programmierung zu machen, denn bei hohen Drehzahlen springt der µC jedes mal in die Interrupt Service Routine rein, sofern man es so programmiert wie im Beispiel. Bei hohen Drehzahlen sollte die Teilung somit gröber, bei niedriger Drehzahl die Teilung feiner sein.  
  
 
[[Bild:Drehscheibe20mm.png|400px|thumb|left|Lochscheibe abgerollt mit idealisiertem Signal ]]
 
[[Bild:Drehscheibe20mm.png|400px|thumb|left|Lochscheibe abgerollt mit idealisiertem Signal ]]
Zeile 39: Zeile 41:
 
Hier folgt nun die Berechnung über die Periodendauer, beachten sollte man das im [http://de.wikipedia.org/wiki/Bogenma%C3%9F Bogenmaß] gerechnet wird, ein Winkel mit dem Bogenmaß 1 rad hat ein Gradmaß von ca. 57,3°. 11.25° sind also ca. 0,196 rad, das führt später natürlich zu unschönen Rechenoperationen im µC, Stichwort [http://www.mikrocontroller.net/articles/Festkommaarithmetik Festkommaarithmetik].  
 
Hier folgt nun die Berechnung über die Periodendauer, beachten sollte man das im [http://de.wikipedia.org/wiki/Bogenma%C3%9F Bogenmaß] gerechnet wird, ein Winkel mit dem Bogenmaß 1 rad hat ein Gradmaß von ca. 57,3°. 11.25° sind also ca. 0,196 rad, das führt später natürlich zu unschönen Rechenoperationen im µC, Stichwort [http://www.mikrocontroller.net/articles/Festkommaarithmetik Festkommaarithmetik].  
  
Nach dem umstellen kommt man aber auf eine recht handliche Formel <math>n = \frac{\varphi }{dt \cdot 360}</math>
+
Nach dem Umstellen kommt man aber auf eine recht handliche Formel <math>n = \frac{\varphi }{dt \cdot 360}</math>
 
+
Es ist auch eine Überlegung wert ob man die Drehzahl nicht umrechnet sondern mit der Periodendauer arbeitet, das ist zwar nicht so geläufig aber das stört den µC nicht. Mit einem Kalkulationsprogramm hat man sich schnell ein Tool gemacht was die Umrechnung vornimmt.
+
 
+
 
+
 
+
  
 +
Es ist auch eine Überlegung wert, ob man die Drehzahl nicht umrechnet sondern mit der Periodendauer arbeitet. Das ist zwar nicht so geläufig aber das stört den µController nicht. Mit einem Kalkulationsprogramm kann man die Umrechnung von Periodendauer in Drehzahl auch extern vornehmen.
  
 +
Man sollte sich auch klar machen, das zumindest ein 8-Bit Prozessor am besten mit '''Ganzzahlen''' zwischen 0 und 255 oder 0 und 65535 zurechtkommt. Für die Teilung der Lochscheibe bieten sich deshalb Werte wie 90, 72, 45, 36, 30, 24, 20, 18, 15, 12, 10 und 8 an. Verwendet man an Stelle der dargestellten 32er Lochscheibe eine 30er oder 36er Scheibe, kann man zumindest mit ganzzahligen Gradzahlen rechnen. "Krumme Werte" wie [http://de.wikipedia.org/wiki/Kreiszahl Pi = 3,1415...], [http://de.wikipedia.org/wiki/Radiant_%28Einheit%29 Radiant = 57,29577...°] usw. sollten eine seltene Ausnahme in der Programmierung sein.
  
 
= Messen der Drehzahl durch zählen der Impulse =
 
= Messen der Drehzahl durch zählen der Impulse =
Zeile 52: Zeile 51:
 
Dieser Teil beschäftigt sich mit der Optischen Drehzahlmessung mit Hilfe einer Lochscheibe und [[Gabellichtschranke]] berechnet über die die Anzahl der Impulse in einer gewissen Zeit.
 
Dieser Teil beschäftigt sich mit der Optischen Drehzahlmessung mit Hilfe einer Lochscheibe und [[Gabellichtschranke]] berechnet über die die Anzahl der Impulse in einer gewissen Zeit.
  
 +
Die meisten µC bieten die Möglichkeit über einen Eingang direkt mit der Hardware externe Pulse zu zählen (z.B. beim AVR der Eingang T1). Über eine vorgegeben Zeit von z.B. 1 Sekunde wird über den externen Eingang die Zahl der Pulse gezählt. Die Drehzahl ergibt sich dann einfach auch der Zahl der Impulse geteilt durch die Zahl der Löcher in der Scheibe und die Zeit für die Messung. Da die Zahl der Löcher und die Zeit konstant sind, erhält man direkt einen Wert proportional zur Drehzahl. Auch ist bei geeigneter Hardware die Belastung für die CPU gering, es werden aber i.A. 2 Timer benötigt: der eine für das Zählen der Impulse und der andere für die Festlegung des Zeitintervalls. Das Zeitintervall muss als Kompromiss zwischen Aktualisierungsfrequenz und Auflösung gewählt werden: mit einer Scheibe mit 32 Löchern erhält man in einer Sekunde ein Auflösung von 1/32 Umdrehungen pro Sekunde oder bei 1/32 Sekunde nur noch 1 Umdrehung pro Sekunde als Auflösung.  Geeignet ist diese Methode vor allem für schnell kommende Pulse, also hohe Drehzahlen bzw. Lochscheiben mit vielen Löchern, da so in der Messzeit genügend Pulse für eine ausreichende Auflösung kommen.
 +
 +
= Richtung, Geschwindigkeit und Position mit Doppellichtschranke ermitteln =
 +
Dieser Teil beschäftigt sich mit der Optischen Drehzahl- und Geschwindigkeitsmessung sowie der Erfassung von Drehrichtung und zurückgelegter Position mit Hilfe einer Lochscheibe und 2 Gabellichtschranken. Hierfür werden Quadratursignale in definierten Zeitabständen ausgewertet.
 +
 
== Einführung ==
 
== Einführung ==
  
 +
Für kontrollierte Bewegungen ist es mitunter wichtig, auch die Drehrichtung/Richtungswechsel und Position auszuwerten. Eine Lochscheibe mit einer Gabellichtschranke liefert lediglich Rechteckimpulse, egal wie rum sich die Lochscheibe bewegt. Bringt man eine zweite Gabellichtschranke an der gleichen Lochscheibe leicht versetzt an, bekommt man auch die Drehrichtung mit. Diese Methode ist altbekannt, simpel und leicht nachzubauen. Wenn man die Drehrichtung kennt, ist auch die Position kein Problem mehr. Ausgehend von einer Kalibrierposition können bei Vorwärtsbewegung Inkremente hochgezählt oder bei Rückwärtsbewegung runtergezählt werden.
  
== Berechnung==
+
Interessierte nehmen dazu mal eine PC-Maus mit Kugelantrieb zur Hand. Darin findet man zwei kleine Lochscheiben, die für die X- und Y-Richtung die Impulse erzeugen. Durch spezielle Gabellichtschranken mit 2 phasenversetzten Ausgängen wird auch die Drehrichtung erkannt.
  
= Drehrichtung mit Doppellichtschranke ermitteln =
+
Das selbe Prinzip ist in linearer Form auch in PC-Druckern zu finden: Entlang des Wagenrücklaufes ist ein transparentes Kunsstoffband gespannt, auf dem winzig kleine Streifenmuster aufgebracht sind. Diese werden von einer Gabellichtschranke mit 2 Ausgängen erkannt und so die Wagenposition gesteuert.
  
== Einführung ==
+
Aber es geht natürlich noch einfacher...
  
Für kontrollierte Bewegungen ist mitunter wichtig, auch die Drehrichtung/Richtungswechsel und Position auszuwerten. Eine Lochscheibe mit einer Gabellichtschranke liefert lediglich Rechteckimpulse, egal wie rum sich die Lochscheibe bewegt. Bringt man eine zweite Gabellichtschranke an der gleichen Lochscheibe leicht versetzt an, bekommt man auch die Drehrichtung mit. Diese Methode ist altbekannt, simpel und leicht nachzubauen. Wenn man die Drehrichtung kennt, ist auch die Position kein Problem mehr. Ausgehend von einer Kalibrierposition können bei Vorwärtsbewegung Inkremente hochgezählt oder bei Rückwärtsbewegung runtergezählt werden.
+
== Zwei Lichtschranken liefern vier Zustände ==
  
Interessierte nehmen dazu mal eine PC-Maus mit Kugelantrieb zur Hand. Darin findet man zwei kleine Lochscheiben, die für die X- und Y-Richtung die Impulse erzeugen. Durch spezielle Gabellichtschranken mit 2 phasenversetzten Ausgängen wird auch die Drehrichtung erkannt. Aber es geht natürlich noch einfacher...
+
[[Bild:vorwaerts_.jpg|thumb|Zustandsfolge bei Vorwärtsbewegung]]
 +
[[Bild:rueckwaerts_.jpg|thumb|Zustandsfolge bei Rückwärtsbewegung]]
 +
[[Bild:2LSZustand.jpg|thumb|2 Lichtschranken (LSA und LSB) liefern phasenversetzte Rechtecksignale. In Vorwärts- und Rückwärtsrichtung ergeben sich unterschiedliche Zustandsfolgen]]
  
== Zwei Lichtschranken liefern vier Informationen ==
+
Man nimmt 2 normale Gabellichtschranken und bringt sie so an, das sie im 1,5 fachen Lochabstand die Lochscheibe durchleuchten. Wenn sich Lichtschranke A in der Mitte des Lichtstreifens befindet, ist Lichtschranke B an der Grenze des Schattenstreifens. Nebenstehende Skizzen zeigen die möglichen Zustände beider Lichtschranken bei Vorwärts- und Rückwärtsbewegung der Lochscheibe. Wichtig ist hierbei, das die Lochscheibe in etwa gleich breite Licht- und Schattensegmente eingeteilt ist und die Lichtschranke(n) einen möglichst haarfeinen Lichtstrahl besitzt. Die Signale der Fototransistoren sollten verstärkt und gegebenenfalls mit TTL-Bausteinen zu korrekten High- und Low-Pegeln aufbereitet werden.
  
Man nimmt 2 normale Gabellichtschranken und bringt sie so an, das sie im 1,5 fachen Lochabstand die Lochscheibe durchleuchten. Wenn sich Lichtschranke A in der Mitte des Lichtstreifens befindet, ist Lichtschranke B schon an der Grenze zum Schattenstreifen und tritt aus dem Lichtstreifen heraus. Wichtig ist hierbei, das die Lochscheibe in gleich breite Licht- und Schattensegmente eingeteilt ist und die Lichtschranke einen möglichst haarfeinen Lichtstrahl besitzt. (Skizze folgt)
 
  
 
Es ergeben sich nun folgende Kombinationen:
 
Es ergeben sich nun folgende Kombinationen:
Zeile 76: Zeile 82:
 
* Zustand 4:    LSA = dunkel und LSB =  hell
 
* Zustand 4:    LSA = dunkel und LSB =  hell
  
[[Bild:2LSZustand.jpg|400px|thumb|left|2 Lichtschranken (LSA und LSB) liefern phasenversetzte Rechtecksignale. In Vorwärts- und Rückwärtsrichtung ergeben sich unterschiedliche Zustandsfolgen]]
+
Dreht man die Lochscheibe weiter, wiederholt sich der Vorgang. Die Zustandsfolge ist 1 > 2 > 3 > 4 > 1 > 2 > 3 > 4 >  usw.
  
  
 
 
Dreht man die Lochscheibe weiter, wiederholt sich der Vorgang. Die Zustandsfolge ist
 
1 > 2 > 3 > 4 > 1 > 2 > 3 > 4 >  usw.
 
  
 
Bei entgegengesetzter Drehrichtung ändert sich diese Reihenfolge. Betrachtet man wieder vom Zustand 1 ausgehend die Gegenrichtung, ergeben sich nun diese Kombinationen:
 
Bei entgegengesetzter Drehrichtung ändert sich diese Reihenfolge. Betrachtet man wieder vom Zustand 1 ausgehend die Gegenrichtung, ergeben sich nun diese Kombinationen:
Zeile 92: Zeile 94:
  
 
Die Zustandsfolge in Gegenrichtung lautet dann: 1 < 4 < 3 < 2 < 1 < 4 < 3 < 2 <  usw.
 
Die Zustandsfolge in Gegenrichtung lautet dann: 1 < 4 < 3 < 2 < 1 < 4 < 3 < 2 <  usw.
 +
  
 
Mit diesem Wissen ist es nun ein Kinderspiel, auch die Änderung der Drehrichtung festzustellen. Dazu muss der letzte Zustand in einer Variable gespeichert und mit dem neu erkannten Zustand verglichen werden. Folgt nach Zustand 1 der Zustand 2, so ist es eine Vorwärtsbewegung. Folgt dem Zustand 1 der Zustand 4, so ist es eine Rückwärtsbewegung. Gleiches Prinzip gilt auch für die restlichen Zustände 2, 3 und 4.
 
Mit diesem Wissen ist es nun ein Kinderspiel, auch die Änderung der Drehrichtung festzustellen. Dazu muss der letzte Zustand in einer Variable gespeichert und mit dem neu erkannten Zustand verglichen werden. Folgt nach Zustand 1 der Zustand 2, so ist es eine Vorwärtsbewegung. Folgt dem Zustand 1 der Zustand 4, so ist es eine Rückwärtsbewegung. Gleiches Prinzip gilt auch für die restlichen Zustände 2, 3 und 4.
 
 
 
  
 
== Positionsüberwachung ==
 
== Positionsüberwachung ==
Zeile 112: Zeile 112:
 
* WENN (Zustand=4 UND A=0 UND B=0) DANN: Setze Zustand=1, Position inkrementieren, Vor
 
* WENN (Zustand=4 UND A=0 UND B=0) DANN: Setze Zustand=1, Position inkrementieren, Vor
 
* WENN (Zustand=4 UND A=1 UND B=1) DANN: Setze Zustand=3, Position dekrementieren, Rück
 
* WENN (Zustand=4 UND A=1 UND B=1) DANN: Setze Zustand=3, Position dekrementieren, Rück
 +
[[Bild:Lochscheibe8.jpg|thumb|Lochscheibe 8 ]]
 +
[[Bild:Lochscheibe10.jpg|thumb|Lochscheibe 10 ]]
 +
[[Bild:Lochscheibe12.jpg|thumb|Lochscheibe 12 ]]
 +
[[Bild:Lochscheibe15.jpg|thumb|Lochscheibe 15 ]]
 +
[[Bild:Lochscheibe18.jpg|thumb|Lochscheibe 18 ]]
 +
[[Bild:Lochscheibe20.jpg|thumb|Lochscheibe 20 ]]
  
Diese Prüfung muss ständig wiederholt werden, damit alle Pegelwechsel der beiden Lichtschranken erfasst werden. Nur so ist es möglich, die exakte Position zu verfolgen. Dafür bieten sich 2 Möglichkeiten: Entweder die Prüfung wird im Hauptprogramm ständig durchlaufen (Polling) oder ein Timer-Interrupt tastet regelmäßig die Lichtschranken ab. Hier soll nur die zweite, also Interruptvariante betrachtet werden, weil sie mehr Vorteile bringt. Weiter unten im Artikel ist dazu ein Beispiel in Sprache C zu finden.
 
  
Zuvor muss aber eine sinnvolle Auslegung von Lochscheibe, Drehzahl und Positionsbereich gefunden und in Einklang mit den Resourcen des verwendeten µControlles gebracht werden. Dazu folgende Betrachtungen:
+
Diese Prüfung muss ständig wiederholt werden, damit alle Pegelwechsel der beiden Lichtschranken erfasst werden. Nur so ist es möglich, die exakte Position zu verfolgen. Dafür bieten sich 2 Möglichkeiten: Entweder die Prüfung wird im Hauptprogramm ständig durchlaufen bzw. ein Timer-Interrupt tastet regelmäßig die Lichtschranken ab oder ein Interrupt reagiert auf eine Änderung der Leichtschranken und die Auswertung erfolgt nach jeder Änderung.  Die Art der Auswertung kann in allen Fällen gleich sein - lediglich wann und wie oft sie aufgerufen wird ist verschieden. Hier soll nur die Interruptvariante betrachtet werden, weil sie mehr Vorteile bringt. Weiter unten im Artikel ist dazu ein Beispiel in Sprache C zu finden.  
  
<gallery>
+
Zuvor muss aber eine sinnvolle Auslegung von Lochscheibe, Drehzahl und Positionsbereich gefunden und in Einklang mit den Ressourcen des verwendeten µControlles gebracht werden. Dazu folgende Betrachtungen:
Bild:Lochscheibe8.jpg|Lochscheibe 8
+
Bild:Lochscheibe12.jpg|Lochscheibe 12
+
Bild:Lochscheibe15.jpg|Lochscheibe 15
+
Bild:Lochscheibe20.jpg|Lochscheibe 20
+
</gallery>
+
  
Wenn 2 phasenversetzte  Lichtschranken je Hell-/ Dunkelzyklus bereits 4 Positionen liefern, benötigt die Lochscheibe nur halb so viel "Löcher" wie eine Lochscheibe mit nur einer Lichtschranke. Eine 15er Lochscheibe liefert demzufolge 15x4 = 60 Positionen auf 360°, das sind 6° je erfasster Position. Entscheidend ist, an welchem Antriebsteil die Lochscheibe montiert ist und mit welcher Untersetzung zwischen Motor und Abtriebswelle(Rad) gearbeitet wird. Ist die Lochscheibe an der Motorwelle angebracht, würde bei einer angenommenen Untersetzung von 10:1 eine erfasste Position nur 0,6° an der Abtriebswelle ausmachen.  
+
Wenn 2 phasenversetzte  Lichtschranken je Hell-/ Dunkelzyklus bereits 4 Positionen liefern, benötigt die Lochscheibe nur halb so viel "Löcher" wie eine Lochscheibe bei Verwendung nur einer Lichtschranke. Eine 15er Lochscheibe liefert demzufolge 15x4 = 60 Positionen auf 360°, das sind 6° je erfasster Position. Entscheidend ist, an welchem Antriebsteil die Lochscheibe montiert ist und mit welcher Untersetzung zwischen Motor und Abtriebswelle(Rad) gearbeitet wird. Ist die Lochscheibe an der Motorwelle angebracht, würde bei einer angenommenen Untersetzung von 10:1 eine erfasste Position nur 0,6° an der Abtriebswelle ausmachen.  
  
Man muss sich klar machen, welche '''Positioniergenauigkeit''' nötig ist. Dabei gilt: Auslegung so genau wie nötig, nicht wie möglich. Weiter muss geklärt werden, wo man die Lochscheibe sinnvoll anbringt. Sie darf im Betrieb weder verschmutzt oder beschädigt werden. Fahrmodelle ziehen Staub, Haare etc. gern an, gut beraten ist man mit einer '''verkapselten Optomechanik'''. Ein weiterer Faktor ist die '''Drehzahl''' (Leerlauf und Vollast) des Motors, weil diese die Frequenz der abzutastenden Signale beeinflusst. Zwischen Drehzahl n [U/min], Frequenz f [Hz] und Teilung T besteht folgender Zusammenhang:
+
Man muss sich klar machen, welche '''Positioniergenauigkeit''' nötig ist. Dabei gilt: Auslegung so genau wie nötig, nicht wie möglich. Weiter muss geklärt werden, wo man die Lochscheibe sinnvoll anbringt. Sie darf im Betrieb weder verschmutzt oder beschädigt werden. Fahrmodelle ziehen Staub, Haare etc. gern an, gut beraten ist man mit einer '''verkapselten Optomechanik'''. Ein weiterer Faktor ist die '''Drehzahl''' (im Leerlauf am höchsten) des Motors, weil diese die Frequenz der abzutastenden Signale beeinflusst. Zwischen Drehzahl n [U/min], Frequenz f [Hz] und Teilung T besteht folgender Zusammenhang:
  
 
'''f = n * T / 60 s'''
 
'''f = n * T / 60 s'''
Zeile 136: Zeile 136:
 
'''f = 474 Hz'''
 
'''f = 474 Hz'''
  
Eine Lichtschranke liefert also ein Rechtecksignal mit f = 474 Hz. Jetzt muss noch das Signal der zweiten Lichtschranke um 90° versetzt darübergelegt werden. Bei idealen Pegeln sind in einer Periode 4 Schaltzustände abzutasten, also muss die Abtastfrequenz mindestens 4-fach über der Grundfrequenz liegen. Da es in der Praxis aber keine idealen Pegel gibt, muss die Abtastfrequenz noch höher ausgelegt werden. Betrachten wir noch mal das Osszillogrammm:
+
Eine Lichtschranke liefert also ein Rechtecksignal mit f = 474 Hz. Jetzt muss noch das Signal der zweiten Lichtschranke um 90° versetzt darübergelegt werden. Bei idealen Pegeln sind in einer Periode 4 Schaltzustände abzutasten, also muss die Abtastfrequenz mindestens 4-fach über der Grundfrequenz liegen. Da es in der Praxis aber keine idealen Pegel gibt, muss die Abtastfrequenz noch höher ausgelegt werden. Betrachten wir noch mal das Oszillogrammm weiter oben:
  
Es fällt auf, das die Zeiten nicht exakt gleich sind, die Zustandszeiten 1 und 3 sind etwas länger als 2 und 4. Das liegt an der Einstellung des Abstandes beider Lichtschranken zueinander, die Phasenlage ist hier nicht genau 90°. Außerdem sind Lochscheibe und Lichtschranken mit kleinen Unregelmäßikeiten, Streuungen, Anstiegs- und Abfallzeiten behaftet, so dass es in einer Periode auch Zeiten gibt, die nicht eindeutig einem der 4 genannten Zustände entsprechen. Für eine sichere Abtastung ist deshalb von der kürzesten (= ungünstigsten) Schaltzeit auszugehen, hier sind es ca. 0,4 Millisekunden, das entspricht 2,5 kHz. Jeder Zustand sollte vom µController schon mindestens 3 bis 4 mal abgetastet werden, so das wir für das Beispiel mindestens ca. 10 kHz Abtastfrequenz einplanen müssen. Als Orientierungshilfe gilt:
+
Es fällt auf, das die Zeiten nicht exakt gleich sind, die Zustandszeiten 1 und 3 sind etwas länger als 2 und 4. Das liegt an der Einstellung des Abstandes beider Lichtschranken zueinander, die Phasenlage ist hier nicht genau 90°. Außerdem sind Lochscheibe und Lichtschranken mit kleinen Unregelmäßikeiten, Streuungen, Anstiegs- und Abfallzeiten behaftet, so dass es in einer Periode auch Zeiten gibt, die nicht eindeutig einem der 4 genannten Zustände entsprechen. Für eine sichere Abtastung ist deshalb von der kürzesten (= ungünstigsten) Schaltzeit auszugehen, hier sind es ca. 0,4 Millisekunden, das entspricht 2,5 kHz. Jeder Zustand sollte vom µController sicherheitshalber schon 3 bis 4 mal abgetastet werden, so das wir für das Beispiel mindestens ca. 10 kHz Abtastfrequenz einplanen müssen. Als Orientierungshilfe gilt:
  
 
'''Abtastfrequenz >= 20 * Frequenz Lichtschranke'''
 
'''Abtastfrequenz >= 20 * Frequenz Lichtschranke'''
  
Die Abtastung muss sicher sein, auch wenn das Hauptprogramm gerade mit anderen Dingen als der Lochscheibenauswertung beschäftigt ist. Man kann zwar die Lochscheibe vom Hauptprogramm durchaus mit abfragen lassen, aber dann sollten keine anderen zeitraubenden Prozeduren darin enthalten sein. Ist nur ein Zustandswechsel ausgelassen wurden, geht es erst an der nachfolgenden gleichen Hell-/Dunkel-Kombination weiter und der Contoller verzählt sich um 4 Inkremente! Deshalb sollte die TimerInterrupt-Variante vorgezogen oder die Abtastung in einen separaten µController ausgelagert werden.
+
Entsprechend der gewünschten Positioniergenauigkeit und Drehzahl kann nun die Teilung der Lochscheibe so gewählt werden, das die Lichtschrankensignale vom µController abgetastet werden können. Da Kaufteile aus dem Industriebereich oft eine recht hohe Teilung vorgeben, ist es manchmal besser, mit kleineren Teilungen anzufangen. Rechts sind Vorlagen, die man sich auf Folien ausdrucken kann.(Nähere Beschreibung im Praxis-Teil)
  
Der Positionsbereich muss schließlich auch in einer Variablen dargestellt werden. Im Beispiel mit Teilung=12 wird der Positionzähler bei einer Motorumdrehung um 48 Inkremente hochgezählt. Bei 2370 U/min wäre eine 16Bit-Variable nach ca. 34 Sekunden übergelaufen. Demzufolge ist auch das Speichervolumen der Positionsvariablen dem tatsächlichen Fahrbereich anzupassen. Man kann auch Ober-/ Untergrenzen definieren, die bei Erreichen den Antrieb anhalten. Somit wird ein mechanisches Überfahren von Endlagen oder ein logisches Überlaufen von Variablen verhindert.
+
Die Abtastung muss sicher sein, auch wenn das Hauptprogramm gerade mit anderen Dingen als der Lochscheibenauswertung beschäftigt ist. Man kann zwar die Lochscheibe vom Hauptprogramm durchaus mit abfragen lassen, aber dann sollten keine anderen zeitraubenden Prozeduren darin enthalten sein. Ist nur ein Zustandswechsel übersehen und ausgelassen wurden, geht es erst an der nachfolgenden gleichen Hell-/Dunkel-Kombination weiter und der Contoller verzählt sich um 4 Inkremente! Deshalb sollte die TimerInterrupt-Variante vorgezogen oder die Abtastung in einen separaten µController ausgelagert werden.
 +
 
 +
Der Positionsbereich muss schließlich auch in einer Variablen dargestellt werden. Im Beispiel mit Teilung =12 wird der Positionzähler bei einer Motorumdrehung um 48 Inkremente hochgezählt. Bei 2370 U/min wäre eine 16Bit-Variable nach ca. 34 Sekunden übergelaufen. Demzufolge ist auch das Speichervolumen der Positionsvariablen dem tatsächlichen Fahrbereich anzupassen. Man kann auch Ober-/ Untergrenzen definieren, die bei Erreichen den Antrieb anhalten. Somit wird ein mechanisches Überfahren von Endlagen oder ein logisches Überlaufen von Variablen verhindert.
  
  
Zeile 158: Zeile 160:
 
|}
 
|}
  
 +
== Kalibrierung ==
  
 +
Im einfachsten Fall fährt man seinem Antrieb auf eine Referenzmarke (Nonius, Paßstift o.ä.) und setzt dort den Positionszähler zurück.
 +
 +
Wer es noch genauer will, muß auch noch die Lochscheibe in eine definierte Ausgangsstellung bringen. Dazu kann man die Lichtschrankensignale mit 2 LEDs optisch anzeigen. In der Kalibrierstellung müssen dann der Antrieb auf der Refernzmarke stehen und beide LEDs leuchten. Als Referenzmarke kann natürlich auch eine zusätzliche Lichtschranke dienen, die eine kleine Bohrung am Antrieb erkennt. Wichtig ist, dass die Referenzmarke nur einmal und eindeutig am Antrieb angebracht ist.
  
== Kalibrierung ==
 
 
== Geschwindigkeit und Beschleunigung ==
 
== Geschwindigkeit und Beschleunigung ==
== Baustelle ==
+
 
 +
Geschwindigkeit wird meist in [m/s], [km/h] oder [mph] ausgedrückt, also der Wegstrecke je Zeiteinheit. Im µController interessieren uns diese Einheiten erst mal nicht, hier werden Inkremente je Zeiteinheit gezählt. Die Zeitintervalle, in denen die Inkremente ausgewertet werden, liefert wieder ein TimerInterrupt. Dieser ist mit deutlich längeren Zyklen auszulegen, damit auch genügend Inkremente je Zyklus gezählt werden können. Im Code-Beispiel unten werden bei 16Mhz CPU-Takt die Vorteiler 1 und 1024 für die TimerInterrupt´s verwendet: Timer 0 mit Prescaler =1024 für die Geschwindigkeitsberechnung mit ca. 61 Hz und Timer 2 mit Prescaler =1 für die Abtastung der Lichtschranken mit 62,5 kHz. Die Geschwindigkeitsmessung wurde mit 12er, 15er und 18er Teilung getestet. In der ISR des Timer_0 Overflow wird die Differenz aus aktueller Position und der Position des vergangenen Zyklus gebildet. Da diese Wegdifferenz in definierten Zeitabständen ermittelt wird, hat man hier bereits die Geschwindigkeit in n Inkremente je 0,01638 Sekunden. Mit dieser etwas abstrakten Geschwindigkeitseinheit wird im Hauptprogramm der Motor gesteuert.
 +
 
 +
Das gleiche Verfahren ist auch für die Beschleunigung anwendbar. Die Beschleunigung ist die Geschwindigkeitsänderung je Zeiteinheit. In der ISR des Timer_0 Overflow kann die Differenz aus aktueller Geschwindigkeit und der Geschwindigkeit des vergangenen Zyklus gebildet werden, um so die Beschleunigung zu erhalten. Die Einheit ist wieder etwas ungewohnt: Inkremente je 0,01638 Sekunden in 0,01638 Sekunden, also Inkremente/Quadratsekunden. Voraussetzung für eine vernünftige Beschleunigungsermittlung ist, das eine genügend hohe Auflösung der Geschwindigkeit vorliegt(=hohe Teilung der Lochscheibe). Ansonsten sind die ermittelten Werte zu klein und liegen, je nach Trägheit des Motors, fast immer bei 0, 1, 2 oder maximal 3.
 +
 
 +
Vorteil der Differenzmethode ist, man kann die Geschwindigkeit in einer 8Bit-Variable mit Vorzeichen ausdrücken. Die Werte des Beispieles lagen je nach Teilung zwischen -50 und +50 und sind für die Motorsteuerung ausreichend. Bessere Auflösung erfordert höhere Teilung, höhere Abtastrate, höhere CPU-Frequenz.
 +
 
 +
== Praxis==
 +
 
 +
=== Herstellung der Lochscheibe ===
 +
Für eigene Projekte ist es mitunter schwer, Lochscheiben in passender Größe und Teilung zu finden. Oft müssen dann Kompromisse in der Drehzahlsteuerung oder Positionierung gemacht werden, weil die vielleicht günstigere Teilung nicht zu beschaffen ist.
 +
 
 +
Hier wird deshalb ein Selbstbau von preiswerten Lochscheiben vorgestellt: Man trägt in einer Excel-Tabelle z.B. 18 mal die Zahl 20 ein und markiert diesen Zellbereich. Anschließend erstellt man mit dem Diagramm-Assistent ein Ring-Diagramm. Darin muss man nun jeden Datenpunkt einzeln formatieren und abwechslend die Farbe schwarz und weiß zuordnen. Markiert man die komplette Datenreihe, kann man unter 'Formatieren'>'Optionen' auch die Innenringgröße einstellen. Dieses Ring-Diagramm kann nun beliebig kopiert und vergößert oder verkleinert werden, auch die Datenreihe kann auf z.B. 24x15 oder 30x12 angepasst werden. So lassen sich auf einer A4-Seite einige Dutzend Lochscheiben in allen Größen und Teilungen herstellen. Das fertige Arbeitsblatt muss nun noch mit geeigneter Tinte auf Folie ausgedruckt werden. Den Drucker muss man möglichst auf satte Farbe und kräftgen Kontrast einstellen. Zum Schluß wird die ausgedruckte Folie mit A4- Laminierfolie verstärkt, wer kein Laminiergerät hat, geht in einen Copy-Shop o.ä.
 +
 
 +
Die so gewonnenen Lochscheiben werden nun ausgeschnitten und bei Bedarf mit einem Heißluftgerät noch etwas "nachgebacken", bevor sie im eigenen Projekt mit Kraftkleber auf ein kleines Rad aufgeklebt werden. Hierbei auf gute Zentrierung achten, damit die Lochscheibe möglichst rund läuft. Sekundenkleber ist deshalb ungeeignet, weil kaum Zeit für Korrektur und Einstellung bleibt.
 +
 
 +
=== Anpassen der Lichtschranke ===
 +
 
 +
Baustelle:
 +
 
 +
Fotos, Anregungen zum Nachbau, Beschaffung, Erfahrungen
 +
 
 
weiterführende Informationen:
 
weiterführende Informationen:
 
[http://de.wikipedia.org/wiki/Inkrementalgeber Inkrementalgeber]
 
[http://de.wikipedia.org/wiki/Inkrementalgeber Inkrementalgeber]
 +
 +
=== Quellcode ===
 +
 +
<pre>
 +
 +
//Deklaration global
 +
volatile uint8_t Zust_Li;            //Zustandsmerker Position linker Motor
 +
volatile uint16_t Li_Inkr;          //aktuelle Position linker Motor
 +
volatile uint16_t old_Li_Inkr;      //Position im vorangegangenen Takt
 +
volatile int8_t Speed_Li_Ist;        //Wegänderung je Takt, in ISR Timer 0
 +
 +
...
 +
 +
// Interrupt-Service-Routine  Timer_0 Overflow
 +
SIGNAL (SIG_OVERFLOW0)
 +
{
 +
  // ISR-Code  61,035 Pro Sekunde
 +
  Timeout++;
 +
  Speed_Li_Ist = Li_Inkr - old_Li_Inkr;
 +
  old_Li_Inkr = Li_Inkr;
 +
}
 +
 +
 +
// Interrupt-Service-Routine  Timer_2 Overflow
 +
SIGNAL (SIG_OVERFLOW2)
 +
{
 +
  // ISR-Code  62.5 kHz
 +
  // 4 Zustaende durch jeweils 1 Bit repräsentiert (1,2,4,8)
 +
  // Lichtschranke A liegt an Port A.0
 +
  // Lichtschranke B liegt an Port A.1
 +
 +
  if ( (Zust_Li == 1) && ( !(PINA & (1<<PINA0)) )&& ( PINA & (1<<PINA1) ) ){
 +
    Li_Inkr = Li_Inkr + 1;
 +
    Zust_Li = 2;
 +
  } /* end if */
 +
 +
  if ( (Zust_Li == 1) && (PINA & (1<<PINA0) )&& ( !( PINA & (1<<PINA1)) ) ){
 +
    Li_Inkr = Li_Inkr - 1;
 +
    Zust_Li = 8;
 +
  } /* end if */
 +
 +
  if ( (Zust_Li == 2) && (PINA & (1<<PINA0) )&& ( PINA & (1<<PINA1) ) ){
 +
    Li_Inkr = Li_Inkr + 1;
 +
    Zust_Li = 4;
 +
  } /* end if */
 +
 +
  if ( (Zust_Li == 2) && ( !(PINA & (1<<PINA0)) )&& ( !( PINA & (1<<PINA1)) ) ){
 +
    Li_Inkr = Li_Inkr - 1;
 +
    Zust_Li = 1;
 +
  } /* end if */
 +
 +
  if ( (Zust_Li == 4) && (PINA & (1<<PINA0) )&& ( !( PINA & (1<<PINA1)) ) ){
 +
    Li_Inkr = Li_Inkr + 1;
 +
    Zust_Li = 8;
 +
  } /* end if */
 +
 +
  if ( (Zust_Li == 4) && ( !(PINA & (1<<PINA0)) )&& ( PINA & (1<<PINA1) ) ){
 +
    Li_Inkr = Li_Inkr - 1;
 +
    Zust_Li = 2;
 +
  } /* end if */
 +
 +
  if ( (Zust_Li == 8) && ( !(PINA & (1<<PINA0)) )&& ( !( PINA & (1<<PINA1)) ) ){
 +
    Li_Inkr = Li_Inkr + 1;
 +
    Zust_Li = 1;
 +
  } /* end if */
 +
 +
  if ( (Zust_Li == 8) && (PINA & (1<<PINA0) )&& ( PINA & (1<<PINA1) ) ){
 +
    Li_Inkr = Li_Inkr - 1;
 +
    Zust_Li = 4;
 +
  } /* end if */
 +
 +
}
 +
 +
...
 +
 +
int main (void)
 +
{
 +
 +
//Init
 +
TCCR2 |= (1<<CS20);                  //Prescaler = 1 (16MHz/1 = 16000000) ->
 +
                                    //16000000/256 -> 62500 Interrupts je Sekunde
 +
 +
TCCR0 |= (1<<CS02)|(1<<CS00);        //Prescaler = 1024  (16000000 / 1024 = 15625) ->
 +
                                    //15625/256 = 61,035  -> 61 Interrupts je Sekunde
 +
 +
TIMSK |= (1<<TOIE0)|(1<<TOIE2);      //Timer Overflow Interrupt Enablae für Timer 0 und 2
 +
 +
 +
Li_Inkr = 32000;Zust_Li = 1;        // Kalibrierstellung bei 32000
 +
sei();                              // Interrupts aktivieren
 +
 +
 +
  while(1)
 +
  {
 +
 +
  // hier kann Position und Geschwindigkeit ausgewertet werden
 +
 +
  }
 +
}
 +
 +
</pre>
  
 
= Vor und Nachteile der Messmethoden=
 
= Vor und Nachteile der Messmethoden=

Aktuelle Version vom 29. Juni 2013, 22:51 Uhr


Ermitteln der Drehzahl und Wegstrecke in Abhängigkeit einer Winkeländerung oder Impulsfolge in einer Abgelaufenen Zeit

  • Messen der Drehzahl nach jedem Impuls, also in Abhängigkeit einer Winkeländerung.
  • Messen der Drehzahl durch Zählen der Impulse nach Ablauf einer bestimmten Zeit.
  • Richtung, Geschwindigkeit und Position mit Doppellichtschranke ermitteln
Dieser Artikel ist noch lange nicht vollständig. Der Auto/Initiator hofft das sich weitere User am Ausbau des Artikels beteiligen.

Das Ergänzen ist also ausdrücklich gewünscht! Besonders folgende Dinge würden noch fehlen:

Mehr Grundlagen und vor allem mal praktische Programmbeispiele / Algorithmen etc.


Messen der Drehzahl nach jedem Impuls

Dieser Teil beschäftigt sich vor allem mit der Optischen Drehzahlmessung mit Hilfe einer Lochscheibe und Gabellichtschranke berechnet über die Periodendauer ohne Drehrichtungserkennung.

Testaufbau mit einer 32er Lochscheibe
GP1S23 Gabellichtschranke Bild: Conrad Electronic


Einführung

Am einfachsten ist Impulse direkt an einer Bürste eines Motors zu zählen. Siehe dazu: http://www.roboternetz.de/community/...einem-DC-Motor .

Die Winkelgeschwindigkeit ist die Winkeländerung pro Zeiteinheit. Mit der Lichtschranke und den geometrischen Daten der Lochscheibe kann man nun relativ einfach die Zeit für eine bestimmte Winkeländerung messen. Die Lochscheibe gibt uns die Winkeländerung bei einer Periode vor, bei einer 32er Lochscheibe wären das 11,25° pro Periode , wie in den Bildern vom Oszilloskop zu sehen ändert sich natürlich bei Änderung der Drehzahl die Periodendauer, die Winkeländerung pro Periode ist aber konstant da diese durch die Lochscheibe vor gegeben ist.

Um die Periodendauer zu messen verwende ich den ICP1 (Input Capture Pin) eines Atmega8 der bei steigender Flanke den Timer1 ausliest und in das ICR1 Register schreibt. Läuft der Mikrocontroller auf 8Mhz und wir stellen den Vorteiler des Timers auf 8 so bekommen wir die Periodendauer in µs als Wert.

Auslegen der Lochscheibe

In den meisten Fällen definieren der mechanische Aufbau den Durchmesser der Lochscheibe und die Drehzahl die Teilung (Anzahl der Löcher). Der µContoller und die Gabellichtschranke müssen die Impulse auch erfassen und verarbeiten können. Wenn man das Drehzahlband abschätzen kann ist es hilfreich, sich schon Gedanken um die Programmierung zu machen, denn bei hohen Drehzahlen springt der µC jedes mal in die Interrupt Service Routine rein, sofern man es so programmiert wie im Beispiel. Bei hohen Drehzahlen sollte die Teilung somit gröber, bei niedriger Drehzahl die Teilung feiner sein.

Lochscheibe abgerollt mit idealisiertem Signal

Berechnungen

Hier folgt nun die Berechnung über die Periodendauer, beachten sollte man das im Bogenmaß gerechnet wird, ein Winkel mit dem Bogenmaß 1 rad hat ein Gradmaß von ca. 57,3°. 11.25° sind also ca. 0,196 rad, das führt später natürlich zu unschönen Rechenoperationen im µC, Stichwort Festkommaarithmetik.

Nach dem Umstellen kommt man aber auf eine recht handliche Formel [math]n = \frac{\varphi }{dt \cdot 360}[/math]

Es ist auch eine Überlegung wert, ob man die Drehzahl nicht umrechnet sondern mit der Periodendauer arbeitet. Das ist zwar nicht so geläufig aber das stört den µController nicht. Mit einem Kalkulationsprogramm kann man die Umrechnung von Periodendauer in Drehzahl auch extern vornehmen.

Man sollte sich auch klar machen, das zumindest ein 8-Bit Prozessor am besten mit Ganzzahlen zwischen 0 und 255 oder 0 und 65535 zurechtkommt. Für die Teilung der Lochscheibe bieten sich deshalb Werte wie 90, 72, 45, 36, 30, 24, 20, 18, 15, 12, 10 und 8 an. Verwendet man an Stelle der dargestellten 32er Lochscheibe eine 30er oder 36er Scheibe, kann man zumindest mit ganzzahligen Gradzahlen rechnen. "Krumme Werte" wie Pi = 3,1415..., Radiant = 57,29577...° usw. sollten eine seltene Ausnahme in der Programmierung sein.

Messen der Drehzahl durch zählen der Impulse

Dieser Teil beschäftigt sich mit der Optischen Drehzahlmessung mit Hilfe einer Lochscheibe und Gabellichtschranke berechnet über die die Anzahl der Impulse in einer gewissen Zeit.

Die meisten µC bieten die Möglichkeit über einen Eingang direkt mit der Hardware externe Pulse zu zählen (z.B. beim AVR der Eingang T1). Über eine vorgegeben Zeit von z.B. 1 Sekunde wird über den externen Eingang die Zahl der Pulse gezählt. Die Drehzahl ergibt sich dann einfach auch der Zahl der Impulse geteilt durch die Zahl der Löcher in der Scheibe und die Zeit für die Messung. Da die Zahl der Löcher und die Zeit konstant sind, erhält man direkt einen Wert proportional zur Drehzahl. Auch ist bei geeigneter Hardware die Belastung für die CPU gering, es werden aber i.A. 2 Timer benötigt: der eine für das Zählen der Impulse und der andere für die Festlegung des Zeitintervalls. Das Zeitintervall muss als Kompromiss zwischen Aktualisierungsfrequenz und Auflösung gewählt werden: mit einer Scheibe mit 32 Löchern erhält man in einer Sekunde ein Auflösung von 1/32 Umdrehungen pro Sekunde oder bei 1/32 Sekunde nur noch 1 Umdrehung pro Sekunde als Auflösung. Geeignet ist diese Methode vor allem für schnell kommende Pulse, also hohe Drehzahlen bzw. Lochscheiben mit vielen Löchern, da so in der Messzeit genügend Pulse für eine ausreichende Auflösung kommen.

Richtung, Geschwindigkeit und Position mit Doppellichtschranke ermitteln

Dieser Teil beschäftigt sich mit der Optischen Drehzahl- und Geschwindigkeitsmessung sowie der Erfassung von Drehrichtung und zurückgelegter Position mit Hilfe einer Lochscheibe und 2 Gabellichtschranken. Hierfür werden Quadratursignale in definierten Zeitabständen ausgewertet.

Einführung

Für kontrollierte Bewegungen ist es mitunter wichtig, auch die Drehrichtung/Richtungswechsel und Position auszuwerten. Eine Lochscheibe mit einer Gabellichtschranke liefert lediglich Rechteckimpulse, egal wie rum sich die Lochscheibe bewegt. Bringt man eine zweite Gabellichtschranke an der gleichen Lochscheibe leicht versetzt an, bekommt man auch die Drehrichtung mit. Diese Methode ist altbekannt, simpel und leicht nachzubauen. Wenn man die Drehrichtung kennt, ist auch die Position kein Problem mehr. Ausgehend von einer Kalibrierposition können bei Vorwärtsbewegung Inkremente hochgezählt oder bei Rückwärtsbewegung runtergezählt werden.

Interessierte nehmen dazu mal eine PC-Maus mit Kugelantrieb zur Hand. Darin findet man zwei kleine Lochscheiben, die für die X- und Y-Richtung die Impulse erzeugen. Durch spezielle Gabellichtschranken mit 2 phasenversetzten Ausgängen wird auch die Drehrichtung erkannt.

Das selbe Prinzip ist in linearer Form auch in PC-Druckern zu finden: Entlang des Wagenrücklaufes ist ein transparentes Kunsstoffband gespannt, auf dem winzig kleine Streifenmuster aufgebracht sind. Diese werden von einer Gabellichtschranke mit 2 Ausgängen erkannt und so die Wagenposition gesteuert.

Aber es geht natürlich noch einfacher...

Zwei Lichtschranken liefern vier Zustände

Zustandsfolge bei Vorwärtsbewegung
Zustandsfolge bei Rückwärtsbewegung
2 Lichtschranken (LSA und LSB) liefern phasenversetzte Rechtecksignale. In Vorwärts- und Rückwärtsrichtung ergeben sich unterschiedliche Zustandsfolgen

Man nimmt 2 normale Gabellichtschranken und bringt sie so an, das sie im 1,5 fachen Lochabstand die Lochscheibe durchleuchten. Wenn sich Lichtschranke A in der Mitte des Lichtstreifens befindet, ist Lichtschranke B an der Grenze des Schattenstreifens. Nebenstehende Skizzen zeigen die möglichen Zustände beider Lichtschranken bei Vorwärts- und Rückwärtsbewegung der Lochscheibe. Wichtig ist hierbei, das die Lochscheibe in etwa gleich breite Licht- und Schattensegmente eingeteilt ist und die Lichtschranke(n) einen möglichst haarfeinen Lichtstrahl besitzt. Die Signale der Fototransistoren sollten verstärkt und gegebenenfalls mit TTL-Bausteinen zu korrekten High- und Low-Pegeln aufbereitet werden.


Es ergeben sich nun folgende Kombinationen:

  • Zustand 1: LSA = hell und LSB = hell
  • Zustand 2: LSA = hell und LSB = dunkel
  • Zustand 3: LSA = dunkel und LSB = dunkel
  • Zustand 4: LSA = dunkel und LSB = hell

Dreht man die Lochscheibe weiter, wiederholt sich der Vorgang. Die Zustandsfolge ist 1 > 2 > 3 > 4 > 1 > 2 > 3 > 4 > usw.


Bei entgegengesetzter Drehrichtung ändert sich diese Reihenfolge. Betrachtet man wieder vom Zustand 1 ausgehend die Gegenrichtung, ergeben sich nun diese Kombinationen:

  • Zustand 1: LSA = hell und LSB = hell
  • Zustand 4: LSA = dunkel und LSB = hell
  • Zustand 3: LSA = dunkel und LSB = dunkel
  • Zustand 2: LSA = hell und LSB = dunkel

Die Zustandsfolge in Gegenrichtung lautet dann: 1 < 4 < 3 < 2 < 1 < 4 < 3 < 2 < usw.


Mit diesem Wissen ist es nun ein Kinderspiel, auch die Änderung der Drehrichtung festzustellen. Dazu muss der letzte Zustand in einer Variable gespeichert und mit dem neu erkannten Zustand verglichen werden. Folgt nach Zustand 1 der Zustand 2, so ist es eine Vorwärtsbewegung. Folgt dem Zustand 1 der Zustand 4, so ist es eine Rückwärtsbewegung. Gleiches Prinzip gilt auch für die restlichen Zustände 2, 3 und 4.

Positionsüberwachung

Von jedem der 4 Zustände gibt es also zwei zu unterscheidende Fälle: Vorwärts und Rückwärts. Insgesamt müssen demzufolge 8 Bedingungen zyklisch abgetastet und ein Positionszähler entsprechend inkrementiert oder dekrementiert werden und schon hat man eine exakte Streckeninformation. In Worte gefasst ergibt sich folgende Logik:

Ausgangszustand: Beide Lichtschranken sind aus (A=0 UND B=0) und Zustand =1

  • WENN (Zustand=1 UND A=0 UND B=1) DANN: Setze Zustand=2, Position inkrementieren, Vor
  • WENN (Zustand=1 UND A=1 UND B=0) DANN: Setze Zustand=4, Position dekrementieren, Rück
  • WENN (Zustand=2 UND A=1 UND B=1) DANN: Setze Zustand=3, Position inkrementieren, Vor
  • WENN (Zustand=2 UND A=0 UND B=0) DANN: Setze Zustand=1, Position dekrementieren, Rück
  • WENN (Zustand=3 UND A=1 UND B=0) DANN: Setze Zustand=4, Position inkrementieren, Vor
  • WENN (Zustand=3 UND A=0 UND B=1) DANN: Setze Zustand=2, Position dekrementieren, Rück
  • WENN (Zustand=4 UND A=0 UND B=0) DANN: Setze Zustand=1, Position inkrementieren, Vor
  • WENN (Zustand=4 UND A=1 UND B=1) DANN: Setze Zustand=3, Position dekrementieren, Rück
Lochscheibe 8
Lochscheibe 10
Lochscheibe 12
Lochscheibe 15
Lochscheibe 18
Lochscheibe 20


Diese Prüfung muss ständig wiederholt werden, damit alle Pegelwechsel der beiden Lichtschranken erfasst werden. Nur so ist es möglich, die exakte Position zu verfolgen. Dafür bieten sich 2 Möglichkeiten: Entweder die Prüfung wird im Hauptprogramm ständig durchlaufen bzw. ein Timer-Interrupt tastet regelmäßig die Lichtschranken ab oder ein Interrupt reagiert auf eine Änderung der Leichtschranken und die Auswertung erfolgt nach jeder Änderung. Die Art der Auswertung kann in allen Fällen gleich sein - lediglich wann und wie oft sie aufgerufen wird ist verschieden. Hier soll nur die Interruptvariante betrachtet werden, weil sie mehr Vorteile bringt. Weiter unten im Artikel ist dazu ein Beispiel in Sprache C zu finden.

Zuvor muss aber eine sinnvolle Auslegung von Lochscheibe, Drehzahl und Positionsbereich gefunden und in Einklang mit den Ressourcen des verwendeten µControlles gebracht werden. Dazu folgende Betrachtungen:

Wenn 2 phasenversetzte Lichtschranken je Hell-/ Dunkelzyklus bereits 4 Positionen liefern, benötigt die Lochscheibe nur halb so viel "Löcher" wie eine Lochscheibe bei Verwendung nur einer Lichtschranke. Eine 15er Lochscheibe liefert demzufolge 15x4 = 60 Positionen auf 360°, das sind 6° je erfasster Position. Entscheidend ist, an welchem Antriebsteil die Lochscheibe montiert ist und mit welcher Untersetzung zwischen Motor und Abtriebswelle(Rad) gearbeitet wird. Ist die Lochscheibe an der Motorwelle angebracht, würde bei einer angenommenen Untersetzung von 10:1 eine erfasste Position nur 0,6° an der Abtriebswelle ausmachen.

Man muss sich klar machen, welche Positioniergenauigkeit nötig ist. Dabei gilt: Auslegung so genau wie nötig, nicht wie möglich. Weiter muss geklärt werden, wo man die Lochscheibe sinnvoll anbringt. Sie darf im Betrieb weder verschmutzt oder beschädigt werden. Fahrmodelle ziehen Staub, Haare etc. gern an, gut beraten ist man mit einer verkapselten Optomechanik. Ein weiterer Faktor ist die Drehzahl (im Leerlauf am höchsten) des Motors, weil diese die Frequenz der abzutastenden Signale beeinflusst. Zwischen Drehzahl n [U/min], Frequenz f [Hz] und Teilung T besteht folgender Zusammenhang:

f = n * T / 60 s

Beispiel: Ein Motor dreht im Leerlauf mit 2370 U/min und hat eine Lochscheibe mit Teilung = 12 an der Motorwelle. Die Frequenz der abzutastenden Signale einer Lichtschranke soll ermittelt werden. (oben im Osszillogramm dargestellt)

f = 2370 * 12 / 60 s

f = 474 Hz

Eine Lichtschranke liefert also ein Rechtecksignal mit f = 474 Hz. Jetzt muss noch das Signal der zweiten Lichtschranke um 90° versetzt darübergelegt werden. Bei idealen Pegeln sind in einer Periode 4 Schaltzustände abzutasten, also muss die Abtastfrequenz mindestens 4-fach über der Grundfrequenz liegen. Da es in der Praxis aber keine idealen Pegel gibt, muss die Abtastfrequenz noch höher ausgelegt werden. Betrachten wir noch mal das Oszillogrammm weiter oben:

Es fällt auf, das die Zeiten nicht exakt gleich sind, die Zustandszeiten 1 und 3 sind etwas länger als 2 und 4. Das liegt an der Einstellung des Abstandes beider Lichtschranken zueinander, die Phasenlage ist hier nicht genau 90°. Außerdem sind Lochscheibe und Lichtschranken mit kleinen Unregelmäßikeiten, Streuungen, Anstiegs- und Abfallzeiten behaftet, so dass es in einer Periode auch Zeiten gibt, die nicht eindeutig einem der 4 genannten Zustände entsprechen. Für eine sichere Abtastung ist deshalb von der kürzesten (= ungünstigsten) Schaltzeit auszugehen, hier sind es ca. 0,4 Millisekunden, das entspricht 2,5 kHz. Jeder Zustand sollte vom µController sicherheitshalber schon 3 bis 4 mal abgetastet werden, so das wir für das Beispiel mindestens ca. 10 kHz Abtastfrequenz einplanen müssen. Als Orientierungshilfe gilt:

Abtastfrequenz >= 20 * Frequenz Lichtschranke

Entsprechend der gewünschten Positioniergenauigkeit und Drehzahl kann nun die Teilung der Lochscheibe so gewählt werden, das die Lichtschrankensignale vom µController abgetastet werden können. Da Kaufteile aus dem Industriebereich oft eine recht hohe Teilung vorgeben, ist es manchmal besser, mit kleineren Teilungen anzufangen. Rechts sind Vorlagen, die man sich auf Folien ausdrucken kann.(Nähere Beschreibung im Praxis-Teil)

Die Abtastung muss sicher sein, auch wenn das Hauptprogramm gerade mit anderen Dingen als der Lochscheibenauswertung beschäftigt ist. Man kann zwar die Lochscheibe vom Hauptprogramm durchaus mit abfragen lassen, aber dann sollten keine anderen zeitraubenden Prozeduren darin enthalten sein. Ist nur ein Zustandswechsel übersehen und ausgelassen wurden, geht es erst an der nachfolgenden gleichen Hell-/Dunkel-Kombination weiter und der Contoller verzählt sich um 4 Inkremente! Deshalb sollte die TimerInterrupt-Variante vorgezogen oder die Abtastung in einen separaten µController ausgelagert werden.

Der Positionsbereich muss schließlich auch in einer Variablen dargestellt werden. Im Beispiel mit Teilung =12 wird der Positionzähler bei einer Motorumdrehung um 48 Inkremente hochgezählt. Bei 2370 U/min wäre eine 16Bit-Variable nach ca. 34 Sekunden übergelaufen. Demzufolge ist auch das Speichervolumen der Positionsvariablen dem tatsächlichen Fahrbereich anzupassen. Man kann auch Ober-/ Untergrenzen definieren, die bei Erreichen den Antrieb anhalten. Somit wird ein mechanisches Überfahren von Endlagen oder ein logisches Überlaufen von Variablen verhindert.


Zusammenfassung:

  1. Welche Positionsgenauigkeit brauch ich?
  2. Sind Lochscheibe und Optik vor Störeinflüssen geschützt?
  3. Welche maximale Drehzahl muss noch sicher abgetastet werden?
  4. Frequenz Lichtschranke anpassen: Hohe Drehzahl mit kleiner Teilung / geringe Drehzahl mit großer Teilung
  5. Phasenlage richtig eingestellt? Optimal sind 90°
  6. Positionsvariable mit genügend Speichervolumen?

Kalibrierung

Im einfachsten Fall fährt man seinem Antrieb auf eine Referenzmarke (Nonius, Paßstift o.ä.) und setzt dort den Positionszähler zurück.

Wer es noch genauer will, muß auch noch die Lochscheibe in eine definierte Ausgangsstellung bringen. Dazu kann man die Lichtschrankensignale mit 2 LEDs optisch anzeigen. In der Kalibrierstellung müssen dann der Antrieb auf der Refernzmarke stehen und beide LEDs leuchten. Als Referenzmarke kann natürlich auch eine zusätzliche Lichtschranke dienen, die eine kleine Bohrung am Antrieb erkennt. Wichtig ist, dass die Referenzmarke nur einmal und eindeutig am Antrieb angebracht ist.

Geschwindigkeit und Beschleunigung

Geschwindigkeit wird meist in [m/s], [km/h] oder [mph] ausgedrückt, also der Wegstrecke je Zeiteinheit. Im µController interessieren uns diese Einheiten erst mal nicht, hier werden Inkremente je Zeiteinheit gezählt. Die Zeitintervalle, in denen die Inkremente ausgewertet werden, liefert wieder ein TimerInterrupt. Dieser ist mit deutlich längeren Zyklen auszulegen, damit auch genügend Inkremente je Zyklus gezählt werden können. Im Code-Beispiel unten werden bei 16Mhz CPU-Takt die Vorteiler 1 und 1024 für die TimerInterrupt´s verwendet: Timer 0 mit Prescaler =1024 für die Geschwindigkeitsberechnung mit ca. 61 Hz und Timer 2 mit Prescaler =1 für die Abtastung der Lichtschranken mit 62,5 kHz. Die Geschwindigkeitsmessung wurde mit 12er, 15er und 18er Teilung getestet. In der ISR des Timer_0 Overflow wird die Differenz aus aktueller Position und der Position des vergangenen Zyklus gebildet. Da diese Wegdifferenz in definierten Zeitabständen ermittelt wird, hat man hier bereits die Geschwindigkeit in n Inkremente je 0,01638 Sekunden. Mit dieser etwas abstrakten Geschwindigkeitseinheit wird im Hauptprogramm der Motor gesteuert.

Das gleiche Verfahren ist auch für die Beschleunigung anwendbar. Die Beschleunigung ist die Geschwindigkeitsänderung je Zeiteinheit. In der ISR des Timer_0 Overflow kann die Differenz aus aktueller Geschwindigkeit und der Geschwindigkeit des vergangenen Zyklus gebildet werden, um so die Beschleunigung zu erhalten. Die Einheit ist wieder etwas ungewohnt: Inkremente je 0,01638 Sekunden in 0,01638 Sekunden, also Inkremente/Quadratsekunden. Voraussetzung für eine vernünftige Beschleunigungsermittlung ist, das eine genügend hohe Auflösung der Geschwindigkeit vorliegt(=hohe Teilung der Lochscheibe). Ansonsten sind die ermittelten Werte zu klein und liegen, je nach Trägheit des Motors, fast immer bei 0, 1, 2 oder maximal 3.

Vorteil der Differenzmethode ist, man kann die Geschwindigkeit in einer 8Bit-Variable mit Vorzeichen ausdrücken. Die Werte des Beispieles lagen je nach Teilung zwischen -50 und +50 und sind für die Motorsteuerung ausreichend. Bessere Auflösung erfordert höhere Teilung, höhere Abtastrate, höhere CPU-Frequenz.

Praxis

Herstellung der Lochscheibe

Für eigene Projekte ist es mitunter schwer, Lochscheiben in passender Größe und Teilung zu finden. Oft müssen dann Kompromisse in der Drehzahlsteuerung oder Positionierung gemacht werden, weil die vielleicht günstigere Teilung nicht zu beschaffen ist.

Hier wird deshalb ein Selbstbau von preiswerten Lochscheiben vorgestellt: Man trägt in einer Excel-Tabelle z.B. 18 mal die Zahl 20 ein und markiert diesen Zellbereich. Anschließend erstellt man mit dem Diagramm-Assistent ein Ring-Diagramm. Darin muss man nun jeden Datenpunkt einzeln formatieren und abwechslend die Farbe schwarz und weiß zuordnen. Markiert man die komplette Datenreihe, kann man unter 'Formatieren'>'Optionen' auch die Innenringgröße einstellen. Dieses Ring-Diagramm kann nun beliebig kopiert und vergößert oder verkleinert werden, auch die Datenreihe kann auf z.B. 24x15 oder 30x12 angepasst werden. So lassen sich auf einer A4-Seite einige Dutzend Lochscheiben in allen Größen und Teilungen herstellen. Das fertige Arbeitsblatt muss nun noch mit geeigneter Tinte auf Folie ausgedruckt werden. Den Drucker muss man möglichst auf satte Farbe und kräftgen Kontrast einstellen. Zum Schluß wird die ausgedruckte Folie mit A4- Laminierfolie verstärkt, wer kein Laminiergerät hat, geht in einen Copy-Shop o.ä.

Die so gewonnenen Lochscheiben werden nun ausgeschnitten und bei Bedarf mit einem Heißluftgerät noch etwas "nachgebacken", bevor sie im eigenen Projekt mit Kraftkleber auf ein kleines Rad aufgeklebt werden. Hierbei auf gute Zentrierung achten, damit die Lochscheibe möglichst rund läuft. Sekundenkleber ist deshalb ungeeignet, weil kaum Zeit für Korrektur und Einstellung bleibt.

Anpassen der Lichtschranke

Baustelle:

Fotos, Anregungen zum Nachbau, Beschaffung, Erfahrungen

weiterführende Informationen: Inkrementalgeber

Quellcode


//Deklaration global
volatile uint8_t Zust_Li;            //Zustandsmerker Position linker Motor
volatile uint16_t Li_Inkr;           //aktuelle Position linker Motor
volatile uint16_t old_Li_Inkr;       //Position im vorangegangenen Takt
volatile int8_t Speed_Li_Ist;        //Wegänderung je Takt, in ISR Timer 0

...

// Interrupt-Service-Routine  Timer_0 Overflow
SIGNAL (SIG_OVERFLOW0)
{
  // ISR-Code  61,035 Pro Sekunde
  Timeout++;
  Speed_Li_Ist = Li_Inkr - old_Li_Inkr;
  old_Li_Inkr = Li_Inkr;
}


// Interrupt-Service-Routine  Timer_2 Overflow
SIGNAL (SIG_OVERFLOW2)
{
  // ISR-Code  62.5 kHz
  // 4 Zustaende durch jeweils 1 Bit repräsentiert (1,2,4,8)
  // Lichtschranke A liegt an Port A.0
  // Lichtschranke B liegt an Port A.1

  if ( (Zust_Li == 1) && ( !(PINA & (1<<PINA0)) )&& ( PINA & (1<<PINA1) ) ){
    Li_Inkr = Li_Inkr + 1;
    Zust_Li = 2;
  } /* end if */

  if ( (Zust_Li == 1) && (PINA & (1<<PINA0) )&& ( !( PINA & (1<<PINA1)) ) ){
    Li_Inkr = Li_Inkr - 1;
    Zust_Li = 8;
  } /* end if */

  if ( (Zust_Li == 2) && (PINA & (1<<PINA0) )&& ( PINA & (1<<PINA1) ) ){
    Li_Inkr = Li_Inkr + 1;
    Zust_Li = 4;
  } /* end if */

  if ( (Zust_Li == 2) && ( !(PINA & (1<<PINA0)) )&& ( !( PINA & (1<<PINA1)) ) ){
    Li_Inkr = Li_Inkr - 1;
    Zust_Li = 1;
  } /* end if */

  if ( (Zust_Li == 4) && (PINA & (1<<PINA0) )&& ( !( PINA & (1<<PINA1)) ) ){
    Li_Inkr = Li_Inkr + 1;
    Zust_Li = 8;
  } /* end if */

  if ( (Zust_Li == 4) && ( !(PINA & (1<<PINA0)) )&& ( PINA & (1<<PINA1) ) ){
    Li_Inkr = Li_Inkr - 1;
    Zust_Li = 2;
  } /* end if */

  if ( (Zust_Li == 8) && ( !(PINA & (1<<PINA0)) )&& ( !( PINA & (1<<PINA1)) ) ){
    Li_Inkr = Li_Inkr + 1;
    Zust_Li = 1;
  } /* end if */

  if ( (Zust_Li == 8) && (PINA & (1<<PINA0) )&& ( PINA & (1<<PINA1) ) ){
    Li_Inkr = Li_Inkr - 1;
    Zust_Li = 4;
  } /* end if */

}

...

int main (void)
{

//Init
TCCR2 |= (1<<CS20);                  //Prescaler = 1 (16MHz/1 = 16000000) ->
                                     //16000000/256 -> 62500 Interrupts je Sekunde

TCCR0 |= (1<<CS02)|(1<<CS00);        //Prescaler = 1024  (16000000 / 1024 = 15625) ->
                                     //15625/256 = 61,035  -> 61 Interrupts je Sekunde

TIMSK |= (1<<TOIE0)|(1<<TOIE2);      //Timer Overflow Interrupt Enablae für Timer 0 und 2


Li_Inkr = 32000;Zust_Li = 1;         // Kalibrierstellung bei 32000
sei();                               // Interrupts aktivieren


  while(1)
  {

  // hier kann Position und Geschwindigkeit ausgewertet werden

  }
}

Vor und Nachteile der Messmethoden


LiFePO4 Speicher Test