So, nach dem meine vorherige Frage in einen Bereich verschoben wurde, der mit dem Thema gar nichts zu tun hat und dort dementsprechend auch nicht verstanden wurde, versuche ich, das Problem mal anders darzustellen. Es geht mir hier um eine rein mathematische Fragestellung und dementsprechend auch um eine rein mathematische Lösung für exakt dieses Problem. Eigentlich kann die Lösung nicht so kompliziert sein, allerdings stehe ich gerade komplett auf dem Schlauch: Ich habe einen Wertebereich (der als linear anzunehmen ist) mit Messwerten, bei denen ich real folgende Werte habe: - Minimalwert ist 193 - Mittelwert ist 2221 - Maximalwert ist 4070 Der interne Wertebereich, den ich zur Verfügung habe, geht von 0 bis 4095. Jetzt würde ich die realen Werte gerne so skalieren, dass sie einerseits den internen Wertebereich so gut wie möglich ausnutzen (bis ganz nach 0 wird es auf Grund des hohen realen Minimalwertes wohl nicht gehen können!?), andererseits der Mittlerwert bei exakt 2048 liegt. Heißt, ich muss einen Skalierungsfaktor und einen Offset ermitteln, der diese Bedingungen erfüllt und mit denen ich jeden anderen, realen Messwert im Bereich 193..4070 auf eben den internen Wert im Bereich von 0..4095 konvertieren kann. Rechenleistung ist dabei kein Problem, Fließpunktzahlen sind vorhanden. Wie kriege ich hier einen passenden Offset und Faktor ermittelt?
Arbeite doch mal die Antworten durch die du schon bekommen hast. Beitrag "ADC-Wert skalieren" Eine andere Möglichkeit wäre eine LUT, siehe... https://blog.stratifylabs.dev/device/2013-10-03-ADC-Thermistor-Circuit-and-Lookup-Table/
Z.B. Max Z. schrieb: > Wie kriege ich hier einen passenden Offset und Faktor ermittelt? Mit Schulmathematik 7. Klasse.
Z.B. Max Z. schrieb: > Ich habe einen Wertebereich (der als linear anzunehmen ist) mit > Messwerten, bei denen ich real folgende Werte habe: > > - Minimalwert ist 193 > - Mittelwert ist 2221 > - Maximalwert ist 4070 Da ist nix linear. Wenn es linear wäre, wäre der Mittelwert 2131.
:
Bearbeitet durch User
Wie schon geschrieben wurde, die Werte:
1 | 0: 193 |
2 | 0.5: 2221 |
3 | 1: 4070 |
sind nicht linear. Sie entsprächen z.B. dem Polynom:
1 | 193 +4235*x -358*x*x |
Mittels Polynominterpolation[1] kann man ein Polynom berechnen, das dein gewünschtes mapping erzeugt:
1 | -184.15408271593785 + 0.9493263981267704*x + 0.000025076857834335404*x*x |
liefert für:
1 | 193: 0 |
2 | 2221: 2048 |
3 | 4070: 4095 |
Ich bezweifel aber, dass das das ist, was du suchst ... [1] https://de.wikipedia.org/wiki/Polynominterpolation
:
Bearbeitet durch User
Z.B. Max Z. schrieb: > Offset und Faktor Offset und Faktor sind Begriffe, die auf ein lineares Gleichungssystem a*x+b hindeuten, mit a als Faktor und b als Offset. Deine Vorgabewerte liegen aber nicht auf einer Linie, sie lassen sich also durch ein lineares Gleichungssystem nicht abbilden. Insofern: Z.B. Max Z. schrieb: > Wie kriege ich hier einen passenden Offset und Faktor ermittelt? Gar nicht. LG, Sebastian
Z.B. Max Z. schrieb: > Heißt, ich muss einen Skalierungsfaktor und einen Offset ermitteln, der > diese Bedingungen erfüllt und mit denen ich jeden anderen, realen > Messwert im Bereich 193..4070 auf eben den internen Wert im Bereich von > 0..4095 konvertieren kann. Rechenleistung ist dabei kein Problem, > Fließpunktzahlen sind vorhanden.
1 | uint16_t normalize_value(uint16_t min, uint16_t max, uint16_t value, uint16_t new_max){ |
2 | return (uint32_t)(value-min)*new_max/(max-min); |
3 | }
|
normalize_value(193, 4070, 193, 4095) -> 0 (0%) normalize_value(193, 4070, 2221, 4095) -> 2142 (~52%) normalize_value(193, 4070, 4070, 4095) -> 4095 (100%) PS: Wenn ungenaue floats erlaubt sind, normalisiere ich gerne auf 0..1. Also "(double)(value-min)/(max-min)". Dass kann man dann einfach mit 4095 multiplizieren, und schon geht's von 0..4095. Und wenn man mehrere Werte im Bereich 0..1 hat, kann man die auch multiplizieren usw., und hat wieder einen Wert von 0..1. Es wird alles einfacher, sobald man merkt, das 100% = 100/100 = 1 ist.
:
Bearbeitet durch User
Z.B. Max Z. schrieb: > Ich habe einen Wertebereich (der als linear anzunehmen ist) Wenn Du die 3 Werte in ein Koordinatensystem einträgst, wirst Du sehen, dass Du da keine Gerade durchziehen kannst. Der Wertebereich ist daher nicht linear. > Wie kriege ich hier einen passenden Offset und Faktor ermittelt? Wenn Du einen Deiner 3 Punkte ignorierst, ist das einfach: Geradengleichung ist:
1 | y = a * x + b |
Bestimmung von Steigung a:
1 | a=(y2–y1)/(x2–x1) |
Fehlt nur noch der y-Achsenabschnitt b:
1 | b = y - a * x |
Konkret für Punkt (x1,y1):
1 | b = y1 - a * x1 |
Das ganze klappt aber nur mit 2 Punkten. Wenn der Wertebereich tatsächlich linear wäre, dann könntest Du einen der 3 Punkte ignorieren. Geht aber nicht, da die 3 Punkte nicht auf einer Geraden liegen. Egal, welche zwei Punkte Du von den dreien auswählst, wirst Du jedesmal eine andere Geradengleichung erhalten - eben weil sie nicht auf einer Geraden liegen. Egal, wie oft Du für das Thema einen neuen Thread öffnest, wirst Du keine zufriedenstellende Lösung erhalten. Das liegt daran, dass Deine Annahme, der Wertebereich sei linear, für die angegebenen Punkte einfach falsch ist. Also: Entweder sind die 3 Punkte (damit Deine Messung) falsch oder Deine Annahme ist falsch. Dieser Widerspruch ist durch wiederholte Fragen einfach nicht auflösbar. Tipp: Ziehe eine Gerade durch den minimalen und den mittleren Punkt. Ziehe eine zweite Gerade durch den mittleren Punkt zum maximalen Punkt. Wende darauf die obigen Formeln an. Dann erhältst Du zwei Geradengleichungen. Mit der ersten Geradengleichung kannst Du dann Punkt zwischen Min und Mittel extrapolieren, mit der zweiten Geradengleichung die Punkte zwischen Mittel und Max. Immerhin ist das einfacher als mit Polynomen herumrechnen zu müssen. Die Genauigkeit wird vielleicht Deinen Ansprüchen nicht genügen. Das ist aber Dein Problem. Alternativ könntest Du Deine Messwerte anzweifeln und da nochmal neu ansetzen.
:
Bearbeitet durch Moderator
Sebastian W. schrieb: > Gar nicht. Was du allerdings machen könntest, wäre aus den drei Meßpunkten eine Gerade zu berechnen, die die Summe der Fehlerquadrate minimiert. Das geht recht einfach in Excel. Trage deine drei Punkte ein, erstelle daraus einen xy-Graphen, und wähle dann "lineare Interpolation" und "Formel einblenden". Dann zeigt Excel dir Offset und Faktor einer "besten" Annäherung. LG, Sebastian
:
Bearbeitet durch User
Z.B. Max Z. schrieb: > für exakt dieses > Problem. Ich gehe von einem linearen System aus. Hier ne Opamp Loesung (Levelshifting) mit Gleichung. siehe Anhang
Z.B. Max Z. schrieb: > So, nach dem meine vorherige Frage Die da im Beitrag "ADC-Wert skalieren" > in einen Bereich verschoben wurde, > der mit dem Thema gar nichts zu tun hat Du siehst das aus einer seltsamen Sicht, denn deine Aufgabe hat mit der verwendeten Toolchain überhaupt nichts zu tun. Wenn dir "uC und Digitaltechnik" irrigerweise falsch vorkommt, dann nimm wenigstens "Signalverarbeitung". Z.B. Max Z. schrieb: > folgende Werte habe: > > Minimalwert ist 193 > Mittelwert ist 2221 > Maximalwert ist 4070 > > Der interne Wertebereich, den ich zur Verfügung habe, geht von 0 bis > 4095. > Jetzt würde ich die realen Werte gerne so skalieren, dass sie einerseits > den internen Wertebereich so gut wie möglich ausnutzen (bis ganz nach 0 > wird es auf Grund des hohen realen Minimalwertes wohl nicht gehen > können!?), andererseits der Mittlerwert bei exakt 2048 liegt. Weil das offenbar sehr viel mit "ich will unbedingt!" zu tun hat, würde ich die Eingangswerte mit zwei(!) unabhängigen(!) Geraden so skalieren, dass 193..2220 auf 0..2047 sowie der Bereich 2221..4070 auf 2048..4095 abgebildet werden. Brute Force at its best.
Moin, Z.B. Max Z. schrieb: > Es geht mir hier um eine rein mathematische Fragestellung und > dementsprechend auch um eine rein mathematische Lösung für exakt dieses > Problem. Rein mathematisch hast du erstmal 3 Gleichungen fuer 3 Punkte in deinem Bereich. Daraus kannst du dir 3 Unbekannte errechnen - das gibt eine quadratische Funktion (Polynom 2.Kajuete). Die wurde dir schon vorexerziert und geht exakt durch die 3 gegebenen Punkte. Du kannst aber auch hergehen und sagen: Ich will da mit Gewalt eine Gerade, also ein Polynom 1.Kajuete, durchlegen - dann hast du 2 Moeglichkeiten: 1.) Du laesst aus deinen 3 Gleichungen fuer 3 Punkte einfach mal eine Gleichung weg, evtl. die, wo du spaeter Abweichungen am besten tolerieren kannst. Dann berechnest du die Gerade fuer diesen Fall und lebst mit der Abweichung, die du dann fuer die weggelassene Gleichung hast. 2.) Du hast ein ueberbestimmtes Gleichungssystem, da kannst du in deinem Fall eine Gleichung fuer eine Gerade berechnen, bei der der Fehler, also die (Quadrate der) Abweichung zur quadratischen Funktion minimal wird. Dann geht deine Gerade aber wahrscheinlich durch keinen der gegebenen Punkte genau, sondern halt nur so ungefaehr. Aber das beste Ungefaehr, was du kriegen kannst. recht viel mehr wird das Problem wohl nicht hergeben, vermute ich mal. Gruss WK
Z.B. Max Z. schrieb: > Wie kriege ich hier einen passenden Offset und Faktor ermittelt? Grundschulmathematik ?
Lothar M. schrieb: > würde ich die Eingangswerte mit zwei(!) unabhängigen(!) Geraden so > skalieren, dass 193..2220 auf 0..2047 sowie der Bereich 2221..4070 auf > 2048..4095 abgebildet werden. Brute Force at its best. Das geht übrigens etwa so:
1 | if (x<2221) y = ((x-193L )*((2047L*63356L)/(2221-193))) /63356L; |
2 | else y = (((x-2221L)*((2047L*63356L)/(4070-2221)))/63356L)+2048L; |
- https://onlinegdb.com/QgrRrlJ3K Oder wer es lieber auf float will, weil ihm die Rechenzeit egal ist:
1 | if (x < 2221) y = (long) ((x - 193.0) *2047.0 / (2221.0-193.0)); |
2 | else y = (long) ((x - 2221.0)*2047.0 / (4070.0-2221.0) + 2048); |
- https://onlinegdb.com/6t2xId8kd
Z.B. Max Z. schrieb: > Eigentlich kann die Lösung nicht so kompliziert sein, allerdings stehe > ich gerade komplett auf dem Schlauch Ich finde es immer wieder erstaunlich, dass genau die Leute, die es selber nicht hinbekommen, sich oft anmaßen, den Kompliziertheitsgrad einer Lösung als "nicht so kompliziert" beurteilen zu können. Und nein, es ist in der Tat nicht sonderlich kompliziert. Z.B. Max Z. schrieb: > Ich habe einen Wertebereich (der als linear anzunehmen ist) mit > Messwerten, bei denen ich real folgende Werte habe: > > - Minimalwert ist 193 > - Mittelwert ist 2221 > - Maximalwert ist 4070 Was ist ein "linearer Wertebereich"? Bevor du mit solchen Begriffen um dich wirfst, solltest du wenigstens ein ganz klein wenig verstehen, wovon du sprichst. Der Mittelwert hängt von der Verteilung deiner Messwerte ab und ist eine statistische Größe. Woraus ist deine 2221 gemittelt? Falls es die Mitte zwischen Minimal- und Maximalwert sein soll, hast du einen NICHTlinearen Zusammenhang. Dein Annahme wäre dann falsch. Eine andere Möglichkeit ist, dass deine Messwerte fehlerbehaftet sind und den funktionalen Zusammenhang nur innerhalb eines gewissen Fehlerbandes darstellen. Eine weitere Möglichkeit ist, dass der Zusammenhang nichtlinear ist, du das Verhalten aber nur an diesen drei Punkten kennst und damit eine Parabel die rein mathematische Lösung für dein Problem wäre. Oder du beharrst auf "Linear" und betrachtest den Zusammenhang als abschnittsweise linear, wie von Lother vorgeschlagen, darfst dich dann aber nicht über den Knick beim mittleren Wert wundern.
:
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.