![]() |
Berechnung eines Wertes aus Widerstandsreihe
Moin,
ich wollte meinen Elektrorechner mal um eine häufig gefragt Funktion erweitern...die genormten Widerstandsreihen (E3,E6,E12,E24,E48,E96,E192). als Dokumentation hab ich da u.a. ![]() laut dieser und anderer Quellen lassen sich die werte berechnen aus der (n-ten Wurzel aus 10)^(position-1). Leider habe komme ich teilweise nicht auf die richtigen Werte (trotz runden). z.B. Reihe E6 => k=1,4677 (6.wurzel aus 10) der 4.wert sollte also ~3,3 sein ich komme jedoch auf 3,161636106733 was ich nicht wirklich auf 3,3 runden kann... kennt sich damit evtl jemand aus? Gruß Frank |
Re: Berechnung eines Wertes aus Widerstandsreihe
Wenn Du einmal in diesem
![]() Deine Berechnungen bestätigt. Und viellecht hilft das noch zur Erklärung (Quelle Wiki): Zitat:
Klaus |
Re: Berechnung eines Wertes aus Widerstandsreihe
Liste der Anhänge anzeigen (Anzahl: 1)
Servus
ich kann mich da nur anschließen, weil die E6 Reihe eine ziemlich große Toleranz hat (20%). Ich hab das mal durchgerechnet (siehe Bild) und ich komm dabei auf einen Toleranzbereich von 2,52982 bis 3,79473 Ohm. Da passen die 3,3 Ohm locker rein :-D. Wenn interesse am Sourcecode besteht, muß ich ihn erstmal aufräumen und poste ihn dann gern. Greetz |
Re: Berechnung eines Wertes aus Widerstandsreihe
es geht mir nicht darum die 3,3 abzudecken, sondern den Wert für ein Bauteil (welches sich an eine der E-Reihen hält) zu einem berechneten Widerstandswert zu bekommen.
wenn ich einen widerstand von 3,2 Ohm ausgerechnet habe, müsste ich z.b. nach E6-Reihe einen 3,3 Ohm verbauen. und diese 3,3 will ich haben. //edit da diese rundungsfehler bekannt sind muss ich das ganze wohl so in etwa machen:
Delphi-Quellcode:
Gruß Frank
procedure TForm1.Button1Click(Sender: TObject);
const //r3:array[0..2] of double=(1.0,2.2,4.7); //r6:array[0..5] of double=(1.0,1.5,2.2,3.3,4.7,6.8); //r12:array[0..11] of double=(1.0,1.2,1.5,1.8,2.2,2.7, 3.3,3.9,4.7,5.6,6.8,8.2); r24:array[0..23] of double=(1.0,1.1,1.2,1.3,1.5,1.6,1.8,2.0,2.2,2.4,2.7, 3.0,3.3,3.6,3.9,4.3,4.7,5.1,5.6,6.2,6.8,7.5,8.2,9.1); r192:array[0..191] of double=(1.00,1.01,1.02,1.04,1.05,1.06,1.07,1.09, 1.10,1.11,1.13,1.14,1.15,1.17,1.18,1.20, 1.21,1.23,1.24,1.26,1.27,1.29,1.30,1.32, 1.33,1.35,1.37,1.38,1.40,1.42,1.43,1.45,1.47,1.49, 1.50,1.52,1.54,1.56,1.58,1.60,1.62,1.64,1.65,1.67,1.69, 1.72,1.74,1.76,1.78,1.80,1.82,1.84,1.87,1.89,1.91,1.93,1.96,1.98, 2.00,2.03,2.05,2.08,2.10,2.13,2.15,2.18,2.21,2.23,2.26,2.29, a2.32,2.34,2.37,2.40,2.43,2.46,2.49, 2.52,2.55,2.58,2.61,2.64,2.67,2.71,2.74,2.77,2.80,2.84,2.87,2.91,2.94,2.98, 3.01,3.05,3.09,3.12,3.16,3.20,3.24,3.28,3.32,3.36,3.40,3.44,3.48, 3.52,3.57,3.61,3.65,3.70,3.74,3.79,3.83,3.88,3.92,3.97, 4.02,4.07,4.12,4.17,4.22,4.27,4.32,4.37,4.42,4.48, 4.53,4.59,4.64,4.70,4.75,4.81,4.87,4.93,4.99, 5.05,5.11,5.17,5.23,5.30,5.36,5.42,5.49, 5.56,5.62,5.69,5.76,5.83,5.90,5.97, 6.04,6.12,6.19,6.26,6.34,6.42,6.49, 6.57,6.65,6.73,6.81,6.90,6.98, 7.06,7.15,7.23,7.32,7.41, 7.50,7.59,7.68,7.77,7.87,7.96, 8.06,8.16,8.25,8.35,8.45, 8.56,8.66,8.76,8.87,8.98, 9.09,9.20,9.31,9.42, 9.53,9.65,9.76,9.88 ); begin if spinedit1.value<(3 shl Combobox1.itemindex) then //maximalwert prüfen E3=2,E6=5,... begin if combobox1.itemindex<4 then showmessage(FloatToStr(r24[(1 shl (Combobox1.Items.count-(Combobox1.itemindex+4))*Spinedit1.value)])) else showmessage(FloatToStr(r192[(1 shl (Combobox1.Items.count-(Combobox1.itemindex+1))*Spinedit1.value)])); end else showmessage('Position zu hoch'); end; [edit=Phoenix]Umbrüche wegen Layout eingefügt Mfg, Phoenix[/edit] |
Re: Berechnung eines Wertes aus Widerstandsreihe
Zitat:
das mit der n-ten Wurzel ist die Theorie für E192, in der Praxis wird aber jede abgeleitete Reihe auf möglichst wenige Stellen gerundet und in sich abgeglichen. Eine Formel gibt es für die resultierenden Zahlenreihen nicht, sie sind einfach nach EIA genormt. Man kann auch nicht nach der eigentlich naheliegenden Regel vorgehen, jeder 8. Wert aus E192 gäbe den Wert in E24 usw. Du wirst also wohl oder übel ALLE Reihen E6 bis E912 abtippen müssen, z.B. hier: ![]() Gruss Reinhard |
Re: Berechnung eines Wertes aus Widerstandsreihe
Hat er ja schon :-D
Jetzt muß er ja nur noch den nächstgrößeren Widerstandswert aus der zugehörigen E-Reihe herausholen. Wird wohl die einzige Lösung sein, wenn mans nicht berechnen kann |
Re: Berechnung eines Wertes aus Widerstandsreihe
ich habe die reihen miteinander verglichen und festgestellt, dass ich eigentlich nur die reihe 24 und 192 abtippen muss.
Die Werte der dazwischenliegenden Reihen sind in den beiden vorhanden. d.h. alle werte der reihen E3, E6 und E12 sind in gleich abständen in der E24 enthalten, gleiches für E48, E96 in E192, wenn ich nicht irgendetwas übersehen habe... jetzt brauche ich nur noch einen algo um möglichst schnell zu dem passenden wert zu kommen. 1. müsste ich auf 1 Stelle vor dem komma kommen (könnte zwar solange /10 machen, bis dieser punkt erreicht ist, aber gibt sicherlich bessere Varianten) 2. dann innerhalb der dekade den jeweiligen wert finden, was aber in Reihe 192 sehr rechenintensiv ist. naja, abgetippt hab ich die nicht, copy&paste ins excel, spalte in scite und per search&replace (teils mit regex) das array zusammengebastelt. ;) Gruß Frank |
Re: Berechnung eines Wertes aus Widerstandsreihe
Wie wärs damit:
Mein erster Code-Post hier im Forum :bounce2: Hoffentlich passt alles *schwitz* Hab mir mal die Freiheit genommen, deine schönen Arrays zu verwenden
Delphi-Quellcode:
Habs paarmal getestet und müsste funktionieren. Ich hab allerdings alle E-Reihen verwendet, weil es ja in der E24 Reihe Widerstände gibt, die in der E6 Reihe nicht auftauchen.
var
a: integer; // ist die verwendete E_Reihe z.B. 6 e_Reihe : integer; // das Array das zum bestimmen verwendet wird Ex_Reihe : array[0..200] of double; // der Widerstand, den du berechnet hast z.B. 3.1 Ohm widerstand: real; // der Widerstand, der dem nächstgelegenen in der E-Reihe entspricht; hier 3.3 Ohm widerstand_nach_e : real; begin // Berechneten Widerstandswert festlegen widerstand := 7.0; // E-Reihe festlegen E_reihe := 6; // deine schönen Arrays in eins zum berechnen übertragen for a := 0 to E_reihe-1 do case e_reihe of 3: ex_reihe[a] := r3[a]; 6: ex_reihe[a] := r6[a]; 12: ex_reihe[a] := r12[a]; { .. } 24: ex_reihe[a] := r24[a]; 192: ex_reihe[a] := r192[a]; end; // Sollte der Widerstandswert größer sein, als der größte der E-Reihe, so ist die Ausgabe // 1.0 Ohm mit einem größeren Multiplikator if widerstand > Ex_Reihe[e_reihe-1] then widerstand_nach_e := 10 else // Eigentliche Auswahlroutine for a := E_Reihe-1 downto 0 do begin if widerstand < Ex_reihe[a] then widerstand_nach_e := ex_reihe[a]; end; label4.caption := 'Nächter Widerstand nach E'+inttostr(e_reihe)+ ': '+floattostrf(widerstand_nach_e,fffixed,10,5); greetz |
Re: Berechnung eines Wertes aus Widerstandsreihe
Hallo,
es gibt noch einen thread zum gleichen Thema, an den ich mich noch erinnere: ![]() Grüße vom marabu |
Re: Berechnung eines Wertes aus Widerstandsreihe
danke marabu, werde mir das mal genauer anschauen. was mir gleich auffällt, ist die Verwendung von Integers statt floats (welches sicherlich schneller geht). Ich werde daher auch floats verwenden (=100er Dekade).
Gibt es eine Möglichkeit einen Wert schneller auf diese dekade zu kommen als so in der Art (ungetested):
Delphi-Quellcode:
Gruß Frank
function tohundreddecade(value:double;var dir:integer):integer;
var ftmp:double; itmp:integer; begin //direction zur rückrechnung in ursprünglichen Wert //result ist natürlich der dekadenwert //itmp ist die temporäre integer-var;ftmp die für floats dir:=0; result:=0; ftmp:=value; if value <100 then begin while ftmp<100 do begin ftmp:=ftmp*10; inc(dir); end; end else if value>999 then begin itmp:=trunc(ftmp); while ftmp>999 do begin itmp:=itmp div 10; dec(dir); end; result:=itmp; end; if result=0 then result:=trunc(ftmp); end; |
Re: Berechnung eines Wertes aus Widerstandsreihe
Hallo Frank,
etwas kompakter - wenn dich die höheren Rechenarten nicht stören - geht es so:
Delphi-Quellcode:
Freundliche Grüße
uses
Math; function Norm(e: Extended; var dExp: Integer): Extended; begin dExp := Ceil(Log10(e)) - 3; Result := e / Power(10, dExp); end; |
Re: Berechnung eines Wertes aus Widerstandsreihe
danke dir marabu (auf log10 hätte auch kommen können ;)).
hab die Funktion noch bisschen modifiziert, da ich die Nachkommastellen des "Hunderterwertes" nicht benötige.
Delphi-Quellcode:
Gruß Frank
uses math;
function Norm(e: Extended; var dExp: Integer): Integer; begin dExp := Ceil(Log10(e)) - 3; Result := round(e / Power(10, dExp)); end; procedure TForm1.Button1Click(Sender: TObject); var dExp: Integer; begin edit2.text:=inttostr(Norm(strtofloat(edit1.text),dexp)); end; |
Re: Berechnung eines Wertes aus Widerstandsreihe
Vielleicht solltest du statt Round() die Funktion Trunc() verwenden - sonst fliegst du ab 999.5 doch noch aus der Dekade raus.
Freundliche Grüße |
Re: Berechnung eines Wertes aus Widerstandsreihe
würde ich so oder so, denn der nächste widerstandswert *jeder* Reihe wäre 100 der nächsten dekade, da muss ich noch überlegen wie ich das mache...das round ist also nicht das problem selbst, ich müsste lediglich bei einem nicht gefundenen Wert die nächste dekade verwenden.
Gruß Frank |
Re: Berechnung eines Wertes aus Widerstandsreihe
Durch die Log10()-Funktion wird der Eingabewert korrekt auf das nach oben halboffene Intervall [100, 1000) abgebildet. Durch die Einführung des Round() fällt das Ergebnis bei Werten zwischen [999.5, 1000) aus dem definierten Bildbereich heraus. Das würde mir aus mathematischer Sicht nicht gefallen.
Die Abbildung auf den Eingangswert der nächsten Dekade ist einfach, wenn du eine binäre Suche
Delphi-Quellcode:
auf einer beliebigen übergebenen E-Reihe implementierst. Ist der Rückgabewert gleich series.Count, dann ist der Eingangswert der richtige und dExp muss um eins inkrementiert werden.
function Find(value: Double; series: TDoubleDynArray; var index: Integer): Integer;
Freundliche Grüße |
Re: Berechnung eines Wertes aus Widerstandsreihe
Hallo und frohes Neues :party: ,
ich habe ma versucht, das Code-Beispiel von AmateurProfi im verlinkten Post zu modifizieren, leider ist da ein Syntax-Fehler drin, mit dem ich nicht wirklich klar komme. ein weiteres Problem ist, das ich mit Teilmengen des Arrays hantieren muss/will, um nicht alle 7 reihen abtippen zu müssen sondern nur die 2 (E24 und E192).Es muss also eine Schrittweite verwendet werden. mein Versuch:
Delphi-Quellcode:
beim Aufruf
const
e3=0; e6=1; e12=2; e24=3; e48=4; e96=5; e192=6; function FindValue(reihe:byte; wert:integer):integer; const //r3:array[0..2] of double=(1.0,2.2,4.7); //2^0 //r6:array[0..5] of double=(1.0,1.5,2.2,3.3,4.7,6.8);//2^1 //r12:array[0..11] of double=(1.0,1.2,1.5,1.8,2.2,2.7,3.3,3.9,4.7,5.6,6.8,8.2); //2^2 r24:array[0..23] of integer=(100,110,120,130,150,160,180,200,220,240,270,300,330,360,390,430,470,510,560,620,680,750,820,910);//schrittweite 8 (1,9,...) =>E3 2^3 r192:array[0..191] of double=( 100,101,102,104,105,106,107,109,110,111,113,114,115,117,118,120,121,123,124,126,127,129,130,132,133,135,137,138,140,142,143,145,147,149, 150,152,154,156,158,160,162,164,165,167,169,172,174,176,178,180,182,184,187,189,191,193,196,198, 200,203,205,208,210,213,215,218,221,223,226,229,232,234,237,240,243,246,249, 252,255,258,261,264,267,271,274,277,280,284,287,291,294,298, 301,305,309,312,316,320,324,328,332,336,340,344,348, 352,357,361,365,370,374,379,383,388,392,397, 402,407,412,417,422,427,432,437,442,448, 453,459,464,470,475,481,487,493,499, 505,511,517,523,530,536,542,549, 556,562,569,576,583,590,597, 604,612,619,626,634,642,649, 657,665,673,681,690,698, 706,715,723,732,741, 750,759,768,777,787,796, 806,816,825,835,845, 856,866,876,887,898, 909,920,931,942, 953,965,976,988 ); var first,last,actual,step:integer; begin first:=0; last:=(3 shl reihe)-1; showmessage(IntToStr(last)); step:=1 shl (7-(reihe+4)); repeat actual:=(first+last) shr 1;//(last div 2)*step;//(first+last) shr 1; result:=r24[actual*step]; if result<>wert then begin if result>wert then last:=actual-1 else last:=actual+1; end else exit; until first>last; if first<=((3 shl reihe)-1) then result:=r24[0]; end;
Delphi-Quellcode:
wird die schleife nicht verlassen, es sollte natürlich 680 gefunden werden.
showmessage(IntToStr(findValue(e6,500)));
kann die Berechnung (bzw. den Sinn) von actual am anfang der schleife nicht nachvollziehen, da der wert kleiner wird, obwohl er größer werden sollte... kann mir da jemand helfen? Gruß Frank |
Re: Berechnung eines Wertes aus Widerstandsreihe
Alles Gute im Neuen Jahr, Frank.
Ob das eine wirklich gute Idee ist - innerhalb der binären Suche eine Schrittweite einzuführen? Ich würde das außen vor lassen:
Delphi-Quellcode:
Getippt und nicht getestet.
const
E6: array [0..5] of Integer = (100, 150, 220, 330, 470, 680); function Find(value: Integer; series: array of Integer; var index: Integer): Boolean; var iLow, iHigh, i, c: Integer; begin Result := False; iLow := 0; iHigh := High(series); while not Result and (iLow <= iHigh) do begin i := (iLow + iHigh) shr 1; if series[i] < value then iLow := Succ(i) else iHigh := Pred(i); Result := series[i] = value; if Result then iLow := i; end; index := iLow; end; // Test var i, r: Integer; begin Find(500, E6, i); if i = Length(E6) then r := 10 * E6[0] else r := E6[i]; end; Freundliche Grüße |
Re: Berechnung eines Wertes aus Widerstandsreihe
hi,
naja, die Arrays der unteren Reihen sind ja noch überschaubar, da würde das nicht stören. Aber die reihen e48,e96 und e192 wären meines Erachtens sinnlose schreibarbeit, wenn man Schrittweiten verwenden kann...ich würde daher schon gern mit den Schrittweiten rechnen. Diese sollte sich aber so ähnlich realisieren lassen, wie ich es probiert habe (pseudo-index verwenden und den werte-vergleich mittels pseudo-index * schrittweite machen). dein test ergibt übrigens den falschen Wert (1000). Gruß Frank |
Re: Berechnung eines Wertes aus Widerstandsreihe
so funktioniert es fast...
Delphi-Quellcode:
nur wenn der schleifenstartwert (bei e6 220=actual 2) der richtige wäre, ist das Ergebnis falsch. z.B.
FUNCTION FindValue(reihe:byte; wert:integer):integer;
const //r3:array[0..2] of double=(1.0,2.2,4.7); //2^0 //r6:array[0..5] of double=(1.0,1.5,2.2,3.3,4.7,6.8);//2^1 //r12:array[0..11] of double=(1.0,1.2,1.5,1.8,2.2,2.7,3.3,3.9,4.7,5.6,6.8,8.2); //2^2 r24:array[0..23] of integer=(100,110,120,130,150,160,180,200,220,240,270,300,330,360,390,430,470,510,560,620,680,750,820,910);//schrittweite 8 (1,9,...) =>E3 2^3 r192:array[0..191] of double=( 100,101,102,104,105,106,107,109,110,111,113,114,115,117,118,120,121,123,124,126,127,129,130,132,133,135,137,138,140,142,143,145,147,149, 150,152,154,156,158,160,162,164,165,167,169,172,174,176,178,180,182,184,187,189,191,193,196,198, 200,203,205,208,210,213,215,218,221,223,226,229,232,234,237,240,243,246,249, 252,255,258,261,264,267,271,274,277,280,284,287,291,294,298, 301,305,309,312,316,320,324,328,332,336,340,344,348, 352,357,361,365,370,374,379,383,388,392,397, 402,407,412,417,422,427,432,437,442,448, 453,459,464,470,475,481,487,493,499, 505,511,517,523,530,536,542,549, 556,562,569,576,583,590,597, 604,612,619,626,634,642,649, 657,665,673,681,690,698, 706,715,723,732,741, 750,759,768,777,787,796, 806,816,825,835,845, 856,866,876,887,898, 909,920,931,942, 953,965,976,988 ); var first,last,actual,step:integer; found:boolean; begin first:=0; last:=(3 shl reihe)-1; step:=1 shl (7-(reihe+4)); found:=false; actual:=-1; while not found and (first<=last) do begin actual:=(first+last) shr 1; if r24[actual*step]<wert then first:=actual+1 else last:=actual-1; end; if first>((3 shl reihe)-1) then result:=r24[0]*10 else result:=r24[actual*step]; end;
Delphi-Quellcode:
gibt mir nicht 220 sondern 150, das dieses der nächst-tiefere wert ist.
showmessage(IntToStr(findValue(e6,215)));
Wie könnte man das lösen? |
Re: Berechnung eines Wertes aus Widerstandsreihe
Hi,
Zitat:
Hier mein Versuch mit verschachtelten Serien:
Delphi-Quellcode:
Du wirst erkennen, wie du es umbauen kannst, damit es mit E192 arbeitet.
type
TSeries = ({e192, e96, e48,} e24, e12, e6, e3); function Lookup(value: Integer; series: TSeries): Integer; const values: array [0..23] of Integer = ( 100,110,120,130,150,160,180,200, 220,240,270,300,330,360,390,430, 470,510,560,620,680,750,820,910 { 100,101,102,104,105,106,107,109,110,111,113,114,115,117,118,120, 121,123,124,126,127,129,130,132,133,135,137,138,140,142,143,145, 147,149,150,152,154,156,158,160,162,164,165,167,169,172,174,176, 178,180,182,184,187,189,191,193,196,198,200,203,205,208,210,213, 215,218,221,223,226,229,232,234,237,240,243,246,249,252,255,258, 261,264,267,271,274,277,280,284,287,291,294,298,301,305,309,312, 316,320,324,328,332,336,340,344,348,352,357,361,365,370,374,379, 383,388,392,397,402,407,412,417,422,427,432,437,442,448,453,459, 464,470,475,481,487,493,499,505,511,517,523,530,536,542,549,556, 562,569,576,583,590,597,604,612,619,626,634,642,649,657,665,673, 681,690,698,706,715,723,732,741,750,759,768,777,787,796,806,816, 825,835,845,856,866,876,887,898,909,920,931,942,953,965,976,988 } ); var iLow, iHigh, iStep, i: Integer; begin Result := 10 * values[0]; iStep := 1 shl Ord(series); iLow := 0; iHigh := Pred(Length(values) div iStep); while iLow <= iHigh do begin i := (iLow + iHigh) shr 1; if values[i * iStep] < value then iLow := Succ(i) else iHigh := Pred(i); if values[i * iStep] = value then iLow := i; end; if iLow * iStep < Length(values) then Result := values[iLow * iStep]; end; procedure TDemoForm.Button11Click(Sender: TObject); var s: String; begin s := ''; while InputQuery('E6 search', 'value', s) do s := IntToStr(Lookup(StrToInt(s), E6)); end; Gute Nacht |
Re: Berechnung eines Wertes aus Widerstandsreihe
Liste der Anhänge anzeigen (Anzahl: 1)
danke dir, glaube ich habe es jetzt hinbekommen...meine bisherigen Tests haben funktioniert
für die, die es interessiert das Projekt im Anhang Gruß Frank |
Re: Berechnung eines Wertes aus Widerstandsreihe
Hi,
vlt kann dir der Autor weiterhelfen. Er hat mir auch schon Helfen können bei Fragen: ![]() |
Re: Berechnung eines Wertes aus Widerstandsreihe
das Hauptproblem hab ich ja dank euch gelöst, denk ich :gruebel:
aber ich werde mir das Programm mal anschauen, sieht auch sehr interessant aus... Gruß Frank |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:13 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz