Ich brauch mal wieder Hilfe zum Verständnis einer INO

Hallo,

in den Weiten des Netzes habe ich ein interessantes Projekt gefunden und nach meinen Ideen nachgebaut.

Es funktioniert auch gut, allerdings gibt es ein paar Fragen und eine Macke.

Das Projekt habe ich hier beschrieben:

Ein HV Kondensator-Lecktester
(ich hoffe externe URLs sind erlaubt)

Mein Problem:
Es wird der Spannungsabfall über einem 150-Ohm Widerstand als Stromwert angezeigt (den ich inzwischen schon auf 1,5k geändert habe). Allerdings geht es um Ströme weit unter 10µA, das Gerät hat derzeit eine Auflösung von 1µA.
Als höchster Wert werden etwa 10mA angezeigt, doch 1mA würde schon reichen.

  1. Es werden IMMER rund 4,5µA zuwenig angezeigt. Ich habe in der INO in die betreffenden Zeilen die tatsächlichen Werte der Teiler-Rs und der Referenzspannung eingetragen, die Spannungsanzeige ist auch relativ genau, nur beim Strom hapert es.
    Als Würgarround habe ich in Zeile 207 statt 0 eine 7 eigetragen (Versuch und Irrtum), etwas besser ist es jetzt. Trage ich mehr ein, wird auch ohne DUT ständig 1µA augegeben.
    Ich vermute derzeit, dass es auf der Platine einen Leckstrom, vorbei am Shunt gibt, das kann aber auch Blödsinn sein.

  2. Ab etwa 300µA beginnt es dann langsam etwas mehr anzuzeigen, als real fließt!

  3. Eigentlich ist mir die Auflösung noch zu dürftig, 0,1µA wären besser :wink:
    Das habe ich sogar hinbekommen, in Zeile 285 den Faktor von 1000 auf 10000 geändert.
    Nur wie funktioniert das nun mit der veränderten Kommastelle? Diese steht jetzt natürlich falsch.

Ich brauche also mal wieder ein paar zielführende “Schubser” :wink:

Old-Papa

Leakage_Tester_V1.2.ino (16 KB)

schönes Gehäuse - wo gibt es das?

(OT: ... ich suche aktuell Metallgehäuse mit LCD 1602 Ausschnitt, aber außer den Verstärker-Gehäusen aus Alu finde ich nicht wirklich was, preisgünstiges schon gar nicht...)

noiasca:
(OT: ... ich suche aktuell Metallgehäuse mit LCD 1602 Ausschnitt, aber außer den Verstärker-Gehäusen aus Alu finde ich nicht wirklich was, preisgünstiges schon gar nicht...)

Für derlei Ausschnitte benutze ich mein Pr*xxon mit Bohrständer und Mikro-Koordinatentisch. Individuelle Ausschnitte fräsen zu können hat was :slight_smile:

Ansonsten gibt's Firmen, die ziemlich frei gestaltbare Frontplatten anfertigen. Das ist halt auch wieder nicht billig (und vielseitig schon gar nicht).

Gruß

Gregor

PS:

noiasca:
schönes Gehäuse - wo gibt es das?

(OT: ... ich suche aktuell Metallgehäuse mit LCD 1602 Ausschnitt, aber außer den Verstärker-Gehäusen aus Alu finde ich nicht wirklich was, preisgünstiges schon gar nicht...)

Gar nicht mehr!

Sowas kaufe ich meist durch Zufall, das hier liegt bestimmt schon 20 Jahre im Schrank.

Old-Papa

Zurück zum eigentlichen Problem.

Als ich eben Deinen Code durchgucken wollte, um zu sehen, ob ich denn überhaupt das Problem verstehe, habe ich bei Zeile 300 aufgehört. Das sieht ja übel aus ... lies doch mal das hier.

Wenn Du die Kommastelle nur für die Ausgabe anders haben möchtest, warum machst Du nicht einfach etwas wie

println(x*1000);

?

Gruß

Gregor

Ich schrieb doch, dass es nicht MEIN Code ist.
Es hilft mir auch nicht, wenn der Code als schlecht bezeichnet wird, besser man erklärt, warum ich das nun so schreiben muss. Ich will das ja verstehen bzw. was lernen.

Was bewirkt also diese zeile? Ja, es wird eine Zeile ausgegeben....

Old-Papa

old-papa:
Ich schrieb doch, dass es nicht MEIN Code ist.
Es hilft mir auch micht, wenn der Code als schlecht bezeichnet wird,...

Und was hilft mir jetzt Deine Bemerkung?!

Gruß

Gregor

Wahrscheinlich auch nichts....

Was oder wie kann ich mit println(x*1000) auf dem LCD ausgeben?
Ja, Arduino ist nicht mein täglich Brot, darum frage ich ja.

Old-Papa

Was das Komma angeht:
Müsstest Du dann nicht in Zeile 342 bei der Ausgabe wieder in der anderen Richtung korrigieren?

Serial.print(current/10.,3); // mA

Edit: Sehe gerade noch die Ausgabe auf der LCD in Zeile 313 und 326 - da natürlich auch:

 lcd.print(current/10.,3);
  i2clcd.print(current/10.,3);

Hallo,

diese ganze serielle Ausgabe nutze ich nicht, auch nicht das Display von Sigorg (oder so)

Eigentlich brauch ich nur den Teil mit dem I2C-LCD

So, was bewirkt Deine Zeile nun?

i2clcd.print(current/10.,3);
Das ",3" bedeute die drei Stellen nach dem Komma, Ja...

Doch wie funktioniert es, dass z.B. ab 10mA das Komma automatisch eine Stelle weiter geht?

Ich teste mal Deine zeile...

Old-Papa

Hallo,

die Abweichung ist konstant. Warum addierst du nicht einfach ein Offset bei der Ausgabe?

Der Wert “current” ist immer shuntvoltage / shuntresistorvalue (Zeile 282)

Wenn Du mit 10000 statt mit 1000 multiplizierst, ändern sich weder Meßgenauigkeit noch Meßwert; nur die “Quantisierung” (Einheit) des in current gespeicherten Wertes.

Mit meiner Zeile habe ich nur Deine Änderung (*10000 statt *1000) bei der Ausgabe rückgängig gemacht - wenn die dahinter im Kommentar stehende Angabe mA erhalten bleiben soll.

Doc_Arduino:
Hallo,

die Abweichung ist konstant. Warum addierst du nicht einfach ein Offset bei der Ausgabe?

Das dachte ich mir auch, bin aber zu doof dazu :wink:
Leider ist die Abweichung nicht ganz konstant, ab etwa 300mA kehrt sich das ins Gegenteil um (es wird etwas mehr angezeigt)

Nochmal das was ich möchte

Anzeige derzeit: 0,000mA (also 1µA Auflösung)
Mein Wunsch: ****,0µA (also 0,1µA Auflösung mit richtiger Kommaposition)
Wie schon geschrieben. in Zeile 295 kann ich den Faktor auf 10000 ändern (steht derzeit auf 1000).

Old-Papa

old-papa:
Anzeige derzeit: 0,000mA (also 1µA Auflösung)
Mein Wunsch: ****,0µA (also 0,1µA Auflösung mit richtiger Kommaposition)
Wie schon geschrieben. in Zeile 295 kann ich den Faktor auf 10000 ändern (steht derzeit auf 1000).

Okay, verstanden.

Zeile 295: 10001000 (die ersten Tausend bringen Dir mA, die zweiten µA)
In allen Ausgabezeilen (weiß jetzt nicht, welche die wirklich wichtige ist) statt “,3” ein “,1”.

Fertig und gute Nacht!

Hallo,

die Kommastellenverschiebung mit 10.000 statt 1000 ist falsch. Der Umrechnungsfaktor von mA in µA ist ja 1000 und nicht 10. Aber selbst wenn du das richtig machst, hast du durch die ganzen Fließkommarechnungen nach dem Komma eh nichts mehr verwertbares, weil alles verschluckt wurde.

Das heißt alle relevanten Rechnungen müssen solange wie möglich mit Ganzzahlen hantieren.

Warum ist currentValue float?
Warum ist voltagereferancevalue float?
Warum ist shuntresistorvalue float?

Kann man ändern in, der Einfachheit alles 32bit unsigned,

const unsigned long currentValue = 7; 
const unsigned long shuntresistorvalue = 1490;          // Ohm
const unsigned long voltagereferancevalue = 4988;	// mV statt V

Wenn du bei letzteren mit mV stat V rechnest hast du automtisch eine höhere Genauigkeit in der Rechnung. Vielleicht funktioniert auch µV statt mV. Dann hättest du mit µV durch Ohm schon µA.

Abgesehen davon würde ich immer soweit wie möglich/sinnvoll mit Ganzzahlen rechnen. Je nachdem was hier für ein Maximalwert zu erwarten ist kann man vor der Division nochmal mit Faktor 1000 erhöhen. Wertebereich von 32bit beachten. Ob man hier schon durch 1023.0 teilt muss man sich überlegen oder ausprobieren.

unsigned long shuntvoltage = currentValue * voltagereferancevalue;

Mindestens muss die Klammer weg von

float shuntvoltage = currentValue * (voltagereferancevalue / 1023.0);

Ansonsten verlierst du schon Rechnengenauigkeit bevor es überhaupt losgeht.

Nimm dir die Formeln raus, bau dir einen Testcode und optimiere die Rechenwege.
Möglichst mit großen Ganzzahlen hantieren um bei Ganzzahl Divisionen die Verluste in Grenzen zu halten. Fließkomma erst wenn es nicht anders geht. Das 32Bit float ist darin sehr begrenzt.

Wow!

Rund 6 Stunden nach dem ersten Posting ist die Lösung noch nicht gefunden und wie viele Leute an der Behebung des Problems mitgewirkt haben, habe ich erst gar nicht gezählt. Und was ich vom OP mitbekomme, ergibt das Bild von einem, der eigentlich nichts kann, außer Code zu kopieren, darin herumzumurksen und hier nach einer „Formel“ für ein supersimples Kommageschubse suchen zu lassen. Naja gut, pampige Antworten kann er. Und das Schreiben des ersten Postings hat vermutlich auch ein paar Kalorien gekostet.

Wenn Freitagnachmittag wäre, würde ich schnell eine Tüte Popcorn holen.

Gruß

Gregor

Und Du bist wahrscheinlich schon mit Arduino-Sprech aus dem Mutterleib gekrochen....

Nein, ich verstehe davon noch immer nicht besonders viel, das ist keine Schande.. Sich darüber lustig zu machen dagegen schon.
Wenn, dann erklärt man was falsch und was besser ist und zwar so, dass es auch der Anfänger versteht. Ein paar hingerotze Textbrocken helfen niemandem.

Vielleicht kommst Du mal in die Lage von anderen Hilfe bei irgendeinem Problem zu erwarten, ich hoffe, die sind dann besser als Du hier.

Old-Papa

wno158:
Was das Komma angeht:
Müsstest Du dann nicht in Zeile 342 bei der Ausgabe wieder in der anderen Richtung korrigieren?

Serial.print(current/10.,3); // mA

Edit: Sehe gerade noch die Ausgabe auf der LCD in Zeile 313 und 326 - da natürlich auch:

 lcd.print(current/10.,3);

i2clcd.print(current/10.,3);

Das brachte überhaupt keine (sichtbare) Änderung.


[/quote]

wno158:
Der Wert "current" ist immer shuntvoltage / shuntresistorvalue (Zeile 282)

Wenn Du mit 10000 statt mit 1000 multiplizierst, ändern sich weder Meßgenauigkeit noch Meßwert; nur die "Quantisierung" (Einheit) des in current gespeicherten Wertes.

Mit meiner Zeile habe ich nur Deine Änderung (*10000 statt *1000) bei der Ausgabe rückgängig gemacht - wenn die dahinter im Kommentar stehende Angabe mA erhalten bleiben soll.

Aha :wink:
Doch ich will ja eben nicht mA sondern mindestens in 0,1µA, also eine Stelle mehr. Das zumindest hatte ich ja mit der 10000 erreicht, ob nun sinnvoll oder nicht :wink: Der Vergleich mit meinem Fluke 8846A sah aber für diesen Anwendungszweck gut aus (das Fluke kann 100pA auflösen!).
Nur die Kommastelle war natürlich noch falsch. Das ist mein eigentliches Verständnisproblem: Wo/wie wird das im Code gemacht?


Doc_Arduino:
Hallo,

die Abweichung ist konstant. Warum addierst du nicht einfach ein Offset bei der Ausgabe?

Das Problem ist wohl gelöst.... Die zum Schutz der Eingänge verbaute Zenerdiode (6,2V) hat offenbar zuviel eigenen Leckstrom (ein Problem vieler Dioden), die wird durch eine andere Schutzschaltung ersetzt.
Dann passt es wohl auch bei höheren µA-Werten bzw. die Abweichung wäre dann nur etwas nach oben und somit leicht korrigierbar.


Doc_Arduino:
Hallo,

die Kommastellenverschiebung mit 10.000 statt 1000 ist falsch. Der Umrechnungsfaktor von mA in µA ist ja 1000 und nicht 10.

Misverständnis: Damit wollte ich nur "eine Null" mehr haben, also von 1,000mA auf 1,0000mA. Die Kommaverschiebung hatte ich ja nicht gefunden :wink:

Doc_Arduino:
Aber selbst wenn du das richtig machst, hast du durch die ganzen Fließkommarechnungen nach dem Komma eh nichts mehr verwertbares, weil alles verschluckt wurde.

Wahrscheinlich, da bin ich noch zu doof für :wink:

Doc_Arduino:
Das heißt alle relevanten Rechnungen müssen solange wie möglich mit Ganzzahlen hantieren.

Warum ist currentValue float?
Warum ist voltagereferancevalue float?
Warum ist shuntresistorvalue float?

Keine Ahnung, das hat der ursprüngliche Autor so geschrieben. Es funktioniert ja auch alles, nur für meinen Zweck wäre zumindest eine Stelle mehr hinter dem Komma besser.
Es irritiert dann allerdings, wenn da nun 1,1234mA steht, besser wären eben 1123,4µA.
Eigentlich ein simpler Wunsch nur die Umsetzung übersteigt mein Wissen zu "Arduino-Sprech"
Dabei hätte ich allerdings statt µA "uA" geschrieben, das "µ" zu erzeugen war mir zu kompliziert.

Doc_Arduino:
Kann man ändern in, der Einfachheit alles 32bit unsigned,

const unsigned long currentValue = 7; 

const unsigned long shuntresistorvalue = 1490;          // Ohm
const unsigned long voltagereferancevalue = 4988; // mV statt V



Wenn du bei letzteren mit mV stat V rechnest hast du automtisch eine höhere Genauigkeit in der Rechnung. Vielleicht funktioniert auch µV statt mV. Dann hättest du mit µV durch Ohm schon µA.

Ok, das geh ich mal an. Bin mal gespannt... :wink:

Doc_Arduino:
Abgesehen davon würde ich immer soweit wie möglich/sinnvoll mit Ganzzahlen rechnen. Je nachdem was hier für ein Maximalwert zu erwarten ist kann man vor der Division nochmal mit Faktor 1000 erhöhen. Wertebereich von 32bit beachten. Ob man hier schon durch 1023.0 teilt muss man sich überlegen oder ausprobieren.

unsigned long shuntvoltage = currentValue * voltagereferancevalue;

Mindestens muss die Klammer weg von

float shuntvoltage = currentValue * (voltagereferancevalue / 1023.0);

Ansonsten verlierst du schon Rechnengenauigkeit bevor es überhaupt losgeht.

Nimm dir die Formeln raus, bau dir einen Testcode und optimiere die Rechenwege.
Möglichst mit großen Ganzzahlen hantieren um bei Ganzzahl Divisionen die Verluste in Grenzen zu halten. Fließkomma erst wenn es nicht anders geht. Das 32Bit float ist darin sehr begrenzt.

Ich werde das so machen, wie Du schreibst. Dabei auch gleich den ganzen überflüssigen Code rauswerfen, ich brauche weder den seriellen Monitor, noch die Ausgabe für ein serielles LCD.
Hoffentlich werfe ich nicht zuviel raus :wink:

Erstmal herzlichen Dank, ich melde dann Vollzug und Ergebnis...

Old-Papa

Hallo Doc-Arduino,

ich habe den Code zunächst mal von einigem Ballast befreit, danach hat es zumindest wie bisher funktioniert.
Dann habe ich die Zeilen so geändert, wie Du das vorgeschlagen hast, dass bringt allerdings Blödsinn auf das Display. :frowning:
Anbei dieser Code...

Wenn ich die Referensspannung als:

const unsigned long voltagereferancevalue = 4988;

eingebe, dann erhalte ich eine etwa 100fach höhere Messpannung. (soll 446V)
Vor dem Wert für den Strom steht ein ulkiges "TE"

Gebe ich den Wert der Referenzspannung wieder in Volt ein (also 4.988) stimmt zumindest die Größenordnung wieder, doch die Spannung wird völlig falsch ausgegeben (statt 446V nun 358V).

In beiden Fällen wird auch ein viel zu niedriger Wert für den Strom ausgegeben, statt ca. 13µA nur ca. 5,6µA (ja, derzeit habe ich vier Nachkommastellen)

// I2C display
i2clcd.setCursor(0, 0);
i2clcd.print(voltageDUT, 1);
i2clcd.print("V ");
i2clcd.setCursor(8, 0);
i2clcd.print(current, 4); //vier Nachkommastellen
i2clcd.print("mA");
i2clcd.setCursor(0, 1);
i2clcd.print("Supply: ");
i2clcd.print(voltage, 1);
i2clcd.print("V ");

Old-Papa

PS: Das mit dem "TE" ist mein Fehler, ich hatte das Dispay nicht gelöscht, das sind Reste des ----TEST---- Schriftzuges.

Leakage_Tester_V1.2-Test_a_.ino (9.17 KB)

So, ich bin halbwegs auf der Zielgeraden.

Jetzt klappt das auch mit den Konstanten, warum das vorhin Blödsinn erzeugte, keine Ahnung....

const unsigned long shuntresistorvalue = 1490;       // Ohm ...
const unsigned voltagereferancevalue = 4988.4;  // (mV) voltage reference value, ....

Damit die immer zuwenig angezeigten ca. 5-6µA addiert werden, dabei aber bei Anzeige von 0,0000mA eben nicht, habe ich eine if-else mit einem empirisch ermittelten Korrekturwert gebastelt:

// current divider ratio correction MAY NOT NEED THIS
if (shuntvoltage > 0 ){
shuntvoltage = shuntvoltage + 8.9; // Versuch eines Korrekturwertes, empirisch ermittelt.
} else {
  shuntvoltage = shuntvoltage + 0.0;
}

Damit die Spannungen richtig angezeigt werden, habe ich diese noch durch 1000 geteilt und den 1000er Teiler für den Strom rausgenommen:

voltageDUT = voltageDUT / 1000;

voltage = voltage / 1000;

// convert to mA reading
// current = current * 1000;

Und dann noch als Krönung auf 5 Kommastellen erweitert:

// I2C display
i2clcd.setCursor(0, 0);
i2clcd.print(voltageDUT, 1);
i2clcd.print("V ");
i2clcd.setCursor(7, 0);
i2clcd.print(current, 5); // Fünf Kommastellen
i2clcd.print("mA");
i2clcd.setCursor(0, 1);
i2clcd.print("Supply: ");
i2clcd.print(voltage, 1);
i2clcd.print("V ");

Verglichen mit einem guten (kalibrierten/justierten) Fluke-DMM ergibt sich noch eine ganz kleine Unlinearität von etwa 4µA über den ganzen Anzeigebereich (0,00000 bis etwa 10,5000mA). Die Referenzspannung ist natürlich nicht so dolle stabil, da direkt aus dem 7805....
Egal, mir werden jetzt selbst 0,01µA als Leckstrom signalisiert, dabei ist es eigentlich auch egal ob 0,01 oder 0,03µA. Wichtig ist beim Leckstromtest von HV Kondensatoren vor allem, ob sie fast absolut Leckstromfrei sind (ja, das geht).

Einzig die Misslichkeit, dass noch immer in mA angezeigt wird stört. Beim Wechsel von 9,99999 auf 10,0001mA springt das Komma ja auch an die richtige Stelle. Warum? Da bin ich noch völlig Ahnungslos.

Old-Papa

Die Bilder zeigen einen 500nF/160V Folien-C, der bei 160V noch völlig leckfrei ist.
Dann noch einen 4700pF/400V der selbst bei 160V schon erheblich leckt, bei knapp 400V noch mehr. Der ist Schrott, dient mir nur zum darstellen solcher Messwerte :wink:

Die rote Warn-LED hat allerdings ins Bild geblitzt....