Forum: Mikrocontroller und Digitale Elektronik Temperaturmessung über UART ATMEGA16


von N. M. (mani)


Lesenswert?

Ein HALLO in die Runde,

ich habe ein Problem mit der Übertragung von float über den UART.
Am Anfang habe ich ein kleines Programm geschrieben das mir auf 
Tastendruck die ASCII-Tabelle anzeigt (um mal zu testen ob es überhaupt 
mal funktioniert).
Das ging auch wunderbar...also kann es mal nicht an der Übertragung 
liegen.

Anschliesend wollte ich etwas "größeres" machen:
Durch einen PT-100 fließt ein Konstantstrom von 10mA und erzeugt über 
diesem einen Spannungsabfall, den ich an ADC0 einlese.
Nach der Umrechnung in eine Temperatur soll diese in ASCII Zeichen 
konvertiert werden (dtostrf) und über den UART durch ein 
Konsolenprogramm(Hyperterminal) sichtbar gemacht werden.
Doch irgenwie kommt nur Müll raus! Ich habe schon ettliche Sachen 
versucht, aber ohne Erfolg...ist bestimmt irgendeine 
Kleinigkeit,trotzdem sehe ich es nicht.Ich hoffe mal einer von euch weis 
Rat?
Hardware: ATMEGA16L    Software: AVR-Studio v.4.13 / WinAVR-20071221
Die Libary libm.a für die Funktion dtostrf habe ich drin.

Hier mal der Code:
1
#include <avr/io.h>
2
#include <stdlib.h>
3
4
void adc_init (void)
5
{
6
  
7
    ADCSRA   |= (1<<ADEN)|(1<<ADPS2)
8
             |(1<<ADPS1)|(1<<ADPS0);  // Aktivierung ADC mit Prescaler 128 --> 8Mhz/128 = 62.5kHz
9
                  //Der Prescaler sollte zwischen 50-200kHz ergeben
10
  ADMUX = 0;            // Auswahl von ADC0 durch MUX
11
}
12
13
void ser_init (void)
14
{
15
  UCSRC|=(1<<URSEL)|(3<<UCSZ0);   //Asynchron 8N1
16
  UBRRH= UBRR_VAL>>8;        
17
  UBRRL= UBRR_VAL & 0xFF;      //Baudrate auf 9600 Bits/sek
18
19
}
20
21
22
int uart_putc(unsigned char c)
23
{
24
  while(!(UCSRA & (1<<UDRE))){;}; //Warten bis senden möglich
25
  UDR=c;
26
  return 0;
27
}
28
29
30
void uart_puts(char *temp_string)
31
{
32
  while (*temp_string!='\n')
33
  {
34
  uart_putc(*temp_string);
35
  temp_string++;
36
  }
37
}
38
39
40
int main(void)
41
{
42
  unsigned int i=0;
43
  char temp_string[10]={0,0,0,0,0,0,0,0,0,0};
44
  float spannung=0,temp=0,temp_insg=0;
45
46
  adc_init();
47
  ser_init();
48
  
49
50
  for(;;)
51
52
  {
53
    for(i=0;i<10;i++)
54
      {
55
      ADCSRA |= (1<<ADSC);      //Start conversion
56
      while (ADCSRA & (1<<ADSC) ) {;}  // wait until converstion completed
57
      
58
      spannung=(float)((5* ADCW)/1024);    //Umrechnen von Binär
59
      temp=(float)(((spannung-1))/0.00391); //Errechnen der Temperatur
60
      temp_insg=(float)temp_insg+temp;
61
      }
62
63
    temp_insg=(float)(temp_insg/10);        //Mittelwert errechnen
64
    dtostrf(temp_insg, 7, 3, temp_string);  //Zerlegung von temp_insg in String
65
    
66
    
67
    uart_puts(temp_string);          //senden des Strings
68
    uart_putc('\n');
69
70
    
71
72
  }
73
return 0;
74
}


Gruß Mani

von fusebit (Gast)


Lesenswert?

Am Rande: 10 mA sind zu viel für ein Pt100. Da wird der schon merklich 
warm...

von mani (Gast)


Lesenswert?

Du meinst von wegen eigenerwärmung durch den Strom ?

Ok, gutes Argument...was wäre da so normal ? 1mA?

Gruß

von Sven (Gast)


Lesenswert?

Hallo Mani,

falls Du diesen Thread noch nicht kennst solltest Du dies hier
auf jeden Fall lesen:

Beitrag "Temperaturmessschaltung möglichst genau?"

Wenn Du den PT100 auf jeden Fall verwenden willst, solltest Du auch
die Schaltung nachbauen.

Sonst wirst Du mit Deinen Ergebnissen nicht so glücklich werden.

Die Software habe ich mir jetzt nicht genauer angeguckt, da
Du aus meiner Sicht schon ein Problem mit der Verschaltung
des PT100 hast. (10mA sind zu viel...)

Wenn Du die Temperatur auf eine andere Weise messen willst,
gibt es eine einfache Möglichkeit mit einem NTC/PTC zu bauen
wirst Du hier unter anderem fündig:

http://www.mikrocontroller.net/articles/Temperatursensor

Gruß Sven

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

a) Was kommt den raus?
b) Hast du mal die "rohen" ergebnisse ausgegeben?

von mani (Gast)


Lesenswert?

@Sven:
Danke für die Links...gerade die Unterscheide der einzelnen
Temperatursensoren sind ziemlich interresant. Das ein PT100 nicht so 
ideal
ist (geringe Steigung) wusste ich...hatte aber gerade noch einen in der 
Kiste liegen
und dachte ich versuchs als Einstieg mal mit dem :-)

@Läubi:
a) Auf dem Hyperterminal bekomme ich etwa sowas ausgegeben: ccacssa....
b) Äääähm...was meinste damit genau? Versuche ja die "rohen" Daten als 
String
zu konvertieren und dann über den Uart auszugeben.
Meinste über JTAG?


Ich habe es auch schon ettliche male versucht mit dem AVR-Studio zu 
simulieren
(kam aber nur Mist raus).
Nach langem lesen hat sich dann herausgestellt dass ich anscheinend 
nicht alleine
bin und dass es allgemein schwierig ist sowas mit dem ATMEGA16 (evtl. 
auch andere) zu
simulieren!? (man möge mich verbessern wenn ich was falsches sage).

Ich habe auch schon die komplette temp. Messung in meinem Programm 
ausgeklammert
und als Wert eine konstante float Zahl eingetragen (z.B 25.65).
Aber irgendwie geht zwischen konvertierung von float in String (Array) 
bzw bei der
Übertragung etwas schief...so dass ich nur Buchstaben anstatt meiner 
Messwerte (Zahhlen) bekomme.

Die Funktionen uart_putc bzw. uart_puts hab ich aus dem Tutorial zu 
WinAVR.http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Schreiben_einer_Zeichenkette_.28String.29

Was könnte das den sein? Bei dem compilierung bekomme ich weder Fehler 
noch warnungen angezeigt.

Gruß

Mani

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

ADCW einfach mal über die Serielle schicken.
Also ohne Floatumrechnung.
Außerdem würd ich das so klammern, sonst geht dir doch der 
Nachkommanteil flöten. (ich weiß nicht wie genau das der Compiler 
handhabt!)
spannung=((float)(5* ADCW))/1024.0;    //Umrechnen von Binär

von mani (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Läubi,

danke für deine guten Tipps...mittlerweile "Funktioniert" es.
Waren allerdings 2 Fehler gleichzeitig :-)

Ich habe bei meinem vorherigen Programm das funktioniert hatte eine 
Wartezeit zwischen 2 Zeichen eingebaut, das war auch der Grund warum es 
funktioniert hat.
Als ich diese Wartezeit entfernt hatte ging DIESES Programm dann auch 
nicht mehr. Das hat mich dann etwas Stuzig gemacht. Hab mal den Quarz 
gewechselt und siehe da...es kam zumindest kein Schrott mehr dabei raus.
Genauer gesagt kam garnichts mehr...das war der 2.Fehler.Ich hatte 
vergessen das Flag TXEN (Sendefreigabe) zu setzen...peinlich,peinlich.

Es ist zwar nicht gerade ein Musterprogram, trotzdem hänge ich es mal 
mit an.

Gruß und vielen Dank nochmal.

Mani

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.