Hallo zusammen
Ich bin grade dabei mir ein Doppelnetzteil zu basteln. 2 x 0-15,5 V , 2
x 1,5 A.
Die Strom u. Spannungsanzeige wollte ich mit einem ATtiny 26
realisieren.
4 Differenzialeingänge, Ausgabe über 2x16 LCD-Anzeige
Bis jetzt hab ich nur die Software für die Spannungsanzeige geschrieben.
Soweit funktioniert auch alles. Nur mit der Genauigkeit bin ich etwas
unzufrieden.
Hier mal eine Messreihe. Die Eingangsspannung hab ich mit 5
verschiedenen Multimetern gemessen.
Die Abweichung zwischen den Multimetern lag bei max. 0,03V
Multim. ADC Multiplikation Ausgabe
(x1563) (gerundet)
0,00 V 0000 00000000 0,0 V
1,00 V 0059 00092217 0,9 V
2,00 V 0121 00189123 1,9 V
3,00 V 0183 00286029 2,9 V
4,00 V 0246 00384498 3,8 V
5,00 V 0309 00482967 4,8 V
6,00 V 0372 00581436 5,8 V
7,00 V 0436 00681468 6,8 V
8,00 V 0500 00781500 7,8 V
9,00 V 0566 00884658 8,8 V
10,00 V 0631 00986253 9,9 V
11,00 V 0694 01084722 10,8 V
12,00 V 0760 01187880 11,9 V
13,00 V 0827 01292601 12,9 V
14,00 V 0893 01395759 14,0 V
15,00 V 0962 01503606 15,0 V
Wenn ich jetzt mal die 6V messung betrachte liegt der Fehler bei 0,2 V.
Das ist ein Messfehler von mehr als 3%, was mir etwas
viel erscheint. Auch die Linearität überzeugt mich nicht unbedingt. Wenn
die Eingangsspannung kleiner wird, wird der Messfehler auch wieder
kleiner.
Ist das normal für die ADC's im ATtiny26 ?
Das lässt sich wohl ohne weitere Angaben zu deiner Schaltung nicht so
ganz beantworten. Benutzt du eine externe Referenz (wenn ja welche?)
oder "nur" die interne? Wie stabil ist die Versorungsspannung? Welchen
Gain verwendest du?
Die "ADC Characteristics" finden sich im Datenblatt ab Seite 129. Da
kannst du ja recht schnell durchrechnen, ob deine Ergebnisse "typisch"
sind. Ansonsten ist wohl von falschen Umgebungsparametern auszugehen.
Na ja
Die Schaltung ist simpel. Die Ausgangsspannung vom Netzgerät wird über
einen Spannungsteiler mit Spindeltrimmer auf die Differenzeingänge
gelegt.
Gain = 1 . Als Referenzspannung hab ich die interne 2,56V genutzt ohne
den Ko an Vref. Mit Ko hatte ich immer von vorherein einen ADC-Wert von
0006 bei 0V Eingangsspannung. Die interne 2,56V Referenz passt aber auch
nicht genau. Den max. ADC-Wert von 1023 erreiche ich erst bei einer
Eingangsspannung von 2,96V am Differenzeingang. Das sollte dann wohl
auch der Referenzspg. entsprechen
Die Stromversorgung für den ATtiny und das LC-Display wird getrennt über
2 LM317 realisiert und ist galvanisch von den Netzgerätspannungen
getrennt.
Der ADC-Wert ist der Mittelwert aus 256 Messungen. (Hab ich hier aus dem
AVR-Tutorial. Abschnitt ADC)
Hi
>Die Schaltung ist simpel. Die Ausgangsspannung vom Netzgerät wird über>einen Spannungsteiler mit Spindeltrimmer auf die Differenzeingänge>gelegt.
Da sind trotzdem noch Fragen offen:
Welchen Wert hat dein Spindeltrimmer?
Wie hoch ist der ADC-Takt?
MfG Spess
Hans Imglück schrieb:> Die Schaltung ist simpel. Die Ausgangsspannung vom Netzgerät wird über> einen Spannungsteiler mit Spindeltrimmer auf die Differenzeingänge> gelegt.
HIer stellt sich die Frage, wo hochohmiger der Spa.-Teiler ist. Hast du
einen Kondensator an den Eingängen? Ich habe für solche langsamen Sachen
immernoch einen Kondensator so 10 - 100nF am Eingang, da der ADC etwas
Strom zieht bei der Messung.
Ingo
Hans Imglück schrieb:> Na ja> Die Schaltung ist simpel. Die Ausgangsspannung vom Netzgerät wird über> einen Spannungsteiler mit Spindeltrimmer auf die Differenzeingänge> gelegt.
Und da du offensichtlich nichts genaueres sagst, gehst du also schon
davon aus, dass der Fehler dort nicht sein kann? ...
Ingo schrieb:> Ich habe für solche langsamen Sachen> immernoch einen Kondensator so 10 - 100nF am Eingang, da der ADC etwas> Strom zieht bei der Messung.
Das ist wichtig: Der Sample&Hold Eingang des ADC lädt am Anfang der
Messung den Eingang des ADC um auf einen kleinen internen Kondensator.
Wenn die Quelle des Eingangs diesen Strom nicht liefern kann, gbt es
Fehlmessungen, die auch von der Höhe der zu messenden Spannung abhängen.
Nicht umsonst schreibt Atmel, das die Quellimpedanz nicht grösser als
(wenn ich recht erinnere) 10k sein soll.
Weiterhin ist es wichtig, AVcc sauber zu halten. Das geht gut mit einer
extra Drossel und ein-zwei Abblockkondensatoren direkt am MC. Sonst
fängt sich der ADC die Umschaltspitzen des restlichen MC ein und die
Messung kann 'springen'.
Oh je
Die Verwendung der ADCs scheint ja doch komplizierter zu sein als zuerst
angenommen.
Da ich nur Assembler programmieren kann sind C-Programme für mich
Böhmische Dörfer.
Das kann ich nicht nachvollziehen.
Zu den noch offenen Fragen :
Der Controller arbeitet mit seinem internen RC-Oszillator (1 MHz).
Der ADC-Takt ist 125 KHz. (Hab auch andere ausprobiert. Ergab aber keine
Änderung)
Der Eingangsspannungsteiler hatte ursprünglich 47K. Im Moment hab ich
testweise nur noch einen 1K Spindeltrimmer dran.
An den Messwerten hat sich dadurch aber nichts geändert. Auch den Ko von
100nF hatte ich ursprünglich vorgesehen.
Hab ich aber testweise wieder abgemacht. Ergab aber auch keine Änderung.
Der Pufferkondensator 100nF an Vcc ist natürlich dran.
Auch der AVcc Pin ist Drossel und Ko genauso beschaltet wie im
Datenblatt angegeben.
Bei der Aufnahme der Messreihe hab ich tatsächlich mit viel
Fingerspitzengefühl die Eingangsspannung exact auf 2 Nullen hinterm
Komma eingestellt.
Nach dem aufaddieren der 256 Messwerte und anschliessenden Teilung durch
256 wurde vorher noch gerundet. Ich habs testweise aber auch ohne runden
versucht. Auch ohne Erfolg
Nach der Umrechnung in Dezimal hab ich die letzten Stellen ignoriert und
nur die 2te Stelle hinterm Komma zum Runden verwendet.
Ich gehe mal davon aus , das es nicht an der Hardware ausserhalb des MC
liegt. Die Ungenauigkeit, insbesondere die fehlende Linearität lässt
sich wohl doch nur Softwaremäßig wegrechnen.
Ich werds aber trotzdem erst nochmal mit einer Externen Referenzspannung
versuchen.
Wenn das keine Besserung bring bleibt mir wohl nicht anderes übrig als
mich mit einem Englisch Wörterbuch zu bewaffnen um die Appnote AVR120 zu
decodieren :)
Vieleicht kommt dann der Aha-Effekt.
Hans Imglück schrieb:> Oh je> Die Verwendung der ADCs scheint ja doch komplizierter zu sein als zuerst> angenommen.
Eigentlich nicht.
Aber du gibst Information immer nur in kleinen Dosen raus. Und das
bedeutet auf unserer Seite, dass man raten und die Dinge rauskramen
muss, die am häufigsten passieren.
Würdest du Schaltplan und Programm zeigen, sieht die Sache gleich ganz
anders aus.
> Da ich nur Assembler programmieren kann sind C-Programme für mich> Böhmische Dörfer.> Das kann ich nicht nachvollziehen.
Du kannst
Volt = Adc_Wert * 5.0 / 1024;
nicht nachvollziehen?
Links vom = steht die Variable (von mir aus in Assembler-Terminologie
'das Register'), rechts wie sich der Wert berechnet.
Im Vergleich dazu ist doch Assembler regelrecht kryptisch, wenn du dich
um jeden Berechnungsscheiss selber kümmern musst. Gerade Applikationen,
bei denen es um Rechnen geht (also nicht einfach nur: wenn taster dann
led ein) würde ich niemals in Assembler schreiben. Viel zu viel Aufwand
nur um die Mathe hinzukriegen und nur ja nicht 2 Register
durcheinanderzuwerfen oder das Carry Flag zu übersehen.
Und ob du jetzt
TIMSK = (1<<TOVF0);
schreibst, oder
LDI r16, (1<<TOVF0);
OUT TIMSK, TOVF0
schenkt sich nun wirklich nichts. Der Wert von (1<<TOVF0) landet im
Register TIMSK. Nur dass ich mir in der C Version keine Gedanken drüber
machen muss, ob ich mir was zerstöre, wenn ich zwischendurch das R16
verändere. Wieder das gleiche Spiel: links vom = steht das Ziel (das
Register TIMSK) und rechts vom = steht, welcher Wert dorthin bugsiert
werden muss.
Aber: jeder wie er mag.
> An den Messwerten hat sich dadurch aber nichts geändert.
Was lässt du dir ausgeben?
Den rohen ADC WErt oder den bereits umgerechneten?
Lass dir mal die rohen ADC WErte auch ausgeben und spiel mit denen ein
wenig im Taschenrechner, damit du auch die Stellen siehst bzw.
vergleichen kannst, du du in dem Programm weggerundet hast.
Und PS:
die Referenzspannung ist alles mögliche. Hauptsächlich ist sie stabil.
Aber sie hat ganz sicher nicht 2.56V
Aber: Der µC gibt dir die tatsächliche Referenzspannung ja auf den ARef
Pin raus. Da kannst du mit deinen genauen Voltmetern ja nachmessen, wie
hoch sie wirklich ist.
Ansonsten: Beschreib nicht was du gemacht hast - zeigs einfach her.
Schaltplan + Programm
Mir ist schleierhaft warum du so genau sein willst, aber die interne
Referenzgurke nutzt. Das interne Ref sollte man nur zum schätzen nehmen,
wie du ja auch schon festgestellt hast...
In meinem Datenblat steht:
"Note1: The device requires a supply voltage of 3V in order to generate
2.56 reference voltage."
Ob sie bei 5V vcc dann nur höher, oder auch instabil ist, kann ich nicht
sagen.
> Mir ist schleierhaft warum du so genau sein willst, aber die interne> Referenzgurke nutzt.
Die interne Referenz ist 1000 mal besser als die externe
Versorgungsspannug als Referenz zu verwenden, denn sie schwankt nicht so
sehr mit Temperatur, Alterung und eben Versorgung.
Daß die ABSOLUTE Genauigkeit nicht so besonders ist, ist ja durch
Kalibrierung in den Griff zu bekommen, aber ABSOLUT auf 10 bit (0.1%)
genaue (extern) Referenzspanungsquellen sind den meisten sowieso zu
teuer.
Oh Mann , da hab ich ja wieder was angerichtet.
Es ist das erste mal, das ich mit einem ADC herumexperimentiere.
War vllt etwas naiv anzunehmen, das es reicht die Eingangsspannung auf
max. Vref runterzuteilen, den ADC-Wert mit einem festen Faktor zu
multiplizieren , zu runden und auszugeben.(Wär ja auch zu schön gewesen
:))
Ingo
Bei einer Abweichung von 3% ist das für mich kein Messgerät mehr,
sondern eher ein Schätzeisen
Und der Begriff "Referenzspannung" suggeriert mir eben eine gewisse
Genauigkeit und Stabilität.
Konnte ja nicht ahnen , das es nur ein Pi mal Daumen Werbeversprechen
ist.
Aber jetzt weiss ich es besser.
Karl Heinz
Ich werde meine Schmierzettel mal in eine digitale Form bringen und hier
nochmal posten.
Dachte eigendlich ich kann mir das sparen, weil ein Spannungsteiler am
ADC-Eingang ja nicht so wahnsinnig kompliziert ist.
Aber OK. Wenn die anderen Schaltungsteile u.U. für den Fehler
verantwortlich sein können ist es wohl doch sinnvoll mal
das ganze zu betrachten.
Ob meine "genauen Voltmeter" wirklich so genau sind möchte ich garnicht
behaupten.
Zumindest sind sie alle recht gleichmäßig ungenau.
Es war mir einfach wichtig, die Eingangsspannung mal mit anderen
Messgeräten nachzumessen. Denn wenn die Spannung am Eingang schon nicht
stimmt, brauch ich mich über die ungenauen ADC-Werte nicht wundern.
Ich konnte mich beim lesen deines letzten Beitrags nicht des Eindrucks
erwehren , das du kein grosser Assembler-Fan bist.
Ich bin leider kein Profi-Programmierer und hab nie C gelernt. Mir ist
ein gut kommentiertes Assemblerprogramm lieber.
So Ausdrücke in C wie z.B.:
Volt = Adc_Wert * 5.0 / 1024;
sind auch nicht das Problem.
Aber folgendes (Auszug aus "ADC und Fixed-Point Arithmetik") :
#define FacScale 1600000000UL ;Was soll dieses UL bedeuten
for (AvgCount = 0; AvgCount < 128; AvgCount ++) { ;AvgCount ++ ?????
ADCSR |= (1 << ADSC); ;was soll der senkrechte Strich vor dem =
void FactorOffsetCalHigh (void) ;Void heisst laut Wörterbuch "Leer
oder Ungültig"
;kann dann wohl nicht so wichtig sein :)
for (;;) { ;Netter Smiley. Der Programmierer hatte wohl
grad gute Laune
Also , wenn man so wie ich mit der Syntax nicht vertraut ist finde ich C
kryptischer als Assembler.
Und wie oben schon erwähnt war ich naiv genug zu glauben, das sich die
ganze rechnerei auf das multiplizieren des ADC-Wertes mit einem festen
Faktor beschränkt. Und das ist selbst in Assembler kein Hexenwerk.
MfG Hans
> das sich die ganze rechnerei auf das multiplizieren> des ADC-Wertes mit einem festen Faktor beschränkt.
Tut es.
Wenn du das Datenblatt lesen würdest könntest du das auch
erreichen. Die Daten des ADC sind zwar für den optimalen
Fall angegeben, aber nicht so schlecht:
Single Ended Conversion
VREF = 4V, VCC = 4V
ADC clock = 200 kHz
1 LSB
Integral Non-Linearity (INL)
Single Ended Conversion
VREF = 4V, VCC = 4V
ADC clock = 200 kHz
0.5 LSB
Differential Non-Linearity (DNL)
Single Ended Conversion
VREF = 4V, VCC = 4V
ADC clock = 200 kHz
0.5 LSB
Gain Error
Single Ended Conversion
VREF = 4V, VCC = 4V
ADC clock = 200 kHz
0.75 LSB
Offset error
Single Ended Conversion
VREF = 4V, VCC = 4V
ADC clock = 200 kHz
0.5 LSB
Also in der Summe ist der Wert immer besser als 0.3% genau, und sogar
der Nullpunkt stimmt auf +/-1.
Bloss musst du es ja unbedingt den differential mode mit
Gain von 1 machen, und er OpAmp im uC ist schon deutlich
schlechter:
Gain = 1x 10 Bits
Absolute Accuracy
Gain = 1x
VREF = 4V, VCC = 5V
ADC clock = 50 - 200 kHz
24 LSB
Integral Non-Linearity (INL)
(Accuracy after Calibration for Offset and
Gain Error)
VREF = 4V, VCC = 5V
ADC clock = 50 - 200 kHz
1.5 LSB
Gain Error
Gain = 1x 2 %
Offset Error
Gain = 1x
VREF = 4V, VCC = 5V
ADC clock = 50 - 200 kHz
4 LSB
Da ist man froh, wenn es auf +/-30 (3%) genau wird.
> Und das ist selbst in Assembler kein Hexenwerk.
Mit einer Dezimalzahl mit Nachkommastellen ?
Na ja, schon länger.
>> Und der Begriff "Referenzspannung" suggeriert mir eben eine gewisse>> Genauigkeit und Stabilität.
Man muß hier sagen das die Referenz sehr wohl sehr stabil ist und das
reicht dann auch schon. Ob diese genau 2.56 Volt hat oder eben 2.7V ist
nicht garantiert. Kompensiert man diese dann ist die Welt schon in
Ordnung.
Ich wußte nicht das du kein C lesen kannst aber das verlinkte Beispiel
berechnet die Korrektur über DeltaU / DeltaADC also eine simple
Gleichung.
Dann wird der Faktor und OFFSET, Nullpunkt berechnet und das kann man
auch in Assembler machen.
Es ist immer wieder das gleiche Verfahren, du pickst dir 2 Punkte heraus
bei denen du die gemessene Spannung und den ADC Wert erfasst. Damit hast
du 2 Wertepaare für die Berechnung von Steigung und OFFSET und kannst
den Fehler herausrechnen. Im Grunde willst du ja nur einen bekannten
Eingangswert einen Ausgangswert zuweisen.
So, doch noch nen bischen C...
1
// ADC Werte für die Referenzpunkte
2
#define AdcRawHigh 3194 // Stützpunkt 2.00 Volt
3
#define AdcRawLow 626 // Stützpunkt 0.40 Volt
4
#define DeltaRaw (AdcRawHigh - AdcRawLow)
5
6
// ADC Skalierung für die Ausgabe
7
#define OutValHigh 20000.0 // Ausgabewert für AdcRawHigh
8
#define OutValLow 4000.0 // Ausgabewert für AdcRawLow
9
#define DeltaOut (OutValHigh - OutValLow)
10
11
// Berechnung der ADC Korrekturwerte mittels Referenzpunkte
Im Beispiel wird eine Spannung von 0.40 sowie 2.00 Volt vorgegeben und
dann definiert was ich denn gerne auf der Anzeige sehen möchte, 4000
sowie 20000. Dann setzt man sich das Komma bei der Ausgabe dorthin wo es
hin soll also 2.000 V, 0.400 Volt.
Hans Imglück schrieb:> Dachte eigendlich ich kann mir das sparen, weil ein Spannungsteiler am> ADC-Eingang ja nicht so wahnsinnig kompliziert ist.> Aber OK. Wenn die anderen Schaltungsteile u.U. für den Fehler> verantwortlich sein können ist es wohl doch sinnvoll mal> das ganze zu betrachten.
Ein Foto wäre auch nicht schlecht. Denn die Verdrahtung kann auch noch
Fehler produzieren, z.B. durch Spannungsabfälle am GND.
Die 0V der zu messenden Spannung sollte daher direkt an den GND-Pin
gehen, der zu AVCC gehört - also nicht irgendwo an irgendeinen
GND-Anschluss, z.B. an 0V des Netzgerätes.
Gruß Dietrich
Hans Imglück schrieb:> Karl Heinz> Ich werde meine Schmierzettel mal in eine digitale Form bringen und hier> nochmal posten.> Dachte eigendlich ich kann mir das sparen, weil ein Spannungsteiler am> ADC-Eingang ja nicht so wahnsinnig kompliziert ist.> Aber OK. Wenn die anderen Schaltungsteile u.U. für den Fehler> verantwortlich sein können ist es wohl doch sinnvoll mal> das ganze zu betrachten.
Ja.
zb interessiert ganz enorm, was du mit AVcc bzw. ARef gemacht hast.
> Ich konnte mich beim lesen deines letzten Beitrags nicht des Eindrucks> erwehren , das du kein grosser Assembler-Fan bist.
:-)
von mir stammen ca 40% des Assembler Tutorials
> Ich bin leider kein Profi-Programmierer und hab nie C gelernt. Mir ist> ein gut kommentiertes Assemblerprogramm lieber.>> So Ausdrücke in C wie z.B.:> Volt = Adc_Wert * 5.0 / 1024;> sind auch nicht das Problem.>> Aber folgendes (Auszug aus "ADC und Fixed-Point Arithmetik") :>
Siehst du, jetzt machst du einfach dicht.
Du hast nämlich einen großen Vorteil! Du weißt zu einem Gutteil, was
eigentlich passieren müsste.
> #define FacScale 1600000000UL ;Was soll dieses UL bedeuten
Das UL ist für deine Zwecke uninteressant. Behalte einfach im
Hinterkopf, dass es da eine Zahl gibt, nämlich 1600 Millionen, und gut
ists fürs erste.
> for (AvgCount = 0; AvgCount < 128; AvgCount ++) { ;AvgCount ++ ?????
for( intialisierung; laufbedingung; Aktion nach jedem
Schleifendurchlauf.
den ++ kenst du in Assembler als Inkrement. Also einfach 1 dazuzählen
> ADCSR |= (1 << ADSC); ;was soll der senkrechte Strich vor dem =
Das ist ein Oder
Für dich als Assemblerprogrammierer bedeutet diese Anweisung einfach
nur:
im Register ADCSR das Bit ADSC auf 1 setzen.
Und da du dich mit dem ADC auskennst, weißt du auch, dass damit der ADC
gestartet wird. Jetzt arbeitet er
xyz |= ( 1 << bit ) setzt das Bit 'bit' in xyz auf 1
xyz kann irgendein Register sein
xyz &= ~( 1 << bit ) löscht das Bit 'bit' in xyz (setzt es auf
0)
| ist in C das binäre Oder
& ist in C das binäre Und
In C hat man den Vorteil, dass man sich nicht darum kümmern muss, was
xyz genau ist. Als Assemblerprogrammierer kennst du die Befehle SBI und
CBI. Genau auf die läuft es hinaus.
Kannst du wegen der Adresslage SBI bzw. CBI nicht benutzen, dann musst
du in Assembler genau was machen? Du machst
LDS r16, TIMSK2
OR R16, ( 1 << bit )
STS TIMSK2, R16
um ein Bit zu setzen. Also um Grunde wieder genau die gleiche Operation.
> void FactorOffsetCalHigh (void) ;Void heisst laut Wörterbuch "Leer> oder Ungültig"> ;kann dann wohl nicht so wichtig sein :)
ist es auch nicht.
Es besagt einfach nur, dass dieses Unterprogramm keinen Wert liefert.
> for (;;) { ;Netter Smiley. Der Programmierer hatte wohl> grad gute Laune
Hat nichts mit smiley zu tun
for( intialisierung ;
Laufbedingung ;
Aktion am Ende eines Schleifendurchlaufs )
da stehen 3 Teile, die durch ; voneinander getrennt sind. Du würdest die
3 Teile ungefähr so in Assembler wiederfinden
1
initialisierung
2
3
label:
4
5
werte die Laufbedingung aus.
6
BREQ Ende_Schleife
7
8
9
.... hier kommt der Schleifenkörper
10
11
12
Aktion am Ende eines Schleifendurchlaufs
13
14
RJMP label
15
16
Ende_Schleife:
Im for werden also diese 3 Dinge angegeben. Die ; sind obligat, aber man
kann jeden der 3 Teile, einzeln oder in Kombination auch einfach
weglassen, wenn man da nichts hat.
> Also , wenn man so wie ich mit der Syntax nicht vertraut ist finde ich C> kryptischer als Assembler.
Du musst es nur lesen können.
Das meiste erschliesst sich für dich ziemlich problemlos, um zu
verstehen was du im Assembler zu tun hast.
Du weißt das im Code zb an dieser Stelle das ADSC Bit im Register ADSRC
zu setzen ist, damit der ADC loslegt.
Wenn man davon ausgeht, dass der C-Code erst mal keine Fehler enthält,
was wird daher
ADCSR |= ( 1 << ADSC );
machen?
> Und wie oben schon erwähnt war ich naiv genug zu glauben, das sich die> ganze rechnerei auf das multiplizieren des ADC-Wertes mit einem festen> Faktor beschränkt. Und das ist selbst in Assembler kein Hexenwerk.
Wenn Kommazahlen im Spiel sind, sieht die Sache aber anders aus. Aber so
wie es aussieht, hast du Fixpoint-Arithmetik im Griff und (das meine ich
ERNST), dazu beglückwünsche ich dich. Das ist gut!
Nichts desto trotz kann man auch da leicht Fehler machen. Denn was ich
in C lapidar in 2 Zeilen an Berechnungen hinschreibe, zieht sich im
Assembler über viele Zeilen hin.
Daher: Code zeigen!
Hans Imglück schrieb:> Da ich nur Assembler programmieren kann sind C-Programme für mich> Böhmische Dörfer.
Das ist aber schlecht. Auch als überzeugter Assemblerprogrammierer
sollte man natürlich C zumindest einigermaßen problemlos lesen können.
C ist doch schließlich im Kern nicht mehr als ein syntaktisch furchtbar
aufgeblähter Makroassembler.
> Nach dem aufaddieren der 256 Messwerte und anschliessenden Teilung durch> 256 wurde vorher noch gerundet.
Was willst du da "vorher" runden? Runden macht doch nur beim Dividieren
irgendeinen Sinn. Und Dividieren mit Runden bei einem Divisor von 256
besteht schlicht und einfach darin, 128 zum Wert zu addieren und dann
das Ergebnis ab dem zweitniedrigsten Byte als Quotient zu benutzen.
Das wissen sogar viele C-Programmierer.
> Ich habs testweise aber auch ohne runden> versucht. Auch ohne Erfolg> Nach der Umrechnung in Dezimal hab ich die letzten Stellen ignoriert und> nur die 2te Stelle hinterm Komma zum Runden verwendet.
Komma? Willst du uns verarschen? In der ganzen Aufgabe kommt nicht ein
Komma vor. Die AD-Wandler liefern natürlich Integers. Auch die
Mittelwertbildung liefert einen Integer. Und auch die Skalierung für die
Anzeige liefert einen Integer. Und auch die Wandlung in's Dezimalsystem
liefert nur eine Reihe kleine Integers. Das einzige verfickte Komma in
der ganzen Aufgabe ist eventuell ein festverdrahtete Kommasymbol in der
Anzeige!
Und sowas will Assemblerprogrammierer sein. Da lachen ja die Hühner.
Hallo
An bko
Ich schrieb ja oben :
"Wenn ich jetzt mal die 6V messung betrachte liegt der Fehler bei 0,2 V.
Das ist ein Messfehler von mehr als 3%."
Wenn ich jetzt mal 6V als 100% ansehe ist 1% = 0,06V. Eine Abweichung
von 0,2 V wären dann eben 3,3... %
Das bezog sich als Beispiel eben nur auf die eine Messung, nicht auf die
ganze Tabelle.
An C-Hater
Es ist nunmal leider so das mir einige C-Syntax-Konstrukte Rätsel
aufgeben. Ich bin da auch nicht stolz drauf.
Die Routine zum Auslesen der ADC-Werte hab ich hier aus dem
"AVR-Tutorial. Abschnitt ADC" abgekupfert.
Da war diese Rundung nunmal mit drin. Streite dich also mit dem Autor
des Tutorials, nicht mit mir !
Bei der Sache mit dem Komma hab ich mich wohl etwas ungeschickt
ausgedrückt. Ich rechne natürlich nicht mit Kommazahlen.
Da dieses Komma aber bei der Ausgabe immer an der gleichen Stelle
eingefügt wird, hab ich mich einfach darauf bezogen.
Ich hab auch irgendwo erwähnt das ich kein Profi - Programmierer bin,
sondern nur ein ganz kleiner Hobbybastler.
Also sei bitte etwas nachsichtiger.
Im übrigen finde ich deine agressive Ausdrucksweise etwas neben der
Spur. Und da du ja auch nix produktives beitragen kannst
und nur verbal mit Dreck um dich wirfst, halte dich bitte in Zukunft
einfach hier raus !
MfG Hans
Hans Imglück schrieb:> Die Routine zum Auslesen der ADC-Werte hab ich hier aus dem> "AVR-Tutorial. Abschnitt ADC" abgekupfert.
Du vermeidest allerdings auffallend, uns endlich mal deine Schaltung zu
zeigen. Solange du die Hardware nicht gemäss den Vorgaben des
Datenblattes verschaltest, ist jede Diskussion über die Genauigkeit des
ADC nicht sinnvoll. Meine Erfahrung zeigt, das der ATTiny26 durchaus
gute Werte liefert, nur muss eben die Aufbereitung von AVcc, AGND und
ARef entsprechend sauber sein.
bko schrieb:> Eine kleine Zwischenfrage aus der Digitalecke an die Analogabteilung:> Wie berechnet sich eigentlich hieraus 3% Fehler? 0,00 V 0000 00000000
0,0 V
> 1,00 V 0059 00092217 0,9 V
Bei 0,9V / 1V sind es ja schon 8,2% ( genauen Werte genommen ).
Hans Imglück schrieb:> Wenn ich jetzt mal 6V als 100% ansehe ist 1% = 0,06V. Eine Abweichung> von 0,2 V wären dann eben 3,3... %
und wenn du jetzt Mal 1V als 100% ansiehst ist 1% 0,01V, eine Abweichung
von 0,1V wären dann eben 10% ???
Wenn Du mit deinem Multimeter 1V im 1000V Bereich misst kommt ja auch
nichts genaues raus.
und außerdem ignorierst Du scheinbar den Post von Mawin zur Genauigkeit
der Differentialeingänge
Hallo nochmal
Ich hab jetzt mal die Schaltung und das Programm zum runterladen auf
meine HP gestellt.
Da ich das Programm mit Textpad geschrieben habe passten die Tabulatoren
nicht vernünftig wenn man sich das mit Notepad anguckt. Ich habs extra
für Notpad nochmal richtig formatiert. Daher gibts das Listing 2 mal.
Im Schaltplan hab nur die Beschaltung für einen Zweig meines
Doppelnetzteils gezeichnet. Der andere Zweig wäre ja identisch.
http://home.arcor.de/sinussabaeus/Netzteilanzeige.JPGhttp://home.arcor.de/sinussabaeus/UI-Messung_Notepad.asmhttp://home.arcor.de/sinussabaeus/UI-Messung_Textpad.asm
An Matthias Sch.
Ich kann im Datenblatt überhaupt nichts von AGnd finden . Wenn ich
direkt am IC nachmesse sind die GND-Pins auch intern miteinander
verbunden.
An Ingo und Walter S.
Ihr habt ja recht mit den 10% Abweichung. Ich hab einfach nur aus der
mitte der Tabelle mal einen Wert rausgepickt.
Und den Beitrag von MaWin hab ich nicht ignoriert , sondern nur erstmal
kommentarlos hingenommen. Das muss ich mir in einer ruhigen Minute
nochmal genauer angucken.
Hans Imglück schrieb:> An Matthias Sch.> Ich kann im Datenblatt überhaupt nichts von AGnd finden . Wenn ich> direkt am IC nachmesse sind die GND-Pins auch intern miteinander> verbunden.
Ja, du hast recht, der Tiny26 hat keinen gesonderten AGND Anschluss.
Trotz interner Verbindungen musst du allerdings unbedingt beide GND
Anschlüsse mit Masse verbinden, ich hoffe die fehlende Verbindung im
Schaltplan ist nur ein Lapsus.
10uH sind übrigens wirklich wenig als Drossel für AVcc. Nimm da
100-470uH. Ein 10uf-47uF Elko parallel zum 100n kann auch nicht schaden.
Hans Imglück schrieb:> Ihr habt ja recht mit den 10% Abweichung.
nein, da hast du mich komplett falsch verstanden. Ich dir damit zeigen
das man zur Berechnung der Genauigkeit nicht irgendeinen Wert als Basis
nimmt, sondern dass bei Messgeräten die Genauigkeit auf den
Skalenendwert bezogen wird
Hallo
An Walter S.
Scalenendwert . Ja, hab ich vor ewig langer Zeit auch mal gelernt.
Problem war nur, das ich die Anzeige eben auf diesen Endwert justiert
habe.
Damit fiel er für die Fehlerberechnung natürlich aus.
An Matthias Sch.
Mit den Bauteilwerten hab ich mich strickt an die Angaben im Datenblatt
gehalten und ja, die beiden Massepins sind unter der Fassung miteinander
verbunden
Da sich ansonsten noch niemand über mein "tolles" Assemblerprogramm
ausgelassen hat, gehe ich mal davon aus, daß entweder ausser mir keiner
durchblickt oder noch keiner einen Fehler entdeckt hat.
Die Beiträge von Mawin und Bernd N. werd ich mir nochmal auf der Zunge
zergehen lassen.
In diesem Sinne möchte ich das Thema hier abschliessen und mich bei
allen Beteiligten (ausser c-hater :)) für ihre Teilnahme bedanken.
Mfg Hans
Hallo Hans Imglück
Anhand deiner Messdaten, von ganz oben, habe ich eine Korrektur-Tabelle
und das dazu passende Leseprogramm erstellt.
Wenn die ADC-Werte wiederholstabil sind, was so zu sein scheint, dann
solltest du mit dieser Tabelle eine Genauigkeit auf etwa +-(2) an der
vierten Volt-Stelle erreichen können. Deine Voltausgabe sollte um eine
zusätzliche Ausgabestelle funktionstüchtig werden.
Um die Korrekturtabelle komplett erstellen zu können, musste ich einen
fehlenden Messpunkt extrapolieren. Das hat zu folgenden Punkt geführt:
( ADC 1023 , 15.91 Volt )
In deiner Messreihe liegt das Ergebnis für den 15,00 Volt Punkt leicht
oberhalb der 15 Volt (mit noch höherem Überhang beim fehlenden 15,91
Volt Punkt). Da meine Korrekturtabelle ausschließlich mit positiven
Korrekturen arbeitet, mustte ich deinen Multiplikator leicht absenken,
auf dezimal 1556, um über die komplette Breite eine positive Korrektur
zu bekommen.
Die Tabelle belegt 256 Byte am oberen Ende im Programmspeicher und das
Leseprogramm zusätlich etwa 128 Byte, den Platz solltest du noch haben.
Das Programm ermittelt zu einem 10-Bit ADC-Eingangswert einen 4-Bit
Hex-Korrekturwert der dem ADC-Wert aufzuaddieren ist. Danach geht es
direkt, ohne weitere Korrekturen, in die Multiplikation mit dezimal
1556, was schon den richtigen Ausgabeanzeigewert liefern sollte.
Wie du das bei dir einzubauen hast, solltest du sicherer wissen als ich.
Auch musst du sehen wie du mit den Registern klarkommst. Benutzt werden
r16, r17, r20, r21, r30, r31. Die Programmaufmachung ist nicht
sonderlich schön und übersichtlich, dafür ist es
Simulator-funktionsgeprüft und sollte die gewünschte Korrektur leisten.
Das Programm reiche ich in der nächsten Post nach.
Die Korrekturtabelle ist hoch redundant und deswegen mindestens "leicht"
overpowered. Zum Zeitpunkt der Programmerstellung wusste und ahnte ich
das nicht, das kam erst bei der Tabellenbestimmung. Andererseits ist
das, abgesehen von der Speicherplatz Belegung, kein Problem. Die Tabelle
kann auf jede Menge mehr an Messpunkten abgestimmt sein und
dementsprechend feinfühliger arbeiten. Da ist es eher so, dass die
Beschränkung auf 4-Bit Korrekturwert schnell zum eigentlichen Problem
werden kann.
Wenn ich das neu machen würde, würde ich das für 4-Bit Korrektur auf 64
Byte herunterbrechen, im Kern aber nur aus Speicherpatzgründen, denn
sieht man davon ab, hat die derzeitige Version nur Vorteile. Entschieden
wichtiger wäre die Erhöhung des Korrekturwertes auf mindestens 5-Bit. In
Verbindung mit der angedeuteten möglichen Datenreduktion müsste das
nicht zu einer größeren Tabelle führen.
Diese friedliche Tabelle hat aber auch was Gutes, sie lässt vermuten
dass der ADC im Kern friedlich ist und die ermittelte Tabelle, auch ohne
zusätzliche Messpunkte, die Korrektur in den Messintervallen
zufriedenstellend leisten könnte. Wird der Chip ersetzt ist sie
hinfällig, es sei denn diese Art Abweichung sei, über den Einzelchip
hinaus, systembedingt.
Das sollte die "neue" Anzeige ausgeben
Hallo Anfänger
Nach Anfänger sieht das allerdings nicht grade aus. Offengesagt bin ich
gradezu überwältigt das du dir soviel Mühe gegeben hast um mein Problem
zu lösen. Das hat sicherlich einige Stunden gedauert.
Da ich schon garnicht mehr damit gerechnet habe, daß das
Thema noch von Interesse ist hab ich heute eigendlich mehr zufällig
nochmal reingeguckt.
Ich werde deine Lösung auf alle fälle ausprobieren und hier nochmal eine
Rückmeldung geben. Vermutlich werde ich bei der Strommessung genauso
vorgehen müssen.
Leider werde ich in den nächsten 14 Tagen nicht dazu kommen mit dem
Projekt weiterzumachen.
Auf jeden Fall will ich mich erstmal recht herzlich bei dir bedanken, da
ich mich für die Zeit und Mühe die du dir gegeben hast vermutlich nie
revanchieren kann.
MfG Hans
Hallo Hans Imglück,
du musst dich nicht revanchieren, ich habe das auch stark aus
Eigeninteresse gemacht. Schön dass du es ausprobieren willst, mich
interessiert schon ob es ohne weitere Messpunkte, zufriedenstellend im
innern der Intervalle arbeitet. Falls es doch "größere" Abweichungen
geben sollte, könnte ein Satz zusätzlicher Messpunkte das evtl auch noch
beseitigen. Solche Messpunkte müssen nicht auf glatten Voltwerten
liegen! Einfach einen Wert im gewünschten Bereich einstellen,
arithmetisches Mittel der 5 Multimeteranzeigen errechnen und den
zugeordneten ADC-Ausgabewert in Analogie zu den schon vorhandenen
Messpaaren (z.B 13,69 V xxxx ADC). Es kostet mich nur wenige Minuten um
damit eine neue Tabelle zu bestimmen.
Strom
Wenn du hierfür Gain nicht verstellen müsstest (was du aber musst) würde
der obige Abgleich auch für die Strommessung funktionieren. Mit der
Gain-Änderung auf 20x kommt die Frage auf, was oben primär abgelichen
wurde. Unsauberkeiten in der Gain-1x Verstärkung, oder Unsauberkeiten im
ADC. Davon wird es abhängen, ob und wieweit die Korrektur auch für die
Strommessung herhält. Eines ist jedoch sicher, sie wird merklich weniger
genau sein als die Spannungsmessung (Eine mögliche Alternative wäre eine
externe Vorverstärkung, aber hier würde mich der zusätzliche Aufwand, im
Verhältnis zum unklaren Erfolg, abschrecken).
Dein verlinktes Programm habe ich mir nochmal genau angesehen. Um
Stolperfallen vorab aus dem Weg zu räumen und einen Versuchslauf
möglichst einfach zu machen, folgt eine Umsetzung wie das in dein
Programm eingebaut werden könnte.