Forum: Compiler & IDEs Modulo bringt unerwartete Ergebnisse


von Robin T. (rotoe) Benutzerseite


Lesenswert?

Hallo erstmal,

zu Anfang: Ich habe vor ein kleines Ladegerät zu basteln. Dafür brauche 
ich auch einen ADC. Ich möchte auf 2 Kommastellen genau messen. Aber 
wenn ich z.B. 2,5V anlege bekomme ich mittels Modulo: 2,1108 raus. 
Irgendwie steh ich aufm Schlauch. Ich habe keine Ahnung warum der 
soviele Stellen anzeigt. Momentan hab ich sowieso nen totalen BlackOut. 
Irgendwie verstehe ich nicht wie Modulo die Kommastellen begrenzt. Wenn 
z.B. die Zahl 4,448827364232 ist läuft meine Variable hofnungslos über 
oder begrenzt Modulo das von sich aus?
Hier mal der Relevante Code. Wenn ihr mehr wollt sagt bescheid. Ist 
vieleicht etwas unübersichtlich. Wenn ich morgen wieder bei klarmen 
verstand bin und es nötig ist werde ich ein paar Kommentare einfügen.
1
UZelle = ADC*10;
2
mV = UZelle%2046;
3
UZelle = UZelle/2046;
4
_delay_ms(250);
5
set_cursor(0,2);
6
lcd_string("Zelle=");
7
lcd_string(utoa(UZelle, ASCII, 10));
8
lcd_string(",");
9
if(mV <= 9)
10
{
11
  lcd_string("0");
12
}
13
lcd_string(utoa(mV, ASCII, 10));
14
lcd_string("V  ");

von Matthias L. (Gast)


Lesenswert?

Kannst du mal den Sinn folgender Zeilen erklären?
1
UZelle = ADC*10;
2
mV = UZelle%2046;
3
UZelle = UZelle/2046;



Frage:
- Welche Referenzspannung hat der ADC?
- Welche Auflösung? 10bit => 1024 ?
- Welcher Spannungsbereich liegt am ADC-Eingang so an?
- Wie soll das Ausgangssignal normiert sein? in Millivolt?

von Peter D. (peda)


Lesenswert?

Wenn Du 2 Kommastellen haben willst, mußt Du %100 und /100 verwenden.

Ab ATmega8 darf man auch float verwenden.
Alle 250ms eine float Zahlenausgabe tut nicht weh.


Peter

von Robin T. (rotoe) Benutzerseite


Lesenswert?

Matthias Lipinsky wrote:
> Kannst du mal den Sinn folgender Zeilen erklären?

> UZelle = ADC*10;
Da wird der eingelesene ADC_Wert mal 10 genommen um die Auflösung zu 
verbessern.
> mV = UZelle%2046;
Da "sollen" die mV ausgrerechnet werden.
Um auf 5V zu kommen muss 1024 / 204,6 genommen werden. Weil mal 10 
genommen also 2046.
[c]
> UZelle = UZelle/2046;
Hier werd die Spannung ausgerechnet.


> Frage:
> - Welche Referenzspannung hat der ADC?
5V
> - Welche Auflösung? 10bit => 1024 ?
10Bit
> - Welcher Spannungsbereich liegt am ADC-Eingang so an?
0-5V
> - Wie soll das Ausgangssignal normiert sein? in Millivolt?
1,23V

von Andreas K. (a-k)


Lesenswert?

Robin Tönniges wrote:

>> UZelle = ADC*10;
> Da wird der eingelesene ADC_Wert mal 10 genommen um die Auflösung zu
> verbessern.

0..5V => 0..10230.

>> mV = UZelle%2046;
> Da "sollen" die mV ausgrerechnet werden.

0..2045    => 0..2045
2046..4091 => 0..2045
4092..6137 => 0..2045
usw.

M.a.W: Ab diesem Zeitpunkt ist es Unfug.

von Andreas K. (a-k)


Lesenswert?

Bei 5V Referenz und 10 Bit ADC entspricht ein ADC-Schritt 5V/1024.

Also in mV: UZelle = (ADC * 5000L) / 1024.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

>Ab diesem Zeitpunkt ist es Unfug.
Schon vorher, wenn nämlich aus dem AD-Wert 0..1023 (also 1024 Schritten) 
dann irgendwann nur noch 0..2045 (also 2 * 1023 Schritte) mit ca. 1 
Promille Fehler wird.
Das wird immer wieder gern mal falsch gemacht, und so ein klitzekleiner 
Steigungsfehler in die AD-Kennlinie gebracht.

Wir fangen hier bei Null an. Und Null ist nicht einfach nichts, sondern 
durchaus brauchbare Information. Richtigerweise müsste hier also modulo 
2048 gerechnet werden (wenn überhaupt).

von Andreas K. (a-k)


Lesenswert?

Lothar Miller wrote:

> durchaus brauchbare Information. Richtigerweise müsste hier also modulo
> 2048 gerechnet werden (wenn überhaupt).

Naja, einen Wert 0..1023 mit %2048 zu traktieren ist nicht sinnvoller 
als ein paar NOPs einzubauen.

von Robin T. (rotoe) Benutzerseite


Lesenswert?

> Lothar Miller wrote:
> Naja, einen Wert 0..1023 mit %2048 zu traktieren ist nicht sinnvoller
> als ein paar NOPs einzubauen.

Es wird ja nicht 0..1023 mit %2048 sondern o..1023*10 also 0..10230 
%2048 genommen.

von Falk B. (falk)


Lesenswert?

@ Peter Dannegger (peda)

>Alle 250ms eine float Zahlenausgabe tut nicht weh.

Nöö, aber mal 5 min über Festkommaarithmetik nachdenken auch nicht . 
. . ;-)

MfG
Falk

von Peter D. (peda)


Lesenswert?

Falk Brunner wrote:
> Nöö, aber mal 5 min über Festkommaarithmetik nachdenken auch nicht .
> . . ;-)

Sehe ich hier aber nicht.
Es wird über %2046 oder %2048 gestritten. Und beides ist Schwachfug, 
wenn man Dezimalzahlen ausgeben will.


Peter

von Falk B. (falk)


Lesenswert?

@ Peter Dannegger (peda)

>Es wird über %2046 oder %2048 gestritten. Und beides ist Schwachfug,
>wenn man Dezimalzahlen ausgeben will.

Ein Grund mehr, über Festkommaarithmetik nachzudenken ;-)

MFG
Falk

von Robin T. (rotoe) Benutzerseite


Lesenswert?

Falk Brunner wrote:
> Ein Grund mehr, über Festkommaarithmetik nachzudenken ;-)

Mal davon abgesehen das ich von Anfang an Festkommaarithmetik verwendet 
habe.
Hat aber nichts mit dem eigentlichen Problem zu tun. Ich versuche den 
Rest der Teilung von 10230 / 2048 herauszufinden und hinter 5, zu 
hängen.

von Matthias L. (Gast)


Lesenswert?


von Robin T. (rotoe) Benutzerseite


Lesenswert?

Ah ok. Problem gelöst. Ich werds jetzt in mV umwandeln wies hier schon 
jemand gesagt hat dann %1000 fertig.
Danke für eure Hilfe

von Matthias L. (Gast)


Lesenswert?

>jemand gesagt hat dann %1000 fertig.

Geht auch ohne. (siehe meine geposteten Links)

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
Noch kein Account? Hier anmelden.