Forum: Mikrocontroller und Digitale Elektronik Char wandeln


von guest (Gast)


Lesenswert?

Hallo,

Ich versuche grade eine Spannungsmessung mit dem ADC des Mega32 zu 
basteln. Bisher liefs auch ganz gut. Ich möchte nun aber nicht nur den 
digitalen Wert des ADC Wandler aufs Display bringen, sondern auch eine 
Umrechnung auch Volt.

Ich bekomme aber mein Char Array nicht konvertiert. atof() bringt meinen 
Compiler zum weinen und ich weiß nicht warum.

Hier mal der Code bisher
1
#include <avr/io.h>
2
#include <avr/delay.h>
3
#include <util/display.h>
4
#include <stdio.h>
5
#include <stdlib.h>
6
#include <avr/interrupt.h>
7
8
9
void main()
10
{
11
  int i=0;
12
  int result;                // Ergebniss der ADC Messung
13
  char buffer[6];              // Var für Wandlung Binär->Dez
14
15
  // ADC TESTS
16
  display_init();    
17
  ADMUX = 0b01000000;            // AD Kanal und Referenz einstellung
18
  do
19
  {
20
    ADCSRA = 0b11101110;        // ADC Initialisieren
21
22
    _delay_ms(15);
23
    result = ADC;        
24
    itoa(result, buffer, 10 );      // Wandlung Binär->Dez
25
    display_ptext("ADC:",2,1);      // Ausgabe
26
    display_position(2,6);
27
    display_text(buffer);
28
    if(buffer<'1000')          // 1/1000 bei Nichtnutzung löschen
29
    {
30
      display_ptext(" ",2,9);
31
    }
32
    _delay_ms(5);
33
  } while(i < 1);
34
}

Nun würde ich halt gerne:
spannung = ((buffer/1023)*5) rechnen. Geht natürlich nicht. Wie muss ich 
da vorgehen? Am liebsten in c++ ^^

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du verfolgst fast den richtigen Ansatz, aber machst kurz vor der 
Zielgeraden einen entscheidenden Fehler.

Einerseits wandelt itoa nicht "Binär->Dez" um, sondern erzeugt eine 
Klartext-Repräsentation (ein String, eine Zeichenkette) des übergebenen 
numerischen Wertes, andererseits musst Du, um Deine Berechnung anstellen 
zu können, das nicht mit der Klartext-Repräsentation des Wertes 
anstellen.

Am einfachsten ist das mit Floating-Point-Arithmetik:
1
int result;
2
float spannung;
3
 
4
spannung = (result / 1023.0) * 5.0;
(Beachte hier die abweichende Schreibweise der Konstanten!)

Diesen so bestimmten /float/-Wert musst Du noch für die Ausgabe in eine 
Klartextrepräsentation umwandeln, das geht am einfachsten mit der 
Funktion sprintf.
1
sprintf(buffer, "%2.2f V", spannung);

Der Ansatz hat aber zwei Nachteile:

- Floating-Point-Arithmetik ist rechenzeitintensiv und benötigt viel 
Codespeichher

- sprintf benötigt ebenfalls viel Codespeicher

von H.Joachim S. (crazyhorse)


Lesenswert?

geht doch mit Ganzzahl genauso.
(long) result*5000/1023;
liefert dir die Angabe in mV. komma passend setzen, fertig.

von guest (Gast)


Lesenswert?

Rufus ich habe mein programm jetzt um deinen code erweitert. Leider 
steht nun an der stelle wo die spannung stehen sollte nur ein 
fragezeichen. diese ganze umwandelei von datentypen ist mir allerdings 
auch noch ein rätsel. vielleicht kannst du mir nochmal sagen was ich 
falsch gemacht habe.
1
#include <avr/io.h>
2
#include <avr/delay.h>
3
#include <util/display.h>
4
#include <stdio.h>
5
#include <stdlib.h>
6
#include <avr/interrupt.h>
7
8
9
void main()
10
{
11
  int i=0;
12
  float spannung;
13
  int result;                // Ergebniss der ADC Messung
14
  char buffer[6];              // Var für Wandlung Binär->Dez
15
16
  // ADC TESTS
17
  display_init();    
18
  ADMUX = 0b01000000;            // AD Kanal und Referenz einstellung
19
  do
20
  {
21
    ADCSRA = 0b11101110;        // ADC Initialisieren
22
23
    _delay_ms(15);
24
    result = ADC;        
25
    itoa(result, buffer, 10);      // Wandlung Binär->Dez
26
    display_ptext("ADC:",2,1);      // Ausgabe
27
    display_position(2,6);
28
    display_text(buffer);
29
    if(buffer<'1000')          // 1/1000 bei Nichtnutzung löschen
30
    {
31
      display_ptext(" ",2,9);
32
    }
33
    spannung = (result / 1023.0) * 5.0;
34
    display_ptext("Spannung:",3,1);
35
    sprintf(buffer, "%2.2f V", spannung);
36
    display_position(3,10);
37
    display_text(buffer);
38
    _delay_ms(5);
39
  } while(i < 1);
40
}

von Stefan E. (sternst)


Lesenswert?

1
    if(buffer<'1000')
Das ist ..., naja, Unsinn halt.
->
1
    if(result<1000)

> Leider steht nun an der stelle wo die spannung stehen sollte nur
> ein fragezeichen.

http://www.mikrocontroller.net/articles/FAQ#Aktivieren_der_Floating_Point_Version_von_sprintf_beim_WinAVR_mit_AVR-Studio

von Karl H. (kbuchegg)


Lesenswert?

@ Thread Opener

>
1
    if(buffer<'1000')
> Das ist ..., naja, Unsinn halt.

Ohne Vorkentnisse in Stringverarbeitung ist das nicht wirklich zu 
verstehen, warum das überhaupt compiliert. Es compiliert, aber es macht 
etwas völlig anderes als du vermutest.

Zum Thema Stringverarbeitung: Scroll in der von Stefan verlinkten FAQ 
auch etwas nach oben. Dort findest du eine kurze, minimalistische 
Abhandlung über Strings. Die umfasst ungefähr 10% von dem was es über 
Strings so alles zu erzählen gäbe.

> sprintf(buffer, "%2.2f V", spannung);

Du solltest dir auch in einem C-Lehrbuch deiner Wahl die Bedeutung der 
Buchstaben und Ziffern im Formatstring von sprintf ansehen.

%2.2f ist nicht sehr sinnvoll. Das besagt:
Die Floating Point Zahl wird in einem Feld der Länge 2 ausgegeben, wobei 
2 Stellen davon Nachkommastellen sein sollen.
Nun sind 2 Stellen + der klarerweise notwendige Dezimalpunkt schon 
mindestens 3 Stellen und da sind jetzt noch gar keine Stellen vor dem 
Komma gerechnet. 2.2 kann daher schon nicht passen, weil es mindestens 
4.2 sein müssten (das Feld muss mindestens 4 Stellen breit sein: Eine 
Vorkommastelle, der Dezimalpunkt und 2 Nachkommastellen macht 4 Stellen 
gesamt). Jetzt ist da noch kein eventuell vorhandenes Vorzeichen gezählt 
(gut, kommt bei dir nicht vor) und mit einer Vorkommastelle wirst du 
auch nicht auskommen.
Gut ist nur, dass sprintf deine Angaben weitgehend ignoriert, wenn es 
damit nicht zurechtkommt. Trotzdem solltest du das richtig stellen.
Dazu musst du aber wissen, was es so alles gibt.


-> Das lernst du aus einem C-Buch!
Du brauchst eines! Ohne geht es nicht!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> %2.2f ist nicht sehr sinnvoll.

Da hast Du natürlich wie so oft recht.

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.