Temperaturmessung mit dem R8C/13

Software und Quellcodes für Microcontroller

Software und Quellcodes für Microcontroller

Moderator: Moderatorengruppe

Re: Temperaturmessung mit dem R8C/13

Neuer Beitragvon derguteweka am Dienstag 13. November 2012, 18:09

Moin,

Frage 1+2: Durch eine geaenderte Ausgabefunktion, z.b. so:
Code: Alles auswählen
void lcd_integer (signed int data)
{
        unsigned char byt;
        unsigned char fnu=0; //fuehrendeNullunterdrueckung
        lcddata((data<0)?'-':' '); //vorzeichenausgabe
        data=data<0?-data:data; // absolutbetrag

        byt = data / 1000;
        data = data - byt * 1000;
        if ((fnu) || (byt!=0))
        {
          lcddata(byt + 48);
          fnu=1;
        }
        byt = data / 100;
        data = data - byt * 100;
        if ((fnu) || (byt!=0))
        {
          lcddata(byt + 48);
          fnu=1; // nur, falls weiter 0en unterdrueckt werden sollten
        }
        byt = data / 10;
        data = data - byt * 10;
        lcddata(byt + 48);
        lcddata('.');
        lcddata(data + 48);
}


Obacht, der Name der Funktion ist jetzt natuerlich Kappes. Ihr Argument hat sich auch geaendert: Sie nimmt jetzt eine vorzeichenbehaftete Integer - fuer wenns kalt wird...

Gruss
WK
derguteweka
48735
Moderator
 
Beiträge: 1043
Registriert: Freitag 18. August 2006, 15:47

Re: Temperaturmessung mit dem R8C/13

Neuer Beitragvon Menson am Mittwoch 14. November 2012, 14:58

Ja passt auf anhieb :lol:

Alles wie erwartet - voranstehende Null(en) werden nicht angezeigt, Kommapunkt ist auch richtig.

Danke mal bis hierher.

Damit gebe ich mich aber noch nicht zufrieden ;-)
Bei fast jeder Messung ändert sich der Messwert um 0,5°C. Er wechselt so also zB zwischen 19,6 / 20,1 / 20,6.
Dies ist natürlich nicht gewünscht.

Nun dachte ich daran, dass man nicht jede Messung ans Display weitergibt. Sondern die einzelnen Messungen in einer Variablen addiert. Wenn zB 10 Messungen erreicht sind, wird die Variable durch 10 dividiert und erst dann ans Display übergeben. So habe ich den Mittelwert von 10 Messungen. Dadurch verbessert sich auch noch die Auflösung der Anzeige.

Wie kann ich aber mit den Messwerten rechnen - also addieren?

lg, Menson
Menson
Threadstarter
48755
Bronze Mitglied
 
Beiträge: 37
Registriert: Mittwoch 12. November 2008, 19:35

Re: Temperaturmessung mit dem R8C/13

Neuer Beitragvon derguteweka am Mittwoch 14. November 2012, 16:50

Moin,

Na, welch eine Ueberraschung :D
Allgemein: Addieren kann man Messwerte und alles moegliche andere in C mit Hilfe des Pluszeichens...
Speziell: Das was du vorhast, kann man wahrscheinlich ausreichend schlecht mittels eines simplen Digitalfilters (genauer: IIR-Filter :shock: ) machen; z.B. so:

Eine neue Funktion kommt dazu:
Code: Alles auswählen
float filter(float t)
{
  static float m;
  return m=m*0.95+t*0.05;
}


Die Uebergabe des gemessenen Werts an das LCD ist dann nicht mehr wie vorher
Code: Alles auswählen
lcd_integer(x);
sondern
Code: Alles auswählen
lcd_integer(filter(x));


Die Koeffizienten 0.95 und 0.05 beeinflussen das Verhalten des Filters. Sollten in der Summe immer 1.0 ergeben, sonst kann das Filter instabil werden oder seine Verstaerkung aendern.

Gruss
WK
derguteweka
48758
Moderator
 
Beiträge: 1043
Registriert: Freitag 18. August 2006, 15:47

Re: Temperaturmessung mit dem R8C/13

Neuer Beitragvon Menson am Mittwoch 14. November 2012, 20:08

Vielen Dank für deine Hilfe.

Das mit dem Filter versteh ich nicht so ganz. Es funktioniert zwar irgendwie, aber das mit dem Koeffizienten versteh ich nicht.

Ich meinte das so:
Code: Alles auswählen
   long int s;            // Deklaration: Summe
   int count;            // Deklaration: Counter (zählt von 0 bis 10)

   if (count < 10){      // 10 mal durchlaufen
     s = s + u;         // Summe = Summe + Messwert
     count = count + 1;   // Counter zählt um 1 hoch
     goto ende;}         // Gehe zu Sprungmarke am Ende der Funktion
     else{
     u = s/10;            // nach 10 Durchläufen Mittelwert berechnen (Summe/10)
     count = 0;         // Counter auf Null setzen
     s = 0;}            // Summe auf Null setzen
                       // Funktion läuft weiter und gibt den gemittelten
                     // Messwert an das Display


Blos wird der Wert "u" nicht wie erwartet addiert, sondern die Zahlen werden hintereinander geschrieben. Somit entsteht eine Zahlenkolonne. zB: die Summe von 16.1 + 16.1 ist nicht 32.2, sondern 16.1 16.1 usw.

lg
Menson
Threadstarter
48762
Bronze Mitglied
 
Beiträge: 37
Registriert: Mittwoch 12. November 2008, 19:35

Re: Temperaturmessung mit dem R8C/13

Neuer Beitragvon derguteweka am Mittwoch 14. November 2012, 20:30

Moin,

Der Codeschnipsel ist ein bisschen knapp gehalten, um da qualifiziert was sagen zu koennen.
So ausm Bauch raus und allgemein:
* Vorsicht beim umwandeln von float nach integer, da geht Genauigkeit verloren.
* Guck' dir mal an, wie man mit einer for-schleife programmiert, also sowas:
Code: Alles auswählen
for(i=0;i<10;i++){bla();}

* Du bist arg sparsam mit Variablen, das u ist bei deiner Funktion oft der Eingangswert und manchmal der
Ausgangswert
* goto ist boese :mrgreen:
* Mehrfacher output von Zahlen auf dem LCD kommt wahrscheinlich daher, weil das LCD nicht schnallt, das es von vorne anfangen soll - mit der Funktion lcd_pos(2,4) koennte da was gehen.

Aber sonst und grundsaetzlich wuerde deine Idee der Mittelwertbildung schon funktionieren. Ist halt mehr Aufwand als das IIR Filter. Das laeuft aber ganz aehnlich - da wird auch aufsummiert, aber weil da nicht nach N samples direkt die Summe wieder zurueckgesetzt wird, laesst man die Vergangenheit (also die Summe von alten Werten) ueber einen Koeffizienten (hier die 0.9x) langsam immer weiter schrumpeln.
Schaltungstechnisch entspricht das einem klassischen, simplen RC-Tiefpass.

Gruss
WK
derguteweka
48763
Moderator
 
Beiträge: 1043
Registriert: Freitag 18. August 2006, 15:47

Re: Temperaturmessung mit dem R8C/13

Neuer Beitragvon Menson am Donnerstag 15. November 2012, 06:57

Hallo

Wenn das so ist, dann belass ich es bei dem Filter. Alles muss ich ja nicht verstehen ;-)

Dann gehen wir gleich mal das nächste und auch letzte Problem an:
Ich muss den angezeigten Wert im Display in drei Teile zerlegen! Wenn zB 19.6° angezeigt werden in (1) in (9) und in (6). Jeweils in eine eigene Variable.
tz (für Temperatur Zenerstelle) ist also = 1
te (für Temperatur Einerstelle) ist also = 9
und tk (für Temperatur Kommastelle) ist = 6

Hintergrund dieser Aktion ist der, dass ich die einzelnen Werte an eine 7-Segment-Anzeige weitergeben will. Und dazu brauchts die einzelnen Zahlen.

Als welcher Datentyp müssen die Variablen deklariert werden ? Da der Wert nur zwischen 0 und 9 liegen kann, müsste "unsigned char" das richtige sein !?

Aber wie nun die Werte in die Variablen bekommen ?

lg, Menson
Menson
Threadstarter
48765
Bronze Mitglied
 
Beiträge: 37
Registriert: Mittwoch 12. November 2008, 19:35

Re: Temperaturmessung mit dem R8C/13

Neuer Beitragvon derguteweka am Donnerstag 15. November 2012, 16:56

Moin,

Das zerlegen ist nicht schwer, das passiert ja bereits in der ldc_integer() Funktion Dort wird ja ein paar mal die lcd_data() Funktion aufgerufen, mit genau den Daten, die du haben willst.
Ich halt's aber fuer sinnvoller, wenn du die Hosen nicht so scheibchenweise runterlaesst, sondern mal ganz. Dann ist es einfacher, dafuer ne Loesung zu finden, als wenn man immer so scheibchenweise rumwurstelt.
Bei mehrern 7 Segmentanzeigen biste gleich am multiplexen und da wirds auch entscheidend sein, wie die genau an den Prozessor angeflanscht sind, etc.
Also : Was soll das Dingens am schluss alles koennen, haste n Schaltbild von dem Apparat mitsamt den LEDs und aller Treiberhardware?

Gruss
WK
derguteweka
48768
Moderator
 
Beiträge: 1043
Registriert: Freitag 18. August 2006, 15:47

Re: Temperaturmessung mit dem R8C/13

Neuer Beitragvon Menson am Donnerstag 15. November 2012, 17:20

Also eigentlich bedarf es nicht mehr als ich bereits geschrieben habe.
Vor etwa einem Jahr hab ich mir mit dem R8C/13 eine digitale Uhr [00:00] gebastelt. Mit vier großen LED-7-Segment-Anzeigen. Die Uhr hängt bei mir unterm Flugdach und funktioniert bisher ganz super. Sogar die Genauigkeit läßt (für selbstbau und ohne DCF77) kaum Wünsche offen.
Nun ist mir in den Sinn gekommen, diese Uhr mit einer Temperaturanzeige zu erweitern. Schlussendlich soll die Zeit angezeigt werden, und so etwa alle 10 oder 15 Sekunden mal für ein oder zwei Sekunden die Temperatur.
Das hab ich auch schon damals bei Bau der Uhr im Sinn gehabt, habs aber nicht hinbekommen. Somit ist es erstmal nur bei der Uhr geblieben.
Die Uhr wird mit PWM getaktet. Also dass ist schon mal OK so. Die Erweiterung benötigt also blos die Temperatur-Funktion. Mit dem Zeitsignal kann ich dann beliebig zwischen Uhr- und Temperatur-Funktion hin- und herschalten.

Heute hab ich aber ein ganz anderes Problem entdeckt. Und zwar bin ich mal mit dem LCD-Thermometer (immer noch auf Steckplatte) nach draußen gegangen. Heute Morgen waren 0.9°C am Funktermometer zu lesen. Mein selbstgebautes auf der Steckplatte lies sich davon aber nicht beeindrucken und zeigte stoltze 13.1°C an.
Nun weis ich nicht ob das evetl. an dem 'Filter' liegt oder an sonst was. Leider hatte ich heute keine Zeit mehr mich näher mit dem abweichenden Messwert zu beschäftigen. Weis nicht ob ich morgen dazukomme. Der Sensor ist neu und kann ja nicht so schief liegen. Deshalb bin ich etwas in Sorge. Das Thermometer soll in späterer Verwendung doch einen relativ brauchbaren Wert anzeigen. Beim Funkthermometer wird auch +-1°C als Abweichnung angegeben. Damit kann ich leben, aber mit 12°C nicht :(
Also gibt es zu aller erst mal die Genauigkeit zu behandeln, ansonst macht das ganze ja keinen Sinn.

Hast du ne Idee, woher der Anzeigefehler rührt ?

lg, Menson
Menson
Threadstarter
48769
Bronze Mitglied
 
Beiträge: 37
Registriert: Mittwoch 12. November 2008, 19:35

Re: Temperaturmessung mit dem R8C/13

Neuer Beitragvon derguteweka am Donnerstag 15. November 2012, 17:54

Moin,

OK, wie siehts dann mit der fuehrenden Nullunterdrueckung aus? Was soll dann in der Variablen tz stehen, wenn eine Null unterdrueckt werden soll?
(Wie) Kannst du das Vorzeichen auch irgendwie auf den LED Anzeigen darstellen?

Warum deine Temperatur nicht stimmt, kann ich bei der Informationslage nun nicht wirklich beurteilen. Nimm halt mal ein Voltmeter und die dicken Handschuhe und mess' die Ausgangsspannung des Sensors bei verschiedenen Temperaturen - kann die zur Temperatur passen? Dann nimm die urspruengliche lcd_integer() Funktion und gib den Wert des ADC aus - passt der zur Temperatur, bzw. der Eingangsspannung am ADC Pin? Sind auf dem Board irgendwelche Bauteile, die ein bisschen Leistung umsetzen und so die Platine erwaermen (z.b. Spannungsversorgung) ? 0.5W kann da schon ziemlich viel sein...

Gruss
WK
derguteweka
48770
Moderator
 
Beiträge: 1043
Registriert: Freitag 18. August 2006, 15:47

Re: Temperaturmessung mit dem R8C/13

Neuer Beitragvon Menson am Donnerstag 15. November 2012, 18:22

OK, wie siehts dann mit der fuehrenden Nullunterdrueckung aus? Was soll dann in der Variablen tz stehen, wenn eine Null unterdrueckt werden soll?


Die Zehnerstelle bleibt dann eben aus wenn zB nur 5°C zu Messen sind. So dass eben nicht 05.x°C angezeigt wird.

(Wie) Kannst du das Vorzeichen auch irgendwie auf den LED Anzeigen darstellen?

Ja kann ich. Hab den Quellcode der Uhr jetzt aber nicht im Kopf - aber das gekomm ich schon noch hin. Zuerst muss mal alles andere laufen ;-)

Warum deine Temperatur nicht stimmt, kann ich bei der Informationslage nun nicht wirklich beurteilen. Nimm halt mal ein Voltmeter und die dicken Handschuhe und mess' die Ausgangsspannung des Sensors bei verschiedenen Temperaturen - kann die zur Temperatur passen? Dann nimm die urspruengliche lcd_integer() Funktion und gib den Wert des ADC aus - passt der zur Temperatur, bzw. der Eingangsspannung am ADC Pin? Sind auf dem Board irgendwelche Bauteile, die ein bisschen Leistung umsetzen und so die Platine erwaermen (z.b. Spannungsversorgung) ? 0.5W kann da schon ziemlich viel sein...


Schon klar - mach ich sobald ich Zeit dafür habe.
An der Steckplatte ist nichts was sich erwärmen könnte. Stromversorgung ist verbaut.

Ich melde mich sobald ich Vergleichswerte habe.
Danke mal bis hier hin. :sm12:

lg, Menson
Menson
Threadstarter
48773
Bronze Mitglied
 
Beiträge: 37
Registriert: Mittwoch 12. November 2008, 19:35

Re: Temperaturmessung mit dem R8C/13

Neuer Beitragvon derguteweka am Donnerstag 15. November 2012, 18:45

Moin,

Menson hat geschrieben:
OK, wie siehts dann mit der fuehrenden Nullunterdrueckung aus? Was soll dann in der Variablen tz stehen, wenn eine Null unterdrueckt werden soll?


Die Zehnerstelle bleibt dann eben aus wenn zB nur 5°C zu Messen sind. So dass eben nicht 05.x°C angezeigt wird.

Ist mir klar. Daher frug' ich auch: "Was soll dann in der Variablen tz stehen, wenn eine Null unterdrueckt werden soll?" - und nicht: Was soll passieren bei Temperaturen < 10° oder was nicht...

So koennte man die einzelnen Werte aus einer umgestrickten lcd_integer() funktion rausziehen - hab' ich aber nicht getestet:

Irgendwo am Anfang diese Variablen deklarieren:
Code: Alles auswählen
unsigned char vz,tz,te,tk;

Dann spaeter, statt dem original lcd_integer() Aufruf dann dieser hier:
Code: Alles auswählen
lcd_integer(filter(x),&vz,&tz,&te,&tk);

Die lcd_integer() sieht mittlerweile so aus:
Code: Alles auswählen
void lcd_integer (signed int data,
                  unsigned char * vzp,
                  unsigned char * tzp,
                  unsigned char * tep,
                  unsigned char * tkp)
{
        unsigned char byt;
        unsigned char fnu=0; //fuehrendeNullunterdrueckung
        lcddata((data<0)?'-':' '); //vorzeichenausgabe
        *vzp=(data<0)?1:0;
        data=data<0?-data:data; // absolutbetrag

        byt = data / 1000;
        data = data - byt * 1000;
        if ((fnu) || (byt!=0))
        {
//          lcddata(byt + 48);
          fnu=1;
        }
        byt = data / 100;
        *tzp=byt;
        data = data - byt * 100;
        if ((fnu) || (byt!=0))
        {
//          lcddata(byt + 48);
          fnu=1; // nur, falls weiter 0en unterdrueckt werden sollten
        }
        byt = data / 10;
        *tep=byt;
        data = data - byt * 10;
//        lcddata(byt + 48);
//        lcddata('.');
        *tkp=data;
//        lcddata(data + 48);
}


Damit kriegst du die einzelnen Werte der Ziffern in die variablen. Wenn vz auf 1 gesetzt ist, musst du das minus im Display anschalten.

Gruss
WK
derguteweka
48774
Moderator
 
Beiträge: 1043
Registriert: Freitag 18. August 2006, 15:47

Re: Temperaturmessung mit dem R8C/13

Neuer Beitragvon Menson am Freitag 16. November 2012, 08:18

"Was soll dann in der Variablen tz stehen, wenn eine Null unterdrueckt werden soll?"

Da soll die "0" drin stehen - das mach ich dann mit ner If-Anweisung. If (tz=0){Display aus}.

Aber als erstes mach ich mich mal an das Messergebnis - damit das mal ne ordentliche Temperatur anzeigt.
Habe eben mal mit dem DMM am Sensor gemessen, und der gibt schon eine wesentlich höhere Spannung aus als er eigentlich soll. Hab den Ausgang mit 100k gegen Masse belastet. Vielleicht ist das zu wenig. Vielleicht braucht der einen kleineren Abschlusswiderstand oder der Sensor ist defekt. Muss mal im Datenblatt nachschauen.

Messwerte:
Temperatur eines Vergleichsthermometers = 17.5°C
Ausgangsspannung des LM61C = 778mV
entspricht 17.8°C (wäre also ok)
LCD zeigt an: 18.6°C

Temperatur eines Vergleichsthermometers = 3.8°C
Ausgangsspannung des LM61C = 746mV
entspricht 14.6°C (nicht mehr ok)
LCD zeigt an: 14.8°C

Warum die Ausgangsspannung des LM61C so weit von der zu erwartenden Spannung abweicht muss ich erst mal klären. Jetzt hab ich noch ein paar Termine, aber vllt. hab ich am Abend noch ein wenig Zeit dafür ...

lg, Menson
Menson
Threadstarter
48777
Bronze Mitglied
 
Beiträge: 37
Registriert: Mittwoch 12. November 2008, 19:35

Re: Temperaturmessung mit dem R8C/13

Neuer Beitragvon Menson am Montag 19. November 2012, 13:20

Hallo

Musste das WE über unerwartet in der Klinik bleiben, deshalb kann ich mich erst heute melden.

Hab mich gleich ans Messen der Ausgangsspannung des Tempsensors gemacht.
Gleich vorweg: Ganz klar sehe ich nicht!

Messwerte:
Temperatur eines Vergleichsthermometers = 17.7°C
Ausgangsspannung des LM61C = 790mV
entspricht 19.0°C
LCD zeigt an: 19.5°C

Temperatur eines Vergleichsthermometers = 5.2°C
Ausgangsspannung des LM61C = 689mV
entspricht 8.9°C
LCD zeigt an: 10.3°C

Eigentlich hatte ich erwartet, dass der Tempsensor etwas näher an die gemessene Temperatur rankommt. Obwohl ich hier ja auch wieder +-1°C einräumen muss, da es sich beim Vergleichsthermometer um kein geeichtes Gerät handelt.

Bedenklich finde ich aber, dass die am ADC liegende Gleichspannung vom µC nicht korrekt am LCD wiedegegeben wird. Das zeigt doch einen eindeutigen Rechenfehler an. Wenn am ADC-Eingang 689mV liegen, davon werden rechnerisch 600mV subtrahiert, dann bleiben nur noch 89mV (8.9°C) übrig - und nicht 103mV (10.3°C).
Fakt ist, dass ich bei 5°C realer (!) Temperatur 10°C am Display angezeigt bekomme. Und dass kanns ja wohl nicht sein.

Vielleicht habe ich das Datenblatt vom LM61C falsch interpretiert. Englisch-Kenntnisse sind kaum vorhanden. Jedenfalls finde ich keinen plausieblen Grund für diese Abweichung.

Ich häng mal das Datenblatt des LM61 an.
Womöglich mach ja ich irgendwo einen Fehler.

P.S.
Die Versorgungsspannung des LM61 ist gleich die Versorgungsspannung des µC und beträgt 5V. Sie wird von einem LP2950-5.0 erzeugt. Damit wird mein Board versorgt. Bislang hatte ich damit noch keine Probleme. Sollte also ausreichend stabil sein.

lg, Menson
Sie haben keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.
Menson
Threadstarter
48827
Bronze Mitglied
 
Beiträge: 37
Registriert: Mittwoch 12. November 2008, 19:35

Re: Temperaturmessung mit dem R8C/13

Neuer Beitragvon anders am Montag 19. November 2012, 14:08

Bedenklich finde ich aber, dass die am ADC liegende Gleichspannung vom µC nicht korrekt am LCD wiedegegeben wird.
Dann solltest du dich zunächst um dieses Problem kümmern.

Nimm dir ein Poti und ein Digitalvoltmeter, so daß du verschiedene Spannungen einstellen kannst, und schreib dir eine Routine, die den Messwert ohne großartige Weiterverarbeitung ins Display schreibt. Am Besten binär, also nur das Datenwort, so wie es vom ADC kommt, durch Maskieren in Einsen und Nullen (= T / F ) zerlegen, und deren ASCII-Darstellung ins Display schreiben.

Die Kontrolle kannst du mit dem Taschenrechner machen. Auch der in Windows eingebaute beherrscht die Umwandlung von Binär in Dezimal.

Wenn du zu der Ansicht kommst, dass der ADC fehlerfrei arbeitet, kannst du die Fehler in deinem Programm suchen, sonst musst du eben den Hardwarefehler lokalisieren, evtl. auch einen neuen µC verwenden.
anders
48828
Moderator
 
Beiträge: 3968
Registriert: Freitag 28. Februar 2003, 13:46

Re: Temperaturmessung mit dem R8C/13

Neuer Beitragvon Menson am Dienstag 20. November 2012, 08:06

Nimm dir ein Poti und ein Digitalvoltmeter, so daß du verschiedene Spannungen einstellen kannst, und schreib dir eine Routine, die den Messwert ohne großartige Weiterverarbeitung ins Display schreibt.



Hallo "anders"

Mit dem Routine-Schreiben hab ichs nicht so, wie du weiter oben lesen konntest.

Hab aber das mit dem Poti und dem DVM mal so gemacht. Den Code nur leicht abgeändert, so dass das LCD die Eingangsspannung in mV anzeigt (das Dezimalkomma mal weggedacht).
Der Code sieht nun so aus:

Code: Alles auswählen
   float u;
   u = (float) ad_in(6);
   u = u / 1023.0 * 5.0;

   lcd_integer(filter(1000*u));


Die Messung hat folgendes ergeben:
DVM = 1038mV / LCD = 1089mV
DVM = 2015mV / LCD = 2038mV
DVM = 3000mV / LCD = 3045mV
DVM = 4021mV / LCD = 4080mV
DVM = 4918mV / LCD = 4990mV

Das LCD zeigt also rund 50mV mehr an als das DVM. Das kann durchaus ein Messfehler vom DVM sein. Also alles im grünen Bereich. Der ADC arbeitet also mal korrekt, so wie ich dass sehe.

Was mir allerdings bei der Messung aufgefallen ist:
Beim Verändern der Spannung am Poti, pendelt sich das DVM sehr schnell auf die neue Spannung ein. Das LCD hingegen braucht bestimmt 10 Sekunden um einigermaßen zur Ruhe zu kommen. Liegt das an dem Filter oder am ADC generell?

lg, Menson
Menson
Threadstarter
48842
Bronze Mitglied
 
Beiträge: 37
Registriert: Mittwoch 12. November 2008, 19:35

VorherigeNächste

Zurück zu Software

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast