Hi, nehmen wir mal an, ich möchte eine PWM implementieren, die langfristig im Mittel 23,572% Tastverhältnis hat. Allerdings ist die tatsächliche Auflösung des Tastverhältnisses auf 1% beschränkt, ich kann die PWM also entweder mit 23% oder mit 24% Tastverhältnis laufen lassen. Indem ich jedoch eine bestimmte Folge aus 23 23 24 23 24 23 24 23 23 23... usw ausgebe kann ich das Tastverhältnis im statistischen Mittel langfristig auf beliebige Auflösungen bringen. Aber wie erzeuge ich eine solche Folge? Klar, ich könnte eine Folge aus 572*24 und 428*23 aneinanderreihen aber würde mir eher wünschen, dass die Folge so "abwechslungsreich" wie nur irgendwie möglich wird. Vielleicht stehe ich auch gerade auf dem Schlauch aber mir fällt auf anhieb kein mathematisches Verfahren ein. Wichtig ist auch, dass ich die Folge on the fly berechnen will, also nicht zuerst im RAM präparieren müssen möchte. Hat jemand eine Idee?
Fractional Counter im Fixed Point Format.
Als Alternative, einen großen Zähler nehmen mit passendem Increment und immer wenn er überläuft 24 statt 23 zählen.
Paul H. schrieb: > wie erzeuge ich eine solche Folge? https://de.wikipedia.org/wiki/Sigma-Delta-Modulation
Eine einfache Regelung. Bilde den gleitenden Mittelwert der ausgegebenen Werte. Wenn er unter 23,572 ist, wird der nächste Wert 24, sonst 23.
23,572 = (23 * x + 24 * y)/(x + y) ... so, und jetzt zeig mal was Du gelernt hast.
Das Problem lässt sich auf die Erzeugung von Zufallszahlen mit einer bestimmten Verteilung reduzieren. Als Ausgangspunkt ist unter Umständen der Artikel https://en.wikipedia.org/wiki/Random_number_generation#Generation_from_a_probability_distribution für Dich hilfreich.
Paul H. schrieb: > im Mittel 23,572% Tastverhältnis hat Damit das irgendeinen praktischen Nutzen hat müsste die Spannung aber auf mindestens 0,01% genau sein, sonst ist eine so genaue PWM ziemlich sinnlos.
Paul H. schrieb: > Wichtig ist auch, dass ich die > Folge on the fly berechnen will, also nicht zuerst im RAM präparieren > müssen möchte. Da kannst auch 250 Werte ins ROM (o.ä.) schreiben.
Paul H. schrieb: > ich kann die PWM also entweder mit 23% oder mit 24% Tastverhältnis > laufen lassen. Ist das eine Hardware-PWM, die du ab&zu mit anderen Vergleichswerten versehen willst, oder kannst du (per Overflow-Interrupt oder weil Soft-PWM) in jedem einzelnen PWM-Zyklus den neuen Umschaltwert berechnen und einstellen?
Im jetzigen konkreten Anwendungsfall möchte ich das auf eine Software-PWM anwenden, kann also die PWM-Werte in jedem Zyklus updaten. Aber die Frage hat mich schon seit längerem mal interessiert, mir fallen da verschiedene Anwendungsfälle ein. Theor schrieb: > Das Problem lässt sich auf die Erzeugung von Zufallszahlen mit einer > bestimmten Verteilung reduzieren. Zuerst wollte ich genau hiernach fragen, aber dann kam mir das etwas zu abstrakt vor und ich habe es lieber direkt auf den konkreten Anwendungsfall bezogen :-D Danke an alle für die hilfreichen Ansätze! Die werde ich mal verfolgen und den ein oder anderen davon zu implementieren versuchen. Für die, die es interessiert: In meinem jetzigen Fall brauche ich das, um eine Pumpe anzusteuern, die unterhalb eines bestimmten Tastverhältnisses einfach gar nicht mehr pumpt. Durch geschicktes Pendeln zwischen dem minimalen Tastverhältnis 0% und 2% kann ich somit dennoch beliebige Durchflussmengen erreichen.
Paul H. schrieb: > Hi, nehmen wir mal an, ich möchte eine PWM implementieren, die > langfristig im Mittel 23,572% Tastverhältnis hat Also wenn du abwechselnd mit 23% und 24% ansteuerst, dann hast du im Mittel (rechnerisch...) 23,5%! Ich kann mir jetzt gar nicht vorstellen, dass die restlichen 0,072% da jemandem einen "Faden abbeissen" sollten :-) Gruß Rainer
Paul H. schrieb: > Für die, die es interessiert: In meinem jetzigen Fall brauche ich das, > um eine Pumpe anzusteuern, die unterhalb eines bestimmten > Tastverhältnisses einfach gar nicht mehr pumpt. Durch geschicktes > Pendeln zwischen dem minimalen Tastverhältnis 0% und 2% kann ich somit > dennoch beliebige Durchflussmengen erreichen. Das ist doch aber mehr oder weniger zufällig. Wenn die Lager um 3 Monate gealtert sind oder ein bischen Dreck im Rotor hängt dann läuft sie gar nicht mehr an. Eine bessere und langfristig funktionierende Lösung wäre ein echter Regelkreis bei dem die Durchflussmenge oder die Drehzahl der Pumpe erfasst würde.
Erik schrieb: > Fractional Counter im Fixed Point Format. Oder auch der DDS-Algorithmus, den sonst Bresenham zum Linien-zeichnen verwendet, der kann nämlich auch genau eine Linie mit 23,572 Grad Steigung (und alle anderen). Er arbeitet mit ganzen Zahlen, könnte einfacher sein als fixed point.
Undauch wenn ich einen eiteren Minuspunkt einstecken muß...die Geschichte, aus Ganzzahlen gebrochene Zahlen zu generieren, ist sicher hochinteressant! Aber für deine Pumpe wäre das einzig Richtige, einen Regelkreis zu implementieren. Wie gerade schon empfohlen. Gruß Rainer
1 | cnt+=572; |
2 | if (cnt >= 1000) |
3 | {
|
4 | cnt-=1000; |
5 | set_pwm(24); |
6 | }
|
7 | else
|
8 | {
|
9 | set_pwm(23); |
10 | }
|
Paul H. schrieb: > Aber wie erzeuge ich eine solche Folge? Klar, ich könnte eine Folge aus > 572*24 und 428*23 aneinanderreihen aber würde mir eher wünschen, dass > die Folge so "abwechslungsreich" wie nur irgendwie möglich wird. > > Vielleicht stehe ich auch gerade auf dem Schlauch aber mir fällt auf > anhieb kein mathematisches Verfahren ein. Wichtig ist auch, dass ich die > Folge on the fly berechnen will, also nicht zuerst im RAM präparieren > müssen möchte. > > Hat jemand eine Idee? 35 mal die Folge 24,23,24,23,24,23,24 nacheinander ausgeben und dann 1 mal die Folge 24,23,24,23,24 hinterher und wieder von vorne anfangen. Da die letzte Folge nur eine 23 und eine 24 kürzer ist, lässt sich m.E. die gesamte Sequenz nicht abwechslungsreicher gestalten. Egal wo man diese Folge einfügt, der zeitliche Abstand würde immer gleich bleiben. Die Sequenz ist insgesamt 250 Werte lang. (Ich hoffe, ich habe mich nicht vertan, es sollte genau 23,572 herauskommen)
c-heater schrieb: >
1 | > cnt+=572; |
2 | > if (cnt >= 1000) |
3 | > { |
4 | > cnt-=1000; |
5 | > set_pwm(24); |
6 | > } |
7 | > else |
8 | > { |
9 | > set_pwm(23); |
10 | > } |
11 | >
|
Was soll denn dieser schwachsinnige Codesnipsel?
Bernd schrieb: > c-heater schrieb: > >>
1 | >> cnt+=572; |
2 | >> if (cnt >= 1000) |
3 | >> { |
4 | >> cnt-=1000; |
5 | >> set_pwm(24); |
6 | >> } |
7 | >> else |
8 | >> { |
9 | >> set_pwm(23); |
10 | >> } |
11 | >>
|
> > Was soll denn dieser schwachsinnige Codesnipsel? Das ist eine Implementierung des Bresenham-Algorithmus für das Intervall 23..24, welches im Mittel 572/1000 zu 23 addiert. Wer das nicht erkennt, kann nicht programmieren. C nicht und auch keine andere Sprache. Sowas ist eine der absoluten Trivialitäten.
c-hater schrieb: > Bernd schrieb: >> c-heater schrieb: >> >> Was soll denn dieser schwachsinnige Codesnipsel? > > Das ist eine Implementierung des Bresenham-Algorithmus für das Intervall > 23..24, welches im Mittel 572/1000 zu 23 addiert. > > Wer das nicht erkennt, kann nicht programmieren. C nicht und auch keine > andere Sprache. Sowas ist eine der absoluten Trivialitäten. Vielleicht meint Bernd "Warum hast Du nicht gekürzt, Du Ressourcenverschwender?" ;)
>Du Ressourcenverschwender?" ;)
Also gut. Für die 8-Bitter:
1 | cnt+=143; |
2 | if (cnt >= 250) |
3 | {
|
4 | cnt-=250; |
5 | set_pwm(24); |
6 | }
|
7 | else
|
8 | {
|
9 | set_pwm(23); |
10 | }
|
Ja, Leute die nie mit Ganzzahlarithmetik zu tun hatten!! Träumt weiter... Gruß Rainer
c-heater schrieb: >>Du Ressourcenverschwender?" ;) > > Also gut. Für die 8-Bitter:cnt+=143; > if (cnt >= 250) > { > cnt-=250; > set_pwm(24); > } > else > { > set_pwm(23); > } 140 (z.B.) + 143 ist etwas groß, oder? Wie wäre es mit cnt+=71; if (cnt >= 125) { cnt-=124; set_pwm(24); } else { set_pwm(23); } Genau genug?
Rainer V. schrieb: > Ja, Leute die nie mit Ganzzahlarithmetik zu tun hatten!! > Träumt weiter... > Gruß Rainer Mein Vorschlag für PWM nicht genau genug? Dann vergiss auch nicht, auf SEUs abzuprüfen ;)
abcd schrieb: > auf > SEUs Mann, was immer das auch ist! Ich weiß es nicht, aber Ganzzahlarithmetik ist auch nicht so leicht!!! Pi, zB. kannst du durch 22/7 darstellen. Natürlich gibt es da einen Fehler, aber du mußt abschätzen, ob das reicht!! Gruß Rainer
Single Event Upsets. Äußert sich in zufälligen Fehlern. Treten mit bestimmter Wahrscheinlichkeit auf. Wie genau brauchst Du's denn für eine PWM? > Natürlich gibt es da einen Fehler, aber du mußt abschätzen, ob das > reicht!! Irgendwie hatte ich jetzt gehofft, dass Du das machst ;)
Paul H. schrieb: > die > langfristig im Mittel 23,572% Tastverhältnis hat Wenn 23,571428571428571% Tastverhältnis auch genügen, reicht es die 7.Schritt-Folge 24,23,24,23,24,23,24 ständig zu wiederholen. also: 24,23,24,23,24,23,24,24,23,24,23,24,23,24,24,23,24,23,24,23,24 usw.
Paul H. schrieb: > Hat jemand eine Idee? https://www.mikrocontroller.net/articles/AVR_-_Die_genaue_Sekunde_/_RTC#Bresenham_f.C3.BCr_RTCs
Paul H. schrieb: > Durch geschicktes > Pendeln zwischen dem minimalen Tastverhältnis 0% und 2% Das gehört jedenfalls noch einmal "groß" herausgehoben!!! Rainer
Na, "geschicktes pendeln" hat man hier nicht so oft :-))) Ich lach mich schief. Rainer
Paul H. schrieb: > Für die, die es interessiert: > um eine Pumpe anzusteuern... > Durch geschicktes Pendeln zwischen dem minimalen Tastverhältnis 0% und 2% > kann ich somit dennoch beliebige Durchflussmengen erreichen. Paul H. schrieb: > Was gehört das? ? Sehr viele Personen einladen um die Pumpe nochmal heraus zu heben! Sodass es ein großes Ereignis wird. Das "Große-Pumpen-Wieder-Heraus-Hebe-Festival". Das gehört sich so. Rainer V. schrieb: > Das gehört jedenfalls noch einmal "groß" herausgehoben!!! ...The More You Know
:
Bearbeitet durch User
>Wenn 23,571428571428571% Tastverhältnis auch genügen, reicht es die
Warum 23,571428571428571%, wenn ganz einfach 23,572% möglich sind?
c-heater schrieb: > Warum 23,571428571428571%, wenn ganz einfach 23,572% möglich sind? Hier genügen nur 7 Werte, ansonsten 250 ... Alex D. schrieb: > 35 mal die Folge 24,23,24,23,24,23,24 nacheinander ausgeben > und dann 1 mal die Folge 24,23,24,23,24 hinterher und wieder von vorne > anfangen. > > Da die letzte Folge nur eine 23 und eine 24 kürzer ist, lässt sich m.E. > die gesamte Sequenz nicht abwechslungsreicher gestalten. Egal wo man > diese Folge einfügt, der zeitliche Abstand würde immer gleich bleiben. > Die Sequenz ist insgesamt 250 Werte lang. > (Ich hoffe, ich habe mich nicht vertan, es sollte genau 23,572 > herauskommen)
>Hier genügen nur 7 Werte, ansonsten 250 ...
Naja. Das hier:
1 | cnt+=532; |
2 | if (cnt >= 1000) |
3 | {
|
4 | cnt-=1000; |
5 | set_pwm(24); |
6 | }
|
7 | else
|
8 | {
|
9 | set_pwm(23); |
10 | }
|
steht dem gegenüber:
1 | const BYTE lut[7]={ 24,23,24,23,24,23,24}; |
2 | int index; |
3 | ...
|
4 | |
5 | index++; |
6 | if (index >= 7) |
7 | index = 0; |
8 | set_pwm(lut[index]); |
c-hater schrieb: > Wer das nicht erkennt, kann nicht programmieren. C nicht und auch keine > andere Sprache. Sowas ist eine der absoluten Trivialitäten. Damit kannst du vieleicht super programmieren, aber nicht das eigentliche Problem lösen, das da ist: Paul H. schrieb: > Für die, die es interessiert: In meinem jetzigen Fall brauche ich das, > um eine Pumpe anzusteuern, die unterhalb eines bestimmten > Tastverhältnisses einfach gar nicht mehr pumpt. Durch geschicktes > Pendeln zwischen dem minimalen Tastverhältnis 0% und 2% kann ich somit > dennoch beliebige Durchflussmengen erreichen. Also mal bitte die "Software-Scheuklappen" abnehmen und sich das eigentliche Problem ansehen. Um deine eigene Ausdrucksweise zu bemühen: "Wer das nicht kann ist kein Ingenieur, sondern maximal ein Geek, der mit C rumspielen kann". SCNR
Nachdem nun das Problem für 23,572% vollumfassend gelöst ist, können wir uns nun dem nächste Schritt zuwenden: 24,87942% ;) Oder auch: Die Aufgabe wird doch wohl lauten, ein beliebiges Tastverhältnis mit der vorhandenen 1%-Schrittweite darzustellen. Wobei drei Stellen hinterm Komma eh akademischer Blödsinn sind. Eine reicht zur Pumpenansteuerung völlig aus. Oliver
Du nimmst einen Algorithmus, der Dir gleichverteilte Zufallszahlen von 0 bis 1 erzeugt. Die skalierst Du auf den Bereich 0 bis 2*(23.572-23), dann haben die den Mittelwert 0.572. Wenn die Zufallszahl > als 0.572 ist gibs Du eine 24 aus, sonst eine 23. Mit der Methode kann man auch andere Tastverhältnisse als 23 und 24 ausgeben, die einen vorgeschriebenen Mittelwert haben. math rulez! Cheers Detlef PS: In anderen Bereichen heißt diese Methode 'dithern', mit Rauschen die Auflösung vergrößern.
:
Bearbeitet durch User
>Die Aufgabe wird doch wohl lauten, ein beliebiges Tastverhältnis mit der >vorhandenen 1%-Schrittweite darzustellen.
1 | cnt+=NACHKOMMASTELLEN; |
2 | if (cnt >= 1000) |
3 | {
|
4 | cnt-=1000; |
5 | set_pwm(VORKOMMA+1); |
6 | }
|
7 | else
|
8 | {
|
9 | set_pwm(VORKOMMA); |
10 | }
|
ruzzn schrieb: >
1 | > const BYTE lut[7]={ 24,23,24,23,24,23,24}; |
2 | > int index; |
3 | > ... |
4 | >
|
5 | > index++; |
6 | > if (index >= 7) |
7 | > index = 0; |
8 | > set_pwm(lut[index]); |
9 | >
|
10 | >
|
Warum so aufwendig?
1 | uint8_t i; |
2 | ...
|
3 | |
4 | if ((++i) > 6) |
5 | i=0; |
6 | set_pwm(i&1 ? 23 : 24) |
Wir sind aber schon bei "ein beliebiges Tastverhältnis" ...
Detlef _. schrieb: > Wenn die Zufallszahl > als 0.572 > ist gibs Du eine 24 aus, sonst eine 23. Mit der Methode kann man auch > andere Tastverhältnisse als 23 und 24 ausgeben, die einen > vorgeschriebenen Mittelwert haben. > > math rulez! Ok, dann erweitern wir die Aufgabenstellung praxisgerecht so, daß der gewünschte Mitelwert des PWM-Taktverhältnis nicht nur statistisch, sondern tatsächlich erreicht werden muß. Und zwar nicht erst zum Ende des Jahrhunderts, sondern z.B. mit der minimal möglichen Anzahl an Taktschritten. Oliver
'statistisch' ist praxisgerecht und ein Wert wird tatsächlich errreicht. Wie der Aufgabensteller schon sagte kann man von 1000 Werten 572 mal die 24 ausgeben. Wann man 24 und wann man 23 ausgeben kann wurde hier auch schon dargelegt. Das kann man deterministisch machen. Das wollte der Aufgabensteller aber nicht tun, sondern er wollte da eine stochastische Konstante reinbringen. Das kann man so machen wie ich das geschildert habe. Man kann die Varianz der Verteilung auch modifizieren, dann wirds weniger zufällig. Damit kannst Du bestimmen, zu Ende ' welchen Jahrhunderts ' Du noch wie weit vom tatsächlichen Wert weg bist. Oh ja, die Stochastik ist ein weites Feld, so viel zu lernen und zu entdecken. math rulez. Cheers Detlef
Detlef _. schrieb: > math rulez! > Cheers > Detlef > > PS: In anderen Bereichen heißt diese Methode 'dithern', mit Rauschen die > Auflösung vergrößern. Tatsächlich gefällt mir Random Dithering bei Bildern oft besser als Floyd Steinberg. Aber hier ist das sicherlich eine der schlechtesten korrekten Lösungen.
Detlef _. schrieb: > Du nimmst einen Algorithmus, der Dir gleichverteilte Zufallszahlen von 0 > bis 1 erzeugt. Die skalierst Du auf den Bereich 0 bis 2*(23.572-23), > dann haben die den Mittelwert 0.572. Wenn die Zufallszahl > als 0.572 > ist gibs Du eine 24 aus, sonst eine 23. Mit der Methode kann man auch > andere Tastverhältnisse als 23 und 24 ausgeben, die einen > vorgeschriebenen Mittelwert haben. > > math rulez! Dann hätte die Folge aber einen Mittelwert von 23,5. Man müsste einfach R[0,1] mit 0.572 vergleichen. Oder auch rand() mit RAND_MAX*0.572
:
Bearbeitet durch User
Heiko L. schrieb: > Detlef _. schrieb: >> Du nimmst einen Algorithmus, der Dir gleichverteilte Zufallszahlen von 0 >> bis 1 erzeugt. Die skalierst Du auf den Bereich 0 bis 2*(23.572-23), >> dann haben die den Mittelwert 0.572. Wenn die Zufallszahl > als 0.572 >> ist gibs Du eine 24 aus, sonst eine 23. Mit der Methode kann man auch >> andere Tastverhältnisse als 23 und 24 ausgeben, die einen >> vorgeschriebenen Mittelwert haben. >> >> math rulez! > > Dann hätte die Folge aber einen Mittelwert von 23,5. stimmt. Fehler. Zu warm. > Man müsste einfach R[0,1] mit 0.572 vergleichen. Ja, so geht. math rulez. Cheers Detlef
:
Bearbeitet durch User
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.