Forum: Compiler & IDEs ADC in String umwandeln


von JannikS (Gast)


Lesenswert?

Hallo zusammen,

Ich habe mich eben an einer AD wandlung versucht.

Wenn ich das Ergebnis auf dem LCD ausgeben möchte erhalte ich nur Werte 
von 0-258. Es sollte ja von 0-1024 bei 10 Bit sein.

Ich denke mein Fehler liegt in der Umformung.

Hier mal mein Code:

unsigned int adcval;
char adcbuffer[33];

if (channel == 2){
ADMUX = 0x42; // MUX ADC2
}

ADCSRA |= (1<<ADSC);

while ( ADCSRA & (1<<ADSC) ) {
}


adcval = ADCL;
adcval += ADCH;
itoa(adcval, adcbuffer,10);

lcd_write_txt(adcbuffer);

von yalu (Gast)


Lesenswert?

> adcval = ADCL;
> adcval += ADCH;

Du hast einfach nur Low- und High-Byte addiert.

Besser:
1
adcval = ADCL;
2
adcval += ADCH << 8;

Noch besser:
1
adcval = ADC;

von JannikS (Gast)


Lesenswert?

Ahhh, wunderbar. Es funktioniert. So einfach ist das also :)

von JannikS (Gast)


Lesenswert?

Jetzt wo die Ausgabe sauber funktioniert (werte von 0-1023), würde ich 
diese auch gerne einer Spannung zuordnen.

Das was ich hinbekomme ist, dass ich Ganzzahlen von 0-4 (Volt) ausgeben 
kann.
Nur meine Nachkommastellen verschwinden. Wär super wenn ihr mir da auch 
noch mal weiterhelfen könnt. Hier wieder ein Auszug:
1
unsigned int adcval;
2
unsigned int adcbuffer;
3
float result;
4
5
6
void lcd_write_txt(char *txt) {
7
  while(*txt) {
8
        lcd_write(*txt);
9
        txt++;
10
  }
11
}
12
13
int adc_getval(int channel){
14
      
15
  if (channel == 0){
16
    ADMUX = 0x40; // MUX ADC0 Uref = 5V
17
  }
18
      
19
  if (channel == 1){
20
    ADMUX = 0x41; // MUX ADC1 Uref = 5V
21
  }
22
      
23
  if (channel == 2){
24
    ADMUX = 0x42; // MUX ADC2 Uref = 5V
25
  }
26
      
27
  ADCSRA |= (1<<ADSC);
28
      
29
  while ( ADCSRA & (1<<ADSC) ) {
30
  }    
31
32
33
  adcval = ADCL;
34
  adcval += ADCH <<8;
35
      
36
  result = adcval*(5.0/1024.0);    
37
      
38
  itoa(result, adcbuffer,10);  
39
40
    return adcbuffer;
41
}
42
43
int main (void){
44
lcd_write_txt(adc_getval(0));
45
}

Ich tippe irgendwie auf die nutzung von itoa(); und meine funktion 
müsste ja eigentlich auch einen char zurückgeben. Wenn ich diese als 
char deklariere kommt die Warnung vom Compiler: passing argument 2 of 
'itoa' makes pointer from integer without a cast.

von Johannes M. (johnny-m)


Lesenswert?

Festkommaarithmetik!
Gleitkomma-Berechnungen sind auf einem µC nicht nur Ressourcenfresser, 
sondern in diesem Fall auch völlig unsinnig.

Und die Funktion heißt nicht umsonst itoa (integer to ascii), weil 
sie integer-Werte (ganzzahlige Werte) in einen ASCII-String 
konvertiert, und mit float nix anfangen kann. Und in integer gibt es 
nunmal keine Nachkommastellen. Für Gleitkommawerte gibt es zwar 
dtostrf bzw. dtostre , aber wie schon gesagt, lass es lieber sein.

von Johannes M. (johnny-m)


Lesenswert?

Ach übrigens: Du solltest Dir dringendst mal die Dokumentation der 
Funktion itoa in der libc-Doku anschauen! Das mit Deinem adcbuffer 
kann so nicht funktionieren. Ein String wird in C als Array of char 
abgelegt und ist außerdem noch nullterminiert, braucht also ein Zeichen 
mehr als der eigentliche String hat. Wenn Du etwas Sinnvolles 
rausbekommen willst, dann so
1
char adcbuffer[5];
Das reicht dann für eine Vorkommastelle, den Dezimalpunkt und zwei 
Nachkommastellen (wie man die in integer berechnet, müsstest Du eben 
anhand des Artikels Festkommaarithmetik herausfinden). Und das itoa 
machste entweder in main oder Du gibst einen Zeiger auf den Buffer 
zurück.

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.