Hallo zusammen. Da mir dieses Forum schon bei der einen oder anderen Frage sehr hilfreich war, ich aber zu meiner jetzigen Fragestellung nix passendes gefunden habe, wende ich mich eben direkt an euch. Ich arbeite mit WinAVR und programmiere in C. 1.Ich messe per input_capture den duty cycle eines PWM-Signales. 2.Nun möchte ich diesen Wert mit einer Kennlinie abgleichen. Ist z.B. der Wert dc_in=30%,soll dc_out=50% sein, usw. 3. dann soll mit dc_out weitergearbeitet werden. Da ich nun sehr auf die Auslastung des µC achten muß (es ist auch ein dc_in von weniger als 5% bei einer Frequenz von 5KHz (<10µs) + Berechnung von OCRxA), möchte ich nach möglichkeit keine einzelnen Vergleiche in einer Schleife durchführen, bis ich den richtigen dc_in in meiner Kennlinie gefunden habe. Dieses würde im worst case ~10Takte bei 16MHz pro durchlauf bedeuten. Bei 500 Stützstellen -> 5000 Takte -> 31µs. Da ich nun auch ganz gerne zwischen den Stützstellen interpolieren möchte, wird das Ganze mit einer Schleife praktisch unmöglich. Die Stützstellen sollen ausserdem nicht fest in ihren Werten vorgegeben sein (also 100% /500 -> also alle 0.2%; ich benötige auch mal einen Wert genau bei z.B :40.67%). Hat vielleicht jemand von euch ein solches Problem gelöst oder evt. eine kreative Lsg. für mich parat? Ich hänge z.Z. an diesem eigentlich kleinen Problem fest. :-( Ich bedanke mich für jeden Vorschlag, den ich bekomme, weil sämtliche Hilfe ist besser als gar keine..... so long
Tabelle, falls du genug flash dafür hast, ist immer die schnellste Variante.
Das ist, glaube ich auch die einzige Möglichkeit. Aber selbst mit einem schnellen suchalgorithmus benötige ich somit mehr zeit als mit zur verfügung steht. Darum dachte ich evt an etwas wie Adressen direkt mit dem Wert von dc_in ansprechen. Durch eine entsprechende Umwandlung des Wertes. :-)
Wieso Suchalgorithmus? Zu jedem Eingangswert gibt es einen Ausgangswert. Eingangsauflösung 0,1% -> Tabelle mit 1000 Werten zu je 2 Byte, ~2kB. Zu suchen gibts da nichts, und schneller gehts auch nicht.
Da hast Du zwar recht, aber somit hätte ich allerdings fest vorgegebene Stützstellen, alle 0,1%. Aber wie schon gesagt, so wollte ich es nicht realisieren, da auch mal 0,01% benötigt wird. Mehr als 1000 Stützstellen wollte ich nun wirklich nicht angeben müssen! -> somit sind die Stützstellen nicht linear angegeben und ich müßte dc_in mit derTtabelle abgleichen und den nächst liegenden Wert nehmen/suchen. Ich danke dir für deine schnelle Hilfe, und sehe, ich muß wohl einen Kompromiss eingehen und feste Stützstellen nehmen. Falls vielleicht doch noch jemand mal solch ein Problem hatte oder haben wird, wäre ich dankbar wenn er mir seine Lösung dafür mitteilen könnte. Danke. ps: Das Forum hier ist ne super Sache und hat mir schon öfters gute Hilfestellung geben können, dank der Forumssuche..... weiter so! so long
Kombiniere eine Tabelle mit Interpolation! Oder versuche, mathematische Zusammenhänge zu erkennen, mit denen Du die Werte näherungsweise berechnen kannst. Evtl. kannst Du dann in der Tabelle die Abweichungen zwischen Berechnung und Soll ablegen. In Excel git es bei Diagrammen die Funktion "Trendlinie hinzufügen", deren Formel dann angezeigt werden kann. Sehr hilfreich! Gib uns mal ein paar Beispiele (wie genau sollen die Werte sein, wie groß die Abstände, wieviele Einträge in der Tabelle). Das kriegen wir schon hin. Neben der linearen gibt es noch weitere Varianten der Interpolation: quadratische Suche nach Lagrangesche Interpolationsformel Newtonsche Interpolationsformel Stirling, Bessel, Everett, Gauß im Handbuch der Mathematik
Hoi, stückweise linear interpolieren geht recht einfach und braucht noch nicht zuviel Rechenzeit. Da muss auch nicht lang gesucht werden, wenn du z. B. 100 Werte hast und 40.23 % suchst, dann wird der einfach abgerundet und der Wert für 40 und sein Nachfolger geholt... Bleibt nur zu prüfen, ob eine solche Näherung hinreichend genau für dich ist. Aber das geht ja ohne µC ;-) Irgendeine komplexe Funktion als Fit zu nehmen, kann auf dem µC auch schnell nach hinten losgehen.
"Aber wie schon gesagt, so wollte ich es nicht realisieren, da auch mal 0,01% benötigt wird." Zuvor sollte man aber erstmal prüfen, ob die PWM überhaupt so stabil erzeugt wird und ob dann auch die Messung so genau erfolgt. Peter
Auch wenn ich die allgemeine Tabelle mit festen abstand vorziehen würde. Als Suchalgorithmus: Suche mit halbiertem Intervall Du hast deine Tabelle,da stehen alle werte aufsteigend geordnet drin. Bitte nimm die Werte skaliert oder als festkomma NICHT Fließkomma! Sagen wir du möchtest in einer Tabelle von 1000 Werten 40,1% finden 1.Nimm den Wert in der Mitte der Tabelle Ist es dein Wert? ja: schön fertig nein: wenn dein gesuchter Wert größer ist nimm die obere Hälfte sonst die untere Hälfte (aufgrund der aufsteigenden Reihenfolge sind alle Werte in der oberen Hälfte größer/in der unteren Hälfte kleiner) wiederhole 1. Abbruchkriterium ist: Du kannst nicht weiter die Tabelle teilen Niemand hindert dich solltest du einen nichtpassenden Wert am ende erhalten, diesen durch Interpolation mit den Nachbarwerten weiter zu verbessern. Hier kommt es darauf an wie gut du die Zahlen skalierst. Die Anzahl der Vergleiche ist log2(Tabellengröße) also 10 für Tabellengröße 1000.
Mein Problem liegt nicht in der Interpolation oder der Mathematik. Genau die will ich ja eigentlich umgehen. Denn jede Div oder Multiplikation "frißt" extrem viel Rechenleistung. Ich benutze ja immerhin "nur" einen ATmega und der besitzt nunmal keine ALU. Darum wmöchte ich nach möglichkeit so viele Rechnungen wie möglcih (DIV & MULTI) vermeiden. Das mit Excel habe ich mir auch schon überlegt. Ist eiegntlich ne ganz feine Sache. So muß ich nicht immer alle Stützstellen eintragen, sondern kann sie am PC errechnen(interpolation). Und diese dann zum AVR übertragen. Mir geht es darum, wie man effektiv(schnell) auf nicht genau festgelegte Eingangs-Werte in einer Tabelle zugreifen kann, ohne diese mit Suchalgorithmen abzugleichen. 1.Bsp. Tabelle mit def. Stützstellen alle 0.1%->1000 Stützstellen: dc_in=26.77% -> auf Tabelle[dc_in] zugreifen -> geht nicht, da Wert nihct vorhanden -> dc_in so korregieren, daß entweder dc_in abgerundet(26.7) oder aufgerundet(26.8) -> oder aber evt. interpolieren zwischen den beiden nächstliegenden Werten -> sehr Rechenaufwendig 2.Bsp: Tabelle mit undef. Stützstellen ->1000 Stützstellen: dc_in=26.77 -> Kontrolle, ob Tabelle[dc_in] def. -> falls ja, Wert übernehmen -> falls nein nächst liegenden Wert(e) suchen, da dieser aber nicht eindeutig def. ist (heißt er könnte bei 26.65%, 30.4, 26.99, 26.78 liegen) -> Suchalgohritmus - >interploieren -> noch Rechenaufwendiger Einfacher wäre es, wenn man den Wert aus der tabelle nimmt vom nächst tieferen def. dc_in. Aber ich denke mal, ich werde auf Bsp 1 ohne interpolation ausweichen müssen, das benötigt am wenigsten POWER. Oder sind doch noch Ideen da???? THX
@ Peter Das Problem habe ich schon abgehakt. Habe ich zuerst auch befürchetet, aber ich habe eine Auflösung von 0,005%. Die Messung wurde mit einem sehr zuverlässigen Oszi gemacht. @ Wolfram Also wenn eine Suche, dann bestimmt diese. Findet im Mittel dei schnellsten Treffer.Und benötigt die geringsten Ressourcen. so long
Hallo! Stichwort "Look-up" Tabelle - wie schon oft hier beschrieben, wäre das Mittel meiner Wahl und sollte wohl auch Deines sein. Ob nun 1000 oder 5000 Werte in einer Tabelle ist doch wohl egal. Die wirst Du ja sowieso automatisch generieren, oder? Einzig K.O. Grund kann hier der Speicherbedarf sein. Sollte es aber heutzutage auch nicht... Und wenn 5000 nicht reichen nimmst Du eben 10000. So kannst Du jede Genauigkeit erreichen. Deine Gemessenen Werte müssen eben nur auf die gewünschte Nachkommastelle begrenzt werden. Anschließend das Komma "verschieben" und direkt als Index in die Tabelle eintragen. MfG Tobi
verstehe dein Rechenzeitproblem noch nicht ganz. Wenn du sagst, das Eingangssignal kommt mit 5kHz, also alle 200µs. Bei 16MHz hast du doch sattte 3200 Takte Zeit, das Ergebnis zu berechnen. Und, falls die Eingangsfrequenz fest ist, brauchst du den duty-cycle des Eingangssignal gar nicht erst berechnen. Für deine Funktion reicht die entsprechend skalierte Pulsdauer doch aus?
@ crazy horse Also bie einer Frequenz von 5KHz und einem dc von 5% komme ich bei 16MHz Taktung auf gerade mal 160 Takte. Das ist zwar worst case, aber dennoch realistisch und somit zu berücksichtigen. Das ist ja das Prob. @ Tobi So muß ich es wohl machen. Speicherplatz-Probleme tauchen bei mir noch nicht auf. Ich dachte halt nur an die Zukunft und hatte auf eine "bessere" Idee gehofft. Und bisher hat sich hier bei meinen Suchen im Forum meist gezeigt, daß meine Ideen halt nicht schlecht waren, aber dennoch besser zu machen waren. Und eigentlich versuche ich immer, mir erst meine eigenen Gedanken zu machen (so lernt m,an am besten!) und dann mal zu schauen, ob es noch was anderes gibt. Ganz nach dem Motto, daß hier schon sehr oft verwendet wurde: 'Warum das Rad neu erefinden'. mfg
Was hast du gegen die binäre Suche wie Wolfram vorschlägt ? Bei 1000 Werten sind das nur 10 Vergleiche, geht ratzfatz, also überhaupt kein großer Rechenaufwand. Aber wie gesagt, es kommt zuallererst auf die reale Genauigkeit der Eingangsgröße an. Zum Schwindeln kannst Du auch einfach nur Zufallszahlen ausgeben. Peter
"...aber ich habe eine Auflösung von 0,005%." Auflösung und Genauigkeit sind 2 völlig verschiedene Dinge. Peter
Ich verstehe es immer noch nicht - du musst es doch nicht in den 5% der Zeit ausrechnen, sondern hast doch den ganzen Zyklus Zeit??
@ peter Zuersteinmal habe ich nix gegen die von Wolfram vorgeschlagene Suchfunktion. Ist schon mit die schnellste, die es gibt. Bedeutet aber auch, das der Wert vorhanden sein muß nach dem ich suche. Mit "Auflösung und Genauigkeit sind 2 völlig verschiedene Dinge." hast du natürlich vollkommen recht. Ich wollte damit sagen, daß ich eine Genauigkeit von 0,005% +- 0,0005% in dem für mich wichtogen Bereich erreiche. @ crazy horse Wenn ich in Echtzeit dc_out und dc_in verknüpfe, bleiben mir nur die 160 Takte. Ansonsten "hänge ich immer eine Periode hinterher. Und sowas ist mal angenommen auf ein Einspritzsystem, o.a. leider nicht akzeptabel. Aber ich wollte hier keinen Ärger aufbringen. Ich entschuldige mich natürlich dafür. Habe halt gehofft, es gäbe noch eine andere Möglichkeit, auf die man so schnell vielleicht nicht kommt. Ich werde dann jetzt wohl feste Vorgaben benutzen. Mal sehen, ob mit 1000 oder 10000 Werten.Das wird sich zeigen während der Anwendung. Thx
ALU Arithmetisch / Logische Einheit hat jeder µC Du meinst wohl FPU, Gleitkommaeinheit zu gut altdeutsch. Würde aber sozusagen Fixed-Point-Arithmetik machen, Eingang einfach so skalieren, dass z.B. 16 Bit optimal ausgenutz werden. Ein div dauert doch nur ein paar Zyklen. ... , das der Wert vorhanden sein muß nach dem ich suche. Nein, Du kannst den näheren Nachbarwert nehmen oder zwischen den beiden Nachbarn interpolieren. Das ist doch alles schnell zu berechnen, notfalls musst Du vorhandenen Routinen / Labraries auf Geschwindigkeit trimmen. Für Interpolation habe ich noch folgendes gefunden: http://www.embeddedforth.de/emb9.pdf letzter Beitrag auf S. 20 / 16. Optimierung der Stützstellen. Vielleicht könntest Du uns doch mal konkrete Zahlen / Beispiele nennen. Vielleicht helfen mehrere Teiltabellen? Zuerst eine grobe mit Verweisen auf feinere.
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.