Hallo, ich möchte insgesamt 4 Drehzahlsensorn auslesen, die ein Rechtecksignal ausgeben. Ich habe übers Forum herausgefunden, dass es dafür generell 2 Möglichkeiten gibt: 1. Frequenzmessung (also in einem vorgegebenen Zeitintervall werden die einkommenden Impulse gezählt) 2. Zeitmessung (es wird die Zeit zwischen zwei Impulsen gemessen) Was genau brauche ich für die beiden Methoden jeweils? Insgesamt 4 Timer sowieso, oder? Brauche ich bei beiden Methoden Capture Inputs? Mir ist generell auch nicht der Unterschied bewusst zwischen Timer und Timer/Counter. Macht das hier einen Unterschied? Kann man das PWM-Signal irgendwie direkt auslesen indem man das Signal direkt auf einen PWM-Channel legt, sodass man Timer und Interrupts nicht verwenden muss? Ich habe gelesen, dass man das PWM-Signal analog wandeln und mit dem ADC einlesen kann, aber ich glaube, dass das zu ungenau ist. Sensoren und Controller hab ich noch nicht ausgewählt, weshalb ich keine weiteren Angaben machen kann. Ich möchte mich erst mal generell informieren. Danke
Um welche Drehzahlen handet es sich? Es gibt gewisse Grenzen ab denen man die eine Variante der anderen vorzieht.
> 1. Frequenzmessung (also in einem vorgegebenen Zeitintervall werden die > einkommenden Impulse gezählt) > 2. Zeitmessung (es wird die Zeit zwischen zwei Impulsen gemessen) > > Was genau brauche ich für die beiden Methoden jeweils? > Insgesamt 4 Timer sowieso, oder? Brauche ich bei beiden Methoden Capture > Inputs? Mir ist generell auch nicht der Unterschied bewusst zwischen > Timer und Timer/Counter. Macht das hier einen Unterschied? Methode 1: 1 Timer, der bis zb. 1024 Zählt = 1Sekunde und dann einen Interrupt gibt. Danach wird vom 2. Timer, der als Zähler konfiguriert worden ist, die Anzahl gemessen. Anzahl/Zeitbasis = Umdrehungen. Hier kann noch ein Faktor einfließen, zb. 2 Pulse pro Umdrehung. Methode 2: Timer start, warten bis steigende Flanke (oder Fallende) Timer Stop. Hier ist es wichtig, dass der Timer bald möglichst wieder gestartet wird, sonst verlierst "Zeit". > Kann man das PWM-Signal irgendwie direkt auslesen indem man das Signal > direkt auf einen PWM-Channel legt, sodass man Timer und Interrupts nicht > verwenden muss? PWM Controller können meist nur ein PWM Signal ausgeben. Eingelesen wirds über Counter bzw. Timer (siehe oben) > Ich habe gelesen, dass man das PWM-Signal analog wandeln und mit dem ADC > einlesen kann, aber ich glaube, dass das zu ungenau ist. Kannst du auch, aber PWM signale sind meist zwischen 0V und VCC (zb 5V). Ann misst du nur ob es high oder low ist und brauchst auch einen Counter bzw. Timer > Sensoren und Controller hab ich noch nicht ausgewählt, weshalb ich keine > weiteren Angaben machen kann. Ich möchte mich erst mal generell > informieren. Verwende zb Hall-Sensoren oder Lichtschranken. > Danke Ich hoffe es hat geholfen Benjamin
Vielen Dank für deine Antwort Benjamin. Die Anforderungen an den Drehzahlsensor habe sich mittlerweile etwas konkretisiert: Der zu messende Drehzahlbereich liegt zwischen 0 und ca 1800 min-1. Problem ist, dass mit dem Sensor ESP verwiklich werden soll und die Drehzahl dazu recht oft berechnet werden muss. Gut wären alle 10 ms. Ich habe ausgerechnet, dass für die Methode Frequenzmessung ein Impulsrad mit 320 Impulsen pro Umdrehung nötig wäre, um innerhalb von 10ms eine Auflösung von 1km/h des Fahrzeugs hinzubekommen. Diese Methode scheint mir recht unbrauchbar hier. Also Zeitmessung: Laut meinen Berechnungen brauche ich ein Impulsrad, welches ca 30 Impulse pro Umdrehung liefert. Das bedeutet für den Sensor eine maximale Signalfrequenz von 1000 Hz. Problem dieser Methode ist, dass das Fahrzeug bei 10 km/h alle 10ms die Drehzahlberechnung durchführt, bei der max Geschwindigkeit von 100 km/h aber schon nach jeder Millisekunde, weil sich ja der Abstand der Flanken bei höhere Fahrgeschwindikeit verkürzt. Mir fehlt ehrlich gesagt die Erfahrung: Ist das zu viel für einen µC, der z.B. mit 150 Hz Taktfrequenz arbeitet, um noch andere wichtige Aufgaben auszuführen? Aber ich weiß nicht wie ich es anders lösen soll. Und noch eine Frage zum Sensor: Ich habe mich mal bei Bosch umgesehen. Hier ist ein Link zu einem Sensor, der meinen Anforderungen gerecht werden würde. Das Ding liefert leider einen eingeprägten Strom und keine Spannung. http://rb-aa.bosch.com/boaasocs/index.jsp;jsessionid=E7977BCB59F0D67E671B229CA6FAD851.sundoro?ccat_id=133&prod_id=539 1. Soweit ich weiß kann ich ja mit Strom nichts anfangen oder? Oder kann man Strom mit einem µC verarbeiten? 2. Gibts ne einfache Möglichkeit, um aus diesem Strom ne handhabbare Spannung zu machen? 3. Wäre natürlich super, wenn jemand ne Alternative zu diesem Sensor bringen könnte, der auch den oben genannten Anforderungen (also Signalfrequenz 1000Hz und liefert PWM-Spannungssignal) gerecht wird. Wäre sehr nett, wenn ihr mir helfen könnt, ich bin echt auf Hilfe angewiesen...Danke
Hi >2. Gibts ne einfache Möglichkeit, um aus diesem Strom ne handhabbare >Spannung zu machen? Ja, Widerstand. MfG Spess
>Mir fehlt ehrlich gesagt die Erfahrung: Ist das zu viel für einen µC, >der z.B. mit 150 Hz Taktfrequenz arbeitet, Das ist definitiv zu viel für diesen Takt ;) SCNR
Dein uC hat einen Takt von 150Hz? Irgendwie möchte ich das bezweifeln um ehrlich zu sein. Ich habe mal eine Drehzahlregelung mit einer maximalen Drehzahl von 6000U/min auf einem C1515C (8051pendant) mit 10MHz realisiert. Zeitlich ist es weniger kritisch, da du die Messung der Drehzahl ja in der ISR machen würdest. Was du dann im hauptprogramm hast spielt da also keien Rolle. Du stellst bsw. mit einem Timer einen Systemtick von 100us ein. Und zählst innerhalb der ISR des Timers eine Variable Hoch. Wenn nun ein Interrupt von deiner Drehzahlmessung kommt liest du diesen Wert aus, speicherst ihn und löscht ihn wieder. kannst dann normal weiter arbeiten. Zu deinen unteren Fragen: 1. Nur indirekt. 2. Die einfachste Methode: Strom durch einen Widerstand jagen udn abfallende Spannung über einen AD Wandler ausmessen.
Sorry, sorry. Ich meinte natürlich 150 Mhz, nicht 150 Hz !!! > Zeitlich ist es weniger kritisch, da du die Messung der Drehzahl ja in der > ISR machen würdest. Was du dann im hauptprogramm hast spielt da also keien > Rolle. versteh ich nicht ganz. Meine Sorge ist halt, dass wenn ich die Drehzahlen(eigentlch sind es ja 4 dieser Sensoren) so oft, also im schlimmsten Fall jede Millisekunde berechne, der Controller dann seine restlichen Regelungsaufgaben nicht mehr bewältigen kann, weil ihn andauernd ein Interrupt von der Arbeit abhält. Ist diese Angst also begründet? > Du stellst bsw. mit einem Timer einen Systemtick von 100us ein. Und > zählst innerhalb der ISR des Timers eine Variable Hoch. > Wenn nun ein Interrupt von deiner Drehzahlmessung kommt liest du diesen > Wert aus, speicherst ihn und löscht ihn wieder. kannst dann normal > weiter arbeiten. sorry, das versteh ich auch nicht. Wieso 100µs? Was zählt die Variable? > 2. Die einfachste Methode: Strom durch einen Widerstand jagen udn > abfallende Spannung über einen AD Wandler ausmessen. Mir fehlen wohl echt die Basics. Wie sieht das dann konkret aus? Den Sensor über einen Widerstand an die Erdung anschließen und den ADC zwischen Sensor und Widerstand hängen?? Sorry für meine Unwissenheit. Und wieso überhaupt an den ADC? In normaler I/O müsste es doch auch tun oder? Entweder liegt Spannung an, die am Wiederstand abfällt oder nicht. Kennt niemand nen Sensor, der echt gleich ne SPannung liefert?
Du lässt dir alle 100µs einen Interrupt generieren und dann berechnest du die angefallenen Impulse. Das mit dem AD Wandler von Mücke bezog sich auf die Wandlung des Strom über einen Widerstand in eine Spannung und dann zu sampeln. Hier ein Pseudocode
1 | #include "..." |
2 | |
3 | int count; |
4 | bool print; |
5 | |
6 | int main() |
7 | {
|
8 | init(); |
9 | tu_was_ganz_wichtiges(); |
10 | |
11 | while(1) // für immer tu etwas |
12 | {
|
13 | if(print==true) |
14 | {
|
15 | uart_print("Drehzahl"); |
16 | uart_print("%d", (count*10)); |
17 | uart_print("U/s-1\n"); |
18 | print = false; |
19 | }
|
20 | }
|
21 | return (0); //<- wird nie erreicht |
22 | }
|
23 | |
24 | ISR(TIMER) |
25 | {
|
26 | count = lese_counter(); // register des entsprechenden counters lesen |
27 | reset_counter(); // register zurücksetzten: zb REG_COUNTER = 0; |
28 | print = true; |
29 | }
|
Um dich erstmal zu beruhigen: 150MHz sind so gewaltig an rechenleistung das du absolut keien Probleme haben wirst deine 4 Drehzahlen zu bestimmen und auszuwerten. Jetzt aber zum Prinzip wie man bsw. solch eine Drehzahlmessung per Timer und dem zugehörigen Interrupt bewerkstelligt: 1. Schritt: Erstmal muss der Timer der den System-Tick vorgibt eingenstellt werden. Umso geringer du sie machst, umso genauer kannst du die Drehzahl auflösen. Nehmen wir mal an du willst die Drehzahl in 5 U/min Schritte auflösen können: 1800/5 =360 = 2,8ms zwischen zwei Impulsen. Damit das ganze nun möglichst genau wird setzen wir denn Systemtick auf 1/10 dieser minimalen Zeit zwischen zwei Flanken. Bei diesem beispiel also auf 280us. Nun musst du in deinem Datenblatt nachlesen wie du die Register (vor allen denn Reloadwert) Laden musst auf diese zeit zu kommen. Hinweis: Sollte der Reloadwert zu groß werden um in das passende register zu passen: Nimm einen Wert das du auf eien schöne Runde Zahl kommst (bsw. 100us, 10 us usw. Das ereifnacht dann die Rechnung ungemein). 2. Schritt: Nun geht es an die ISR. Zuvor musst du noch eine Gloabale variable definieren die dir als Zählvariable dient. Wir nennen sie mal "UMDR". Diese setzt zu beginn deines programmes auf 0. Innerhalb der ISR des zugehörigen Timers zählst du nun die Variable UMDR hoch (bei jedem Einsprung um 1). 3. Schritt: Das PWM Signal das dein Motor zurückgibt führst du an einen Interrupteingang des uC. Jedes mal wenn nun ein Interrupt ankommt (bsw. steigende Flanke des PWM Signales) wird der Wert der nun in UMDR steht ausgelesen. Wenn du bsw. 10 in UMDR stehen hast, dann bedeutet dies das dein Motor in unserem bswp. 10*280us=2,8ms gebraucht hat für eien Umdrehung. Jetzt liegt dir dieses Ergebniss aber nicht als fertige Umdrehungszahl vor, sondern als Basis zum Systemtick. Nun musst du eifnach umrechnen Echte Umdrehungszahl = UMDR*280u*5 Hier würde also 1785,7 UMDR/min rauskommen. (Das mal 5 kommt aus unserer obigen Abmachung das wir eine Auflösung in 5 U/min haben wollen). Am Ende nun UMDR wieder auf 0 setzen. Achtung: Am Anfang der ISR des PWM solltest du das globale Interrupt deaktivieren. Nicht das dir dein umdrehungswert verfälscht wird. Zur Sache mit dem Widerstand: Richtig, du schliesst denn Wieerstand zwischen Ausgang deines Signalgebers (der ja einen Strom in Abhängigkeit der Drehzalh liefert) gegen masse. Die an ihm abfallende Spannung kannst du über einen ADC messen udn auf die Umdrehungszahl rückrechnen (dafür im Datenblatt nachsehen wie der Strom von der Umdrehungszahl abhängt nachlesen). Du könnstet auch einen port nehmen, jedoch wirst du damit nur eines feststellen: Dreht sich der Motor oder net? Denn ein port kennt ja nur zwei zustände. High und Low. Es gibt kein sehr High und mittelmässiges high oder so ;)
> Du lässt dir alle 100µs einen Interrupt generieren und dann berechnest > du die angefallenen Impulse. versteh ich immer noch nicht weil, weil nach 100µs, also 0,1ms doch nicht mehre Impulse angesammelt haben. Ich habe oben doch schon erleutert, warum ich keine Frequenzmessung alle 10ms machen will, dann kann ich doch alle 0,1 ms erst recht keine machen??? Steh wohl voll aufm Schlauch.
Nein, du musst bevor ein Impuls von deiner PWM kommt (die ja die Drehzahl darstellt) eine Variable hoch genug zählen um genau genug zu Rechnen. Wenn du z.B. dein PWM eine periodendauer von 10ms hat, dann solltest du innerhalb dieser Zeit z.B. die Variable auf 10 hochgezählt haben. Wenn du aber eine periodendauer von 100ms hast (langsamer drehender motor) dann hast du bsw. die Zählvariable auf 100 gezählt. umso größer also deine zählvariable ist, umso gerigner ist deine umdrehungszahl.
ahhhhh, jetz hab ichs glaub ich verstanden. Danke für deine eduld Gast ;-) Also der System-Tick ist quasi der Takt des Timers, der genau in diesem Takt die ISR aufruft und UMDR um eins erhöht. Solange bis vom PWM eine Flanke kommt. Dann wird die Drehzahl in einem weiteren Interrupt berechnet. Richtig so? Nochmal zum ADC: Die Amplitude des Spannungssignals ist doch eigentlich uninteressant. Wichtig ist doch nur, dass ne Flanke ankommt, die dann den Berechnung-Interrupt auslöst. Um den ganzen Spaß also umsetzen zu können brauche ich also insgesamt... 4 Timer für die System-Ticks (oder kann man das auch so machen, dass einer alle 4 Interrupts auslöst?) 4 interne Interrupts 4 externe Interrupts 4 ADC / digitale I/O je nachdem wieviel Sinne meine AUssage oben macht. Wäre nett, wenn du deine Meinung zu meinem Zusammengespinnst nochmal sagst, Gast! Vielen Dank.
>Also der System-Tick ist quasi der Takt des Timers, der genau in diesem >Takt die ISR aufruft und UMDR um eins erhöht. Solange bis vom PWM eine >Flanke kommt. Dann wird die Drehzahl in einem weiteren Interrupt >berechnet. Richtig so? Absolut richtig! Du hast es ;) >Nochmal zum ADC: Die Amplitude des Spannungssignals ist doch eigentlich >uninteressant. Wichtig ist doch nur, dass ne Flanke ankommt, die dann >den Berechnung-Interrupt auslöst. Ach jetzt habe ich verstanden was du vorhast. Das ist aber eher eine Methode nach dem motto von-hinten-durch-die-Brust-ins-Auge. >4 Timer für die System-Ticks (oder kann man das auch so machen, dass >einer alle 4 Interrupts auslöst?) >4 interne Interrupts >4 externe Interrupts >4 ADC / digitale I/O je nachdem wieviel Sinne meine AUssage oben macht. Du brauchst genau einen Timer im uC. in seiner ISR zählst du dann eben 4 Umdrehungen hoch (UMDR1, UMDR2, UMDR3 und UMDR4). Und du brauchst 4 interne/externe Interrupteingänge.
Hi >Du brauchst genau einen Timer im uC. in seiner ISR zählst du dann eben 4 >Umdrehungen hoch (UMDR1, UMDR2, UMDR3 und UMDR4). Oder du lässt den Timer durchlaufen (mit einer Variablen) und holst dir in jeden Interrupt den aktuellen Stand. Von dem wird der letzte Wert subtrahiert (Timerüberlauf beachten). >Problem ist, dass mit dem Sensor ESP verwiklich werden soll und die >Drehzahl dazu recht oft berechnet werden muss. Also wenn du bei so relativ einfachen Sachen schon Probleme hast. Was wird dann mit den Rest? MfG Spess
> Du brauchst genau einen Timer im uC. in seiner ISR zählst du dann eben 4 > Umdrehungen hoch (UMDR1, UMDR2, UMDR3 und UMDR4). ah ja klar. Ich Depp. > Und du brauchst 4 interne/externe Interrupteingänge. ohne deine Geduld überstrapazieren zu wollen, aber wenn du was erklärst versteh ich ausnahmsweise was... und das muss ich fast ausnutzen jetzt. äh, gibts auch noch ne andere Möglichkeit? Problem ist, dass mein Controller keine 4 exteren Interrupts hat, sondern leider Gottes nur 3. Ich hab da mal was von Capture Mode gelesen. Soweit ich das beurteilen kann wäre das ne Möglichkeit, die mit dem DSP TMS320F2812 vereinbar wäre. Datenblatt: http://focus.ti.com/lit/ds/symlink/tms320f2812.pdf Kannst du vielleicht noch ein paar Takte dazu sagen? ;-)
Du könntest einen normalen PORT Pin über Polling abfragen. ist zwar net so ne tolle Methode, aber wäre eine Möglichkeit. Bei Capture weis ich jetzt nicht genau auf was du anspielst. meinst du denn Capture-Mode beim Timer? Oder die Capture Unit des uC? Der Capture Mode des Timers bringt dir nämlich nichts. Die Capture Unit hingegen schon. Leider besitzt diese auch nur 3 Capture Units input Pins (insgesamt zwar 6, sind aber aufgeteilt auf 2 verschiedene Timer, somit nur 3 pro Timer). Sie speichern bei einer bestimmten Einstellung (rising Edge, falling edge, both edge) denn Zählwert des zugehörigen Timers(müsste sein, geht jedoch ausm Datenblatt net genau hervor, gibt es da ne "extended" version?) auf einem FIFO (first in - first out) Stack. Dabei wird es aber etwas komplizierter herauszufinden wie oft der Timer nun schon durchgelaufen ist. Müsste ich mir auch gerade erstmal überlegen wie man dies am besten macht. Somit könntest du dir auch externe Interrupts sparen, indem du einfach 2 Timer verwendest und dann die jweiligen Capture Unit (Timer 1 und 2 für Capture Unit 1/2/3 und Timer 3/4 für Capture unit 4/5/6) Wenn das alles nichts hilft könntest du über vektorisierte Interrupts durch einen 8212 nachdenken. P.S. Entschuldigen wegen Fragen muss man net. Wenn man dies höflich tut hilft man auch gerne.
Oder eine etwas "andere" Methode (ist mir ent direkt eignefallen bowohl doch extrem trivial): Du setzt das 4te PWM auf einen Komparatoreingang des uC. Wenn nun eine steigende Flanke kommt wird der Komp auslösen und seine ISR kannst du auch nutzen ;) Manchmal sieht man denn Wald vor lauter Bäumen nicht.
ok, leider hab ich jetzt nicht alles verstanden. Aber über Polling und vektorisierte Vektoren brauchst du nichts erklären. Glaub das führt zu weit und ich werde selbst mal versuchen mich schlau zu machen. Wenn ich dich richtig verstehe siehst du die Methode über Captur Unit eh als die am ehesten zum Ziel führende. Ich hab also 2 mal 3 Capture Pins. Und 3 Pins sind haben jeweils einen gemeinsamen Timer. Kommt an einem Pin eine PWM Flanke an, so wird der Wert des dem Pin zugeordnetem Timers in einem FIFO-Stack (das ist einfach eine Art Register nehm ich an) gespeichert. Dann ist halt noch die Sache mit den Überläufen zu managen, was aber machbar sein dürfte. Dafür brauche ich keine externen Interrupts. Soweit stimmt's oder? > Somit könntest du dir auch externe Interrupts sparen, indem du einfach 2 > Timer verwendest und dann die jweiligen Capture Unit (Timer 1 und 2 für > Capture Unit 1/2/3 und Timer 3/4 für Capture unit 4/5/6) ich verstehe nicht, was du in der Klammer ausdrücken willst. Ich brauche doch nur zwei Timer, wieso erwähnst du 4? Bzgl Datenblatt hast du recht. Ich habe mich auch schon über dessen Unvollständigkeit gewundert. Aber es gibt auf der entsprechenden Prozessorseite bei TI einige UserGuides, wie etwa auch folgendes, welche hier wohl sehr hilfreich ist: http://focus.ti.com/lit/ug/spru065e/spru065e.pdf http://focus.ti.com/docs/prod/folders/print/tms320c2812.html So generell denkst du aber schon, dass die Auswertung über die Capture Inputs funktionieren kann und dabei auch eine halbwegs elegante Lösung darstellt? Immerhin muss ich das meinen Betreuern noch verklickern ;-) Ich werde mich jetzt noch ein wenig einlesen und mir noch ein paar Gedanken zum genauen Vorgehen machen. Wäre wirklich sehr nett, wenn du, falls ich nochmal ne Frage hätte, mal wieder in diesen Beitrag vorbeischauen könntest. Vielen Dank, du hast mir echt geholfen.
heieiei, ich seh schon, ich hab Informationsbedarf noch und nöcher. Komperatoreingang. Klingt gut. Aber ich hab leider damit noch nie etwas gemacht und finde diesen auch nicht im Datenblatt. Weißt du, dass der 2812 sowas hat?
Jop, die Lösung über die Capture Pins ist die beste Lösung für deine Anwendung. Wieso ich 4 Timer erwähnt habe hat folgenden grund. Im bisherirgen Datenblat wird geschrie´ben das die Capture Pins 1, 2, 3 z.B. für Timer 1/2 zuständig sind. Man kann da bestimmt nochmal auswählen welchen Timer genau man möchte. Lässt sich aber aus der Kurzfassung des Datenblattes net rauslesen (170 Seiten sidn echt arg mau, da sind manche Inhaltvserzeichnisse länger). FIFO Stack ist kein Register, zumindest wenn sich TI an Begriffsdefinitionen hält. Der Stack ist wie der Name schon sagt ein Stappel, auf dem Daten abgelegt werden können (liegt meist im internen Datenspeicher). Er packt immer weitere Daten oben drauf und man kann das oberste Byte auslesen, dann zählt der Stack-pointer runter. Daher kommt der Begriff First in - First out. Aber das würde denn Rahmen sprengen, vor allen Dignen zu dieser Uhrzeit. Willst du also mehr zum Stack wissen, google ist dein Freund. Oder auch das Tutorial hier. Den der Stack funktioniert überall gleich. Frag deinen Betreuer am besten mal was am besten wäre, schreib aber die Methode der vektorisierten Interrupts nicht ab, denn diese ist unglaublich mächtig. Da könntest du über 2 Interrupt Eingänge Locker 12 Interrupts handeln. Wenn es noch fragen gibt, immer her damit.
> Uff....nach durchschauen des Datenblattes habe ich keinen gefunden
also bleibts mal vorläufig bei den Capture Pins ;-)
Oder du kannst deinen Beutreuer davon überzeugen von einem DSP (ist eh komisch. DSP's sind für was anderes gedacht) auf einen uC mit 4 externen Interrupts umzusteigen ;)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.