Forum: Mikrocontroller und Digitale Elektronik Berechnung von Variablen


von Julian Z. (julian1103)


Lesenswert?

Hallo Leute,

hoffe ihr könnt mir helfen.

Ich will mit meinem ATmega32 eine berechnung ausführen und das Ergebnis 
über die serielle Schnittstelle ausgeben.

Die berechnung ist folgende:
1
Messwert = 150 + 512; //MinWert + Test halber AD-Wert
2
Messwert = (Messwert-(Offset+IntOffset))*(1+(Scale+IntScale)/100);
3
    
4
Messwert = Messwert + 0.5; // +0.5 für richtige Rundung
5
Messwert = (int) (Messwert);  // Messwert ohne Nachkommastellen

Die Variablen Messwert, Offset, IntOffset, Scale und IntScale sind 
Floats und können während der Laufzeit geändert werden.

Dann die Ausgabe
1
char Output[10];
2
itoa(Messwert, Output, 10);
3
uart_puts(Output);

Das ergebnis ist dann aber immer 0.
Wenn ich nur 150+512 berechnen lasse, bekomme ich auch 662 raus.

Vllt kann mir jemand einen Tipp geben was ich falsch mache.

Schon mal danke im Voraus.

von Wolfgang (Gast)


Lesenswert?

Julian Z. schrieb:
> Vllt kann mir jemand einen Tipp geben was ich falsch mache.

Du versuchst itoa() zu benutzen, um eine float Variable auszugeben. Wie 
der Name schon suggeriert, ist das Terrain von itoa() die Umwandlung von 
Integer in ASCII.

von Mitlesa (Gast)


Lesenswert?

Zeig deinen Programcode sonst wird das nichts.

Du verwurschtelst da wohl verschiedene Datentypen ....
..... und die müssen wir kennen ....

von Noch einer (Gast)


Lesenswert?

> Die Variablen Messwert ... sind Floats

Böse Falle, beim Aufruf des itoa wandelt C die float nicht automatisch 
in eine int um. Du musst explizit casten.

(Hat der Compiler keine Warnung ausgegeben?)

von g457 (Gast)


Lesenswert?

> Böse Falle, beim Aufruf des itoa wandelt C die float nicht automatisch
> in eine int um. Du musst explizit casten.

itoa() ist..
1
char* itoa(int val, char* s, int radix)
Warum sollte die Sprachspezifikation agrat bei ito() nicht gelten?

von Julian Z. (julian1103)


Angehängte Dateien:

Lesenswert?

Hier mal die mein c-file.
Ich habe auch schon versucht die Variable Messwert sowie Offset und 
IntOffset als uint16_t zu deklarieren.
Selber effekt.
Jede Variable bekommt nur einen Wert ohne Nachkommastelle, der auch ins 
Minus gehen kann. Float nur wegen Scaleberechung --> Prozentrechnung.

von Mitlesa (Gast)


Lesenswert?

Julian Z. schrieb:
> Hier mal die mein c-file.

Dir ist schon klar das du dauernd ins EEPROM schreibst, welches
für Dauer-Schreibvorgänge nicht gedacht ist?

von Julian Z. (julian1103)


Lesenswert?

Während der Laufzeit sollte die Variablen auch nur einmal ins EEPROM 
geschrieben werden und dann nur noch gelesen werden.
Ich mache dies nur einmalig zum Abgleich eines Sensors der später an den 
ADC kommt.

von Julian Z. (julian1103)


Lesenswert?

Allerdings sehe ich bei näherer betrachtung das ich bei den "get" 
befehlen den write befehl benutze was hier eigentlich an anderer stelle 
der read Befehl sein sollte. Dies ist ja aber trozdem nicht der Fehler 
warum die Berechnung nicht funktioniert

von Walter S. (avatar)


Lesenswert?

Problem ist dass du gar keine neuen Messwerte kriegst,
es ist falsch im UART Interrupt plötzlich zu versuchen die Bytes per 
Polling zu holen

von Julian Z. (julian1103)


Lesenswert?

@ Walter S.

Meine Berechnung ist im Main in einer while Schleife. Im moment ist auch 
noch kein ADC implementiert. Dies ist nur ein Test mit Testwerten. Es 
sollte 662 rauskommen wenn Offset und Scale 0 sind. Wenn ich die 
Berechnung von Offset und Scale weglasse funktioniert das auch, dass er 
mir 662 überträgt. Aber die Berechnung funktioniert dann nicht mehr.
Wenn ich es im Debugger durchgehe kommt auch 662 mit Berechnung raus 
aber der uProzessor will da irgendwie nicht mitspielen.

von Walter S. (avatar)


Lesenswert?

mach das mal gescheit mit dem UART Empfang.

Ansonsten ist systematische Fehlersuche angesagt, dann bist nicht dem 
Forum ausgeliefert ;-)

ersetz z.B. Mal
    itoa(Messwert, Output, 10);
durch
    itoa(23, Output, 10);
und schau nach was rauskommt. Es gilt den Fehler so lange einzugrenzen 
bis er keine Chance mehr hat

von Julian Z. (julian1103)


Lesenswert?

die itoa() Funktion funktioniert, da z.B. der "getoffset" befehl ohne 
probleme funktioniert. Auch wenn ich als Messwert nur 150+512 vorgebe 
funktioniert das. Sobald ich die Berechnung drin hab, kommt 0 raus. Also 
ein Fehler in der Berechnung. Soweit konnte ich schon eingrenzen. Nur 
hier bin ich etwas überfordert ;-)

von Walter S. (avatar)


Lesenswert?

also wenn du statt
    Messwert = 150 + 512; //Test halber AD-Wert
    Messwert = 
(Messwert-(Offset+IntOffset))*(1.f+(Scale+IntScale)/100.f);

    Messwert = Messwert + 0.5;
    Messwert = (int) (Messwert);

nur
Messwert = 150 + 512; //Test halber AD-Wert

schreibst kannst du dir 662 anzeigen lassen?

Wenn dem so ist würde ich mir das Assemblerlisting anschauen.

Ein Fehler der aber mit deinem Problem vermutlich nichts zu tun hat:
stringempfangen muss volatile sein

und ich muss es wohl noch Mal direkter schreiben:
dein Aufbau mit dem UART-Interrupt in dem der String eingelesen wird ist 
Schrott

von Julian Z. (julian1103)


Lesenswert?

Walter S. schrieb:
> ...Messwert = 150 + 512; //Test halber AD-Wert
>
> schreibst kannst du dir 662 anzeigen lassen?

Jap so ist es.
Die UART Funktion sei jetzt mal dahingestellt. Soweit funktioniert es um 
zu testen ob das richtige rauskommt oder nicht.

Wenn ich die Offsetberechnung mit rein nehme und diese als uint16_t 
deklariere funktioniert das auch.

So wie es aussieht habe ich hier nur Probleme mit den Floats in der 
Berechnung. Sprich sobald ein Float mit drin ist geht nichts mehr.

von Walter S. (avatar)


Lesenswert?

Julian Z. schrieb:
> Die UART Funktion sei jetzt mal dahingestellt. Soweit funktioniert es um
> zu testen ob das richtige rauskommt oder nicht.

nö es funktioniert nicht, sonst müsstest du nicht fragen

messwert und alles andere muss natürlich auch volatile sein da du darauf 
beharrst alles im Interrupt zu bearbeiten

: Bearbeitet durch User
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.