Forum: Mikrocontroller und Digitale Elektronik LMT84 Temperatursensor mit TI MSP430G


von Jörhg (Gast)


Lesenswert?

Hallo Leute,

ich brauche hilfe beim auslesen der analogen Werte des LMT84 Sensors.

Ich bekomme leider nur Mist raus (irgendwas zwischen 400 bis 600).


Hat jemand schonmal damit gearbeitet ?
1
ADC10CTL0 &= ~ENC; // disable ADC
2
ADC10CTL1 |= CONSEQ_0+ADC10SSEL_3+ADC10DIV_4; 
3
ADC10CTL0 = SREF_1 | ADC10SHT_3 | REFON | ADC10ON | ADC10IE;
4
ADC10AE0 = BIT0;
5
ADC10CTL0 &= ~ENC; //disable ADC
6
ADC10CTL1 |= INCH_5; //Select channel 0
7
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
8
while (ADC10CTL1 & BUSY); // wait
9
j = (unsigned int)ADC10MEM;
10
ADC10CTL0 &= ~ENC;

von Pete K. (pete77)


Lesenswert?

Datenblatt liegt vor? Aufbau korrekt?
500mV wären 95°C.

: Bearbeitet durch User
von Jörhg (Gast)


Lesenswert?

Ja das Datenblatt habe ich vor mir.

Zum Aufbau

Vom Launchpad zum Steckbrett gehen die Leitungen raus, wo der Sensor 
sitzt.

Es liegt wie es aussieht am ADC Wandler. Mit einem Multimeter gemessen 
am OUT Pin habe ich  898mV was  25°C ist.

Danke+ Gruß
Jörg

von Jörhg (Gast)


Lesenswert?

keiner einen Lösungsvorschlag?

Wäre über jede Hilfe wirklich dankbar

von wv (Gast)


Lesenswert?

Hallo Jörhg

das ist ein etwas spartanischer Code zum Testen. Hier wird der ADC 
initialisiert, macht genau eine Messung, schaltet dann den ADC ab und 
beendet das Programm.

- hängt der Sensor am P1.5?
- was steht denn in ADC10MEM nach Programmende?

Die Initialisierung schau ich mir gleich nochmal an, die muß ich erstmal 
auseinderdröseln. Spontan fällt mir auf, daß Du den ADC-Interrupt 
aktiviert hast aber offensichtlich keine ISR vorhanden ist.

Als nächste würde ich mir an Deiner Stelle 2 Funktionen basteln:

1. Initialisierung
2. Messung

und den Interrupt erstmal raus.

Die Messung würde ich mir zum Testen timergesteuert alle 0.5 Sec 
wiederholen lassen, dann kann man besser sehen ob man Mist mißt. Man 
kann dann auch mal statt des Sensors zur Kontrolle ein Poti dranhängen.

Gruß wv

von Jörhg (Gast)


Lesenswert?

Hallo wv

erst einmal Danke für deine Hilfe.

Du hast recht nen Interrupt will ich erst einmal nicht aufrufen. Er soll 
nur den Wert mir anzeigen.
Was mir auffällt ist das sich die Werte stark ändern.  Ich habe hier mal 
nen LM35DZ. Dort
existieren ebenfalls Abweichungen mit dem was ich hier am Multimeter 
raus habe und mit dem am ADC Eingang. Mit was kann das auf sich haben?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Lass' mal den Sensor weg und ersetze ihn durch ein simples Poti (ein 
paar kΩ, kommt nicht auf den genauen Wert an), das Du zwischen VCC und 
GND schaltest, und den Schleifer an Deinen ADC-Eingang.

Solange Du mit dem Aufbau kein stabiles und reproduzierbares Ergebnis 
erzielst, ist es müßig, sich weiter mit Sensoren zu beschäftigen.

Deinen Code zum Ansteuern des ADC hast Du den TI-Beispielen für Deinen 
Controller entnommen? Du schreibst praktischerweise nur "MSP430G", ist 
das der 'F2553, der dem Launchpad beiliegt, oder ein anderer?

von wv (Gast)


Lesenswert?

ich hab jetzt mal die Initialisierung angeschaut,

sollte für die ersten Test mal ok sein, aber ADC10IE sollte raus, oder 
Du schreibst eine ISR dazu.

Referenzspannung ist auf intern 1.5V d. h. in ADC10MEM sollte etwas in 
der Gegend von 612(dez) stehen. Es kann aber sein, daß die erste Messung 
sowieso für'n Eimer ist, da das Programm endet, bevor die 
Sample-and-Hold-Time abgelaufen ist. Ob er dann noch das Ergebnis 
korrekt reinschreibt, weiß ich nicht. Also umbauen auf mehrere Messungen 
hintereinander. Dann mal mit 'nem Poti testen.

Gruß wv

von Jörhg (Gast)


Lesenswert?

Hallo Rufus

Rufus Τ. F. schrieb:
> Du schreibst praktischerweise nur "MSP430G", ist
> das der 'F2553, der dem Launchpad beiliegt, oder ein anderer?

Ich habe den G2553. Leider suche ich grade wie verrückt nach einem Poti.
1
int j=0;
2
3
4
5
void main(void)
6
{
7
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
8
  ADC10CTL0 &= ~ENC; // disable ADC
9
  ADC10CTL1 |= CONSEQ_0+ADC10SSEL_3+ADC10DIV_4;
10
  ADC10CTL0 = SREF_1 | ADC10SHT_3 | REFON | ADC10ON ;
11
  ADC10AE0 = BIT5;
12
  ADC10CTL0 &= ~ENC; //disable ADC
13
  ADC10CTL1 |= INCH_5; //Select channel 0
14
15
16
  while(1){
17
  ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
18
  while (ADC10CTL1 & BUSY); // wait
19
  j = (unsigned int)ADC10MEM;
20
  j= (1.5*(int)j);
21
  j= j* 100;
22
  j= j/1024;
23
  ADC10CTL0 &= ~ENC;
24
}
25
26
}

von Jörhg (Gast)


Lesenswert?

Also die Zeilen
1
j= (1.5*(int)j);
2
  j= j* 100;
3
  j= j/1024;

können auskommentiert werden ( Wandlung auf °C ).

Aber ich habe leider keinen Poti gefunden :(.

Den Code wollte ich nun auf den LMT84 adaptieren.

von Jörhg (Gast)


Lesenswert?

wv schrieb:
> Referenzspannung ist auf intern 1.5V d. h. in ADC10MEM sollte etwas in
> der Gegend von 612(dez) stehen. Es kann aber sein, daß die erste Messung
> sowieso für'n Eimer ist, da das Programm endet, bevor die
> Sample-and-Hold-Time abgelaufen ist. Ob er dann noch das Ergebnis
> korrekt reinschreibt, weiß ich nicht. Also umbauen auf mehrere Messungen
> hintereinander. Dann mal mit 'nem Poti testen.

Ja ich habe im ADC10MEM  eine 600 stehen. Im multimeter wird mir 885 
angezeigt.

von wv (Gast)


Lesenswert?

Hallo Jörg

da läut ein bißchen was schief:

>j = (unsigned int)ADC10MEM;
warum nicht gleich als unsigned int definieren?
>j= (1.5*(int)j);
die rechte Seite wird zum float, der dann einem unsigned int zugewiesen 
wird. Die Nachkommastellen werden abgeschnitten. Rechne doch besser mit 
1500mV Referenzspannung
>j= j* 100;
statt der  abgeschnittenen Nachkommastellen werden 2 Nullen angehängt
>j= j/1024;
und das wird dann ganzzahlig durch 1024 geteilt......
>ADC10CTL0 &= ~ENC;
hier schaltest Du wieder die Messung aus.
Mach doch lieber mit ADC10CTL0 |= ADC10SC; eine neue Messung und setz 
mit dem Debugger einen Breakpoint drauf. Dann kann man sich mehrere 
Ergebnisse ansehen und die Werte vergleichen.

Gruß wv

P.S.: Wenn Du kein Poti findest, dann setz doch mal den P1.5 auf GND.

von wv (Gast)


Lesenswert?

>Ja ich habe im ADC10MEM  eine 600 stehen. Im multimeter wird mir 885
>angezeigt.

das sieht doch gut aus, rechnerisch ergäbe sich 603.

Trotzdem würde ich das erstmal mit mehreren Messungen verifizieren, 
sowas kann auch mal Zufall sein.

Bau Dir doch erstmal eine Umrechnung in mV ein, dann kann man mit dem 
Multimeter vergleichen.

Gruß wv

von Jörhg (Gast)


Lesenswert?

Hallo wv,

also irgendwie verstehe ich nicht wieso der Multimeter mir 885 und mein 
Chip hier  600 ausliest.
Wenn ich aufs Datenblatt ein Blick werfe, dann wären 602 mV 78°C.

wv schrieb:
>>j = (unsigned int)ADC10MEM;
> warum nicht gleich als unsigned int definieren?
>>j= (1.5*(int)j);
> die rechte Seite wird zum float, der dann einem unsigned int zugewiesen
> wird. Die Nachkommastellen werden abgeschnitten. Rechne doch besser mit
> 1500mV Referenzspannung
>>j= j* 100;
> statt der  abgeschnittenen Nachkommastellen werden 2 Nullen angehängt
>>j= j/1024;
> und das wird dann ganzzahlig durch 1024 geteilt......
>>ADC10CTL0 &= ~ENC;

Super danke für die Tipps die nehme ich an mich :D.

Aber woran könnte das liegen das ich da so ein Wert raus habe?

von Jörhg (Gast)


Lesenswert?

Also  ein Beispiel :

600 Habe ich ja im ADC. Vref sind  1,5V. Und es handelt sich ja hier um 
einen 10BIT ADC.

Also

V = 1,5V * 600/1024 ergibt 0,879.

ist die Rechnung korrekt ?

von wv (Gast)


Lesenswert?

>V = 1,5V * 600/1024 ergibt 0,879.

>ist die Rechnung korrekt ?

fast, Du muß durch 1023 teilen, denn das ist der höchste Wert, den ein 
10-Bit Wandler ausgibt.

Gruß wv

von Jörhg (Gast)


Lesenswert?

Danke wv :D

Aber ich habe noch eine Frage.

Und zwar komme ich nicht drum herum Kommazahlen zu verwenden.

Gibt es da nen geschickten Trick ?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Jörhg schrieb:
> Gibt es da nen geschickten Trick ?

Ja. Ganzzahlen verwenden, indem Du mit dem hundertfachen rechnest, und 
bei der Ausgabe ein Dezimalkomma einschmuggelst.

Andererseits: Der 'G2553 hat 16 kiB Flash, so daß Du auch problemlos 
floating-point-Arithmetik nutzen kannst. Solange Du keine gesteigerten 
Anforderungen an Rechenzeit hast (d.h. Deine Umwandlung besonders 
schnell werden muss) und Du keine Platzprobleme im Flash hast, spricht 
nichts dagegen. Du kannst schließlich unbenutztes Flash im µC nicht 
zurückgeben ...

von Jörhg (Gast)


Lesenswert?

Also
1
volatile  unsigned long  int tempextern;
2
3
4
void main(void)
5
{
6
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
7
8
9
  ADC10CTL0 &= ~ENC; // disable ADC
10
  ADC10CTL1 |= CONSEQ_0+ADC10SSEL_3+ADC10DIV_4;
11
  ADC10CTL0 = SREF_1 | ADC10SHT_3 | REFON | ADC10ON ;
12
  ADC10AE0 = BIT5;
13
  ADC10CTL0 &= ~ENC; //disable ADC
14
  ADC10CTL1 |= INCH_5; //Select channel 0
15
16
17
  while(1){
18
  ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
19
  __delay_cycles(50);
20
  while (ADC10CTL1 & BUSY); // wait
21
  tempextern = (unsigned int)ADC10MEM;
22
23
  tempextern = (1500*tempextern);
24
       //   tempextern= tempextern * 100;
25
_no_operation();
26
  tempextern= tempextern/1023;
27
  ADC10CTL0 &= ~ENC;
28
}
29
30
}

Ich komme leider immernocht nicht auf die mV wie auf dem Multimeter.

Abweichung von teilweise 10 bis 30 mV.

von wv (Gast)


Lesenswert?

>Abweichung von teilweise 10 bis 30 mV.

über den ganzen Bereich getestet? Dann bist Du doch schon dicht dran. 1 
Bit bei einem 10Bit ADC und 1.5V Referenz entsprechen etwa 2mV, also 
etwas genauer sollte es noch gehen. Die Ganzzahlrechnung kann man noch 
verbessern in dem man vor der Division noch mit 10 multipliziert, 5 
addiert, und wieder durch 10 dividiert. Dann hast Du kaufmännische 
Rundung auf der letzten Stelle.

Dann hat der MSP2553 noch Kalibrierungswerte für den ADC im InfoMEMA 
stehen. Die kann man dann auch noch in die Rechnung mit einbeziehen 
(Datenblatt Table 10+11 und FamilyUserGuide Chapter24 TLV-structure).

Gruß Wolfgang

von wv (Gast)


Lesenswert?

noch etwas:

>ADC10CTL0 &= ~ENC;

ersetz doch die letzte Zeile durch

ADC10CTL0 |= ADC10SC;

und setz einen Breakpoint drauf. Dann hast Du eine Endlosschleife, wo er 
nur Messungen macht. In Deiner jetzigen Version wird unmittelbar nach 
der Initialisierung gemessen, es könnte sein daß da die Referenzspannung 
noch nicht auf dem richtigen Wert steht.

Gruß wv

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.