Spannungswerte als ASCII in serielle Monitor darstellen, UART

OP #6849819
Lesenswert?

Guten Tag,
ich bin hier newbie habe Problem mit der Aufgabe, wobei man die analoge 
Spannung eines Potentiometers mit Hilfe von Atmega328p ablesen kann mit 
der Genauigkeit 2 Stelle nach dem Komma. Ich versuchte die 
Eingangspannung über digitale Werte von ADC zu berechnen. Ich habe mit 
TinkerCAD simuliert aber die Spannung, die abgelesen wird, stimmt mit 
den Messwerten am Multimeter gar nicht. Vllt liegt irgendewo Fehler. Ich 
bedanke mich für jede Hilfe :D. Ich wünsche euch einen schönen guten Tag 
noch !! Im Anhang findet man das Bild der Simulation zur Erläuterung und 
den Code.
Angehängte Dateien:
#6849824
Lesenswert?

Vielleich hilft es in der Software eine Kalibrierung einzufügen. Ein 
Wert für den Offset, ein Wert für den Multiplikator. Beide Werte so 
einzustellen, dass die Messwerte mit den Multimeter übereinstimmen. 
(Offset bei OV Eingangsspannung, Multiplikator bei maximaler 
Eingangsspannung)
#6849838
Lesenswert?

Bao Thien N. schrieb:
> Guten Tag,
> ich bin hier newbie habe Problem mit der Aufgabe, wobei man die analoge
> Spannung eines Potentiometers mit Hilfe von Atmega328p ablesen kann mit
> der Genauigkeit 2 Stelle nach dem Komma.

Siehe Festkommaaritjmetik. Wenn gleich man es für einen einfachen 
Test auch mit Fließkomma machen kann, da spielt der Resourcenbedarf 
keine Rolle.

> Ich versuchte die
> Eingangspannung über digitale Werte von ADC zu berechnen. Ich habe mit
> TinkerCAD simuliert aber die Spannung, die abgelesen wird, stimmt mit
> den Messwerten am Multimeter gar nicht.

Was heißt das konket? Wie groß ist die Abweichung?

> Vllt liegt irgendewo Fehler. Ich
> bedanke mich für jede Hilfe :D. Ich wünsche euch einen schönen guten Tag
> noch !! Im Anhang findet man das Bild der Simulation zur Erläuterung und
> den Code.

Warum endet dein Quelltext auf .txt? Man hängt einfach das ORIGINAL an!

Hmm
1
int digit = get_ADCvalue();
2
AnalogWert = (digit*500)/1023;

Klingeling! Wie groß können Zwischenergebnisse hier werden? Siehe 
Festkommaarithmetik.
Moderator (Firma: Titel) Persönliche Seite #6849984
Lesenswert?

AnalogWert = (digit*500)/1023;

Oha. Wenn in einem Programm ein Divisor mit 2^n-1 steht (511, 1023, 2047 
usf), dann ist das meistens ein klares Indiz für "hab ich irgendwo 
herkopiert und habe kP was da passiert".

Korrekt ist hier
AnalogWert = (digit*500)/1024;

Nur wer sich das Ergebnis schönsaufen will, nimmt die falsche Steigung 
mit 1023 als Divisor.

Bao Thien N. schrieb:
> aber die Spannung, die abgelesen wird, stimmt mit den Messwerten am
> Multimeter gar nicht.
Was erwartest du und was kommt stattdessen?
Was sagt dein Programm, wenn du laut Messgerät 1V, 2V, 3V... anlegst?
Gast #6850032
Lesenswert?

Lothar M. schrieb:
> ein klares Indiz für "hab ich irgendwo
> herkopiert und habe kP was da passiert".

Das Bild im Eröffnungsbeitrag ist offenbar kopiert. Mir krempeln sich 
immer die Fußnägel hoch, wenn ich Steckbrettchenbilder sehe, A*-Kiddies 
oder auch die Clowns von heises make.

Dem Bildchen nach liegt das Poti an Ub des µCs, wird also am Anschlag 
immer 1023 liefern, unabhängig von der tatsächlichen Spannung - 
ratiometrisch.

Er hat keine Zahlen geliefert, wie groß die Abweichung gegenüber dem DVM 
ist, ein paar-hundert-mV sind unvermeidbar, weil die Speisung nicht 
exakt 5,00 Volt ist.

Als ich meinen ersten ChinaUNO bekommen habe, kamen nach Blink und 
Lauflicht ein LCD und ein Poti dran, erstmal ein paar Grundlagen 
austesten.

> Korrekt ist hier
> AnalogWert = (digit*500)/1024;

Da muß man aufpassen, den passenden Variablentyp zu definieren - ich 
habe schon Fehler suchen dürfen, weil innerhalb der Berechnung ein 
Überlauf stattgefunden hat.

Man kann es anders anfassen: 1023/5 = 204,6, also
AnalogWert = (digit/204,6);

1024 Schritte an 5 Volt macht gerundet 5 mV Auflösung, da sind Wackler 
in der zweiten Nachkommastelle nicht zu vermeiden, wobei das sein 
geringstes Problem sein dürfte.
#6850083
Lesenswert?

Manfred schrieb:
> Lothar M. schrieb:
>> ein klares Indiz für "hab ich irgendwo
>> herkopiert und habe kP was da passiert".
>
> Das Bild im Eröffnungsbeitrag ist offenbar kopiert. Mir krempeln sich
> immer die Fußnägel hoch, wenn ich Steckbrettchenbilder sehe, A*-Kiddies
> oder auch die Clowns von heises make.

Jaja, dein Beitrag hat uns allen noch gefehlt!
Gast #6850168
Lesenswert?

Ich tue mich noch mit anderen Teilen des Programms schwer:
>    unsigned char digit;
...
>  int digit = get_ADCvalue();
geht das überhaupt? Ja gut, ist in einem eigenen Fokus, aber warum macht 
man das? Verwirrt nur.
Und
>  unsigned char AnalogWert;
>  AnalogWert = (digit*500)/1023;
Ist es sicher, dass das mit den Typen passt? Bei dem größtmöglichen 
ADC-Wert ist der AnalogWert ja 500 und passt nicht in unsigned char.
Gast #6850239
Lesenswert?

Achte mal auf deine Datentypen, die hast du wild durcheinander 
gewürfelt. Da finden eine Menge unerwartete Konvertierungen im 
Hintergrund statt, mit ihren Seiteneffekten.

Die Doku des gcc Compilers sagt dazu "The sizes of these variables 
depend on the hardware and operating system of the computer. On a 
typical 32-bit GNU system, the sizes of the integer types are as 
follows..."

Char ist meistens 8-bit signed integer, muss aber nicht zwingend.

Was short ist musste ich erstmal nachlesen: 16-bit unsigned integer auf 
einem typischen 32-bit GNU System. Keine Ahnung was es auf einem AVR 
ist, ist mir aber auch egal weil ich das so niemals nutze.

Anstatt so unklar definierte Sachen wie short und char für Messwerte zu 
benutzen empfehle ich:
1
#include <stdint.h>
2

3
uint16_t get_ADCvalue()
4
{
5
   ...
6
   uint16_t Wert=ADC;
7
   return Wert;
8
}
9

10
...
11

12
uint16_t digit = get_ADCvalue();

uint16_t deswegen, weil das ADC Register dieses Format hat.
Gast #6850621
Lesenswert?

HildeK schrieb:
>>  unsigned char AnalogWert;
>>  AnalogWert = (digit*500)/1023;
> Ist es sicher, dass das mit den Typen passt? Bei dem größtmöglichen
> ADC-Wert ist der AnalogWert ja 500 und passt nicht in unsigned char.

Deshalb schrieb ich gestern, dass man auf den Variablentyp aupassen muß:
Manfred schrieb:
> Da muß man aufpassen, den passenden Variablentyp zu definieren - ich
> habe schon Fehler suchen dürfen, weil innerhalb der Berechnung ein
> Überlauf stattgefunden hat.

Wenn der ADC z.B. 500 liefert, ergibt die Multipikation mit 500 dann 
250000, ein normales unsigned läuft aber bei 65536 über.

Aus dem Grunde erspare ich mir die temporäre Riesenzahl und dividiere:

> Man kann es anders anfassen: 1023/5 = 204,6, also
> AnalogWert = (digit/204,6);

---------

Scheint so, dass Herr Bao Thien N. (baobao97) nicht mehr folgt, sonst 
hätte er ja mal Beispiele geliefert, welche Werte der Arduino mist und 
was sein DVM zeigt.
OP #6850664
Lesenswert?

Hallo Leute,
tut mir leid,ich bin am Wochenende so beschäftig mit Nebenjob als 
Student(T.T). deswegen habe ich jtzt Zeit, mich zu melden.Danke ertsmal 
für eure Hilfe.

Stefan ⛄ F. schrieb
> Anstatt so unklar definierte Sachen wie short und char für Messwerte zu
> benutzen empfehle ich:#include <stdint.h>
> uint16_t get_ADCvalue()
> {
>    ...
>    uint16_t Wert=ADC;
>    return Wert;
> }
> ...
> uint16_t digit = get_ADCvalue();
>
> uint16_t deswegen, weil das ADC Register dieses Format hat.

ich habe versuch aber funktionert auch nicht

Manfred schrieb:
> Man kann es anders anfassen: 1023/5 = 204,6, also
>> AnalogWert = (digit/204,6);

das habe ich auch gemacht aber geht auch leider nicht
Angehängte Dateien:
(Firma: irre) #6850689
Lesenswert?

Bao Thien N. schrieb:
> Die Messwerte auf Serial Minitor unten recht im Bild soll mit dem
> Multimeter(gelbes Stück) übereinstimmt.
Das wird nicht gelingen.
A. deine Ausgabe kann kein Float
B. Du verwendest Vcc als Refrenz.(variiert)
C. Noch Böcke bei den Datenypen/Wertebereichen?

Meine Tipps:
Sogfältig mit Datentypen umgehen.
Ob Fest- oder Fließkomma... deine Ausgabe muss das zeigen können.

Absolute Messungen mit der internen Referenz (z.B. 2 Punkt Kalibrierung)
Ratiometrische Messungen mit Vcc als Referenz

Dann kann das was werden.
#6850717
Lesenswert?

Bao Thien N. schrieb:
> Hallo Leute,
> tut mir leid,ich bin am Wochenende so beschäftig mit Nebenjob als
> Student(T.T). deswegen habe ich jtzt Zeit, mich zu melden.Danke ertsmal
> für eure Hilfe.

Naja.

>> Man kann es anders anfassen: 1023/5 = 204,6, also
>>> AnalogWert = (digit/204,6);
>
> das habe ich auch gemacht aber geht auch leider nicht

Weil du noch mehr Fehler im Programm hast.

unsigned char AnalogWert;

Das sind nur mickrige 8 Bit.

Versuchs mal so.

unsigned int AnalogWert;
....
AnalogWert = (digit*500L)/1024;

Das 500L ist wichtig. Und lies den Artikel Festkommaarithmetik. Dazu 
warst du bisher zu faul oder ignorant.
OP #6850754
Lesenswert?

Christian H. schrieb:
> 1023/5 = 204.6
> Bitte kein Komma verwenden, sondern den Dezimalpunkt.

jetz funktionier das aber nur wenn ich 1024/500 statt 5V. ich meine 
Aufgabeblatt von Uni steht schon man muss Uref mit 100 mutiplizieren, 
ich weiß nicht wieso, wir haben all als online Praktika und Simulation 
mit TinkerCAD, die Schaltung im Bild ist von Dozenten aufgebau, ich habe 
die nicht von jmd kopiert oder so
#6850772
Lesenswert?

Bao Thien N. schrieb:
> Ich lese gerade die immer noch, für mich ein bisschen schwer, in Deutsch
> zu lesen, bitte um Verständnis.

Mag sein, aber in dem Artikel findest du praktisch alle Antworten auf 
deine Fragen. Und da du Student bist, solltest du dir das alles selber 
durcharbeiten können und WOLLEN!

"Nur selber denken macht geistig fett."

Einer der vielen schönen Sprüche meines Mathematiklehrers (RIP)
#6850774
Lesenswert?

Bao Thien N. schrieb:
> Danke euch für alle Unterstüzung, ich bin auf das Ergebnis angekommen,
> nur die Spannung schwankt um den wahren Wert.

Naja, so schwanke ich auch, wenn ich mal wieder zu lange in der Kneipe 
war ;-)

Da ist was faul. Die Spannung sollte bestenfalls um ein paar Dutzend mV 
schwanken, aber niemals um VOLT!

Zeig mal ein Photo von deinem realen Aufbau. Bildformate beachten!
#6850784
Lesenswert?

Bao Thien N. schrieb:
> Falk B. schrieb:
>> Zeig mal ein Photo von deinem realen Aufbau. Bildformate beachten!
>
> als Aufbau in realer Welt habe ich nicht, ich letzte Woch die ersten 2
> online Vorlesung von Mikroprozessor und man muss alles online im
> TinkerCAD(siehe oberes Bild) machen. Diese Aufgabe ist meine
> Vorbereitung für Praktikum in 2 Wochen, ich mache nur selbst Studium.

Häää? Und mit was testest du JETZT?
Moderator (Firma: Titel) Persönliche Seite #6850800
Lesenswert?

Bao Thien N. schrieb:
> ich habe versuch aber funktionert auch nicht
Mach dir vorher Gedanken zu deiner Software. Du kopierst laufend nur 
irgendwas irgendwoher in dein Programm und das tut dann immer noch 
nichts Sinnvolles. Parallel zum kopieren solltest du auch versuchen zu 
kapieren, was der jeweilige Vorschlag dir sagen will.
Hast du eigentlich die Fragen zu deinem ursprünglichen Programm gesehen?

EAF schrieb:
> Was passiert?
> Was erwartest du stattdessen?
Besser wäre:
Was erwartest du?
Und was passiert stattdessen?
Denn das bedeutet, dass man sich vorher Gedanken gemacht hat, ein 
Programm dazu geschrieben hat und ein bestimmtes Verhalten erwartet.

A. S. schrieb:
> Mit 2 Bit und 4V wird's deutlicher:
> 0V..1V=0

> 1V..2V=1

> 2V..3V=2

> 3V..4V=3

1V ist also entweder 0 oder auch 1?
Und 2V kann 1 oder auch 2 sein?
Oder müsste es nicht korrekt so heißen:

0V..0,99V=0

1V..1,99V=1

2V..2,99V=2

3V..3,99V=3

> --> d*4/3
Damit haben wir 1,33V-Schritte und können zurückrechnen:
der AD-Wert 3 ergibt dann auf der Anzeige 4,00V,
AD=2 wird als 2,66V angezeigt,
1 ergibt 1,33V und 0 ergibt 0V. Seltsam krumme Werte...

Aber jetzt kommt es: welchen AD-Wert ergibt mit diesem Wandler eine 
Eingangsspannung von 0V? 1V? 1,5V? 2V? 3V? 3,5V? 3,9V? 4V?
#6850820
Lesenswert?

Bao Thien N. schrieb:
> Falk B. schrieb:
>> Hmm.
>> Aber ich hab noch einen Fehler gefunden. Du liest den falschen ADC-Kanal
>> aus. Dein Poti hängt an A1, du liest aber Kanal 0 aus. Eher so.
>>
>> ADMUX |=(1<<1);
> Auf dem Datenblatt von ATmega328p steht so bei ADMUX aus Wahl, ich
> hoffe, ich habe den richtigen Bit ADC1 mit 1 an 0.MUX0 bit ausgewählt.

Ahhhh, stimmt. Mein Fehler! Ich hab mich durch deine Schreibweise 
irritieren lassen. Hier schreibt man das sinnvollerweise NICHT mittels 
Schiebeoperation, sondern direkt als Zahl!

ADMUX |= 1;
Gast #6850833
Lesenswert?

EAF schrieb:
> Was erwartest du stattdessen?
Bao Thien N. schrieb:
> Die Messwerte auf Serial Minitor unten recht im Bild soll mit dem
> Multimeter(gelbes Stück) übereinstimmt.

Verdammt nochmal, dann zeige eine Reihe Werte:
10 Verschiedene Stellungen des Potis und abtippen, was DVM und Monitor 
anzeigen.

Du gehst leider auch nicht logisch vor: Du hast eine funktionsfähig 
serielle Ausgabe, also füge an jeder Stelle, wo ein Wert erzeugt wird, 
ein serial.print und ein delay ein und schaue Dir die Werte an.

Minus M. schrieb:
> Absolute Messungen mit der internen Referenz (z.B. 2 Punkt Kalibrierung)
> Ratiometrische Messungen mit Vcc als Referenz
>
> Dann kann das was werden.
Ich hoffe, Du teilst Dir selbst Minus zu!

Grundsätzlich kann man auch mit Vcc Werte messen, solange man mit der 
möglichen Drift von Vcc leben kann. Bao scheint doch ein ganz anderes 
Problem zu haben, Werte jenseit der Realität - die er uns hoffentlich 
noch verrät.

Und ja, sein Aufbau ist ratiometrisch, das Ding muß am Rechtsanschlag 
1023 entsprechend 5,00 Volt anzeigen, selbst, wenn Vcc nur 4,7 oder gar 
5,3V beträgt. Darüber sprechen wir, wenn er soweit gekommen ist.
Gast #6850846
Lesenswert?

Falk B. schrieb:
> Das hatten wir schon mal vor VIELEN Jahren diskutiert.

Das macht es nicht richtiger, vor allem, wenn man den zweiten Teil 
unterschlägt: die Addition des halben LSBs. Dann ist 1024 bzw. hier 4 
vermutlich richtig.

Lothar M. schrieb:
> Seltsam krumme Werte...

Nicht Dein Ernst, oder? Und welcher Bereich nun inclusive und welcher 
exclusive 1 ist, was soll das.

Lothar M. schrieb:
> Damit haben wir 1,33V-Schritte und können zurückrechnen:
> der AD-Wert 3 ergibt dann auf der Anzeige 4,00V,
> AD=2 wird als 2,66V angezeigt

Ja.

Startet der AD mit einem ganzen Bit, dann ist 2^n gut, erfordert aber 
das halbe Bit Offset. Das fehlt aber bei Dir. Darum
A. S. schrieb:
> nicht korrekter

Startet (und endet) der AD mit einem halben Bit, ist 2^n-1 perfekt, 2^n 
nur falsch.

Schade finde ich nur, dass dies hier im Thread nichts zu suchen hat, da 
der TO ein absoluter Anfänger ist und an ganz anderer Front kämpft.
Gast #6850900
Lesenswert?

Manfred schrieb:
> Und ja, sein Aufbau ist ratiometrisch,

Da hat der Minusmann schon recht....
Bei einer ratiometrischen Messung darf man auch nur ratiometrische Werte 
erwarten.
Das Messgerät ist allerdings absolut.

Ihm (der TO) versucht also eine ratiometrische und eine absolute Anzeige 
in Übereinstimmung zu bringen.

Das geht natürlich nicht. Ist irgendwie unsinnig. Unlogisch.

Manfred schrieb:
> solange man mit der
> möglichen Drift von Vcc leben kann
Damit bestätigst du, dass es kaum möglich ist, die Anzeigen in 
Übereinstimmung zu bringen.

Das ist sowieso schon schwierig genug!
Aber mit dem logischen Fehler im Bauch quasi unmöglich.
1
// 1 Punkt Kalibrierung (reduzierte Geradengleichung)
2

3
constexpr float maximalEinstellbarerWert {4.59};//Volt vom DMM abgelesen
4
constexpr float steigung {maximalEinstellbarerWert/1024.0};
5

6

7

8
void setup()
9
{
10
  Serial.begin(9600);
11
}
12

13
void loop()
14
{
15
  Serial.print(steigung * analogRead(A1));
16
  Serial.println("V");
17
  delay(1000);
18
}

Kalibriert auf eine Versorgung, ein µC, und ein Referenzmessgerät, ist 
alles OK.
Aber umgesteckt, z.B. von einem PC an den anderen, oder eine externe 
Versorgung?
Zack weg... 10% sind da locker drin.

Also:
Wenn absolute Werte gewünscht sind, dann sollte man das Messverfahren 
auch so bauen, dass man absolute Werte erhält.

----

Bao Thien N. schrieb:
> ich meine
> Aufgabeblatt von Uni steht schon man muss Uref mit 100 mutiplizieren,
Schon richtig!
Das liegt an deiner seltsamen Ausgabe.
Gast #6850932
Lesenswert?

Lothar M. schrieb:
> EAF schrieb:
>> Was passiert?
>> Was erwartest du stattdessen?
> Besser wäre:
> Was erwartest du?
> Und was passiert stattdessen?
> Denn das bedeutet, dass man sich vorher Gedanken gemacht hat, ein
> Programm dazu geschrieben hat und ein bestimmtes Verhalten erwartet.

Da spricht deine Erwartungshaltung, ganz laut!
Evtl. ist die, leicht bis mittelschwer, überzogen.

Bedenke:
Die Erwartungshaltung, ist die Mutter der Enttäuschung.

Wobei man da auch sagen muss, dass eine Enttäuschung ein ungemein 
positives Erlebnis ist.
Das Wort sagt es schon, man kann so eine (Selbst)Täuschung erkennen und 
abwerfen.
Besser geht es kaum, ein wahrhaft Glück bringendes Ereignis.
Also alles gut so, weiter so.
Gast #6850937
Lesenswert?

EAF schrieb:
>> Und ja, sein Aufbau ist ratiometrisch,
>
> Da hat der Minusmann schon recht....
> Bei einer ratiometrischen Messung darf man auch nur ratiometrische Werte
> erwarten.
> Das Messgerät ist allerdings absolut.
>
> Ihm (der TO) versucht also eine ratiometrische und eine absolute Anzeige
> in Übereinstimmung zu bringen.
>
> Das geht natürlich nicht. Ist irgendwie unsinnig. Unlogisch.

Das ist vollkommen richtig und ich hatte es bereits vorher angerissen:

Manfred schrieb:
> Dem Bildchen nach liegt das Poti an Ub des µCs, wird also am Anschlag
> immer 1023 liefern, unabhängig von der tatsächlichen Spannung -
> ratiometrisch.
>
> Er hat keine Zahlen geliefert, wie groß die Abweichung gegenüber dem DVM
> ist, ein paar-hundert-mV sind unvermeidbar, weil die Speisung nicht
> exakt 5,00 Volt ist.

Es bleibt aber das Grundproblem: Der TO hat irgendwelche Zufallswerte 
und muß erstmal seine groben Fehler ausmerzen.
Es müssen erstmal stabile Werte zwischen 0 und 1023 vom ADC kommen und 
sinnvoll nach Volt umgerechnet werden, danach diskutieren wir solche 
Feinheiten.

Ich habe mehrere Anwendungen, wo ich per Arduino messe und sinnvolle 
Werte bekomme, das ist kein Hexenwerk. Ich habe das auch nicht direkt 
beim ersten Versuch hinbekommen, aber, siehe weiter vorne, mir seriell 
Zwischenwerte ausgeben lassen und damit eingegrenzt, wo es klemmte.
Gast #6850943
Lesenswert?

Manfred schrieb:
> Es bleibt aber das Grundproblem: Der TO hat irgendwelche Zufallswerte
> und muß erstmal seine groben Fehler ausmerzen.
Das hat er gesagt bekommen!
1. Die Berechnung und ihre Datentypen
2. Die Multiplexer Port Irritierung/Vertauschung

Manfred schrieb:
> danach diskutieren wir solche Feinheiten.
Da du hier zum Ober Guru ernannt wurdest, werde ich dir natürlich ohne 
jeden Widersprich gehorchen, und das Thema auch nie wieder erwähnen. Ich 
erwarte dann ergebenst dein Startsignal, bevor wir denn auch mal an das 
"Eingemachte" gehen...
Lass uns solange, den TE und auch die unbedarften Mitleser, ruhig in die 
Irre laufen lassen. Ist schließlich deren Irre und nicht unsere. 
Zumindest wir beide wissen es ja besser.
Gast #6851008
Lesenswert?

Ist das so schwer, einfach mal zusätzlich den Wert vom ADC register 
auszugeben?

Man muss Fehler einkreisen. Jede Ausgabe beruht auf einer Eingabe und 
einer Verarbeitung. Das wiederum passiert typischerweise in mehreren 
Schritten. Also gibt man diese Zwischenwerte aus, dann sieht man ob es 
an den Werten oder der Verarbeitung liegt.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren