-
Guten Morgen!
So ich hatte nun die Möglichkeit meinen Vref Pin im Geschäft mit einem besseren Fluke Multimeter zu messen und siehe da, ich hatte auf einmal 2,473V Am Aref Pin. Ist zwar noch nicht ganz das was ich mir vorgestellt hab, aber ich denke das geht in Ordnung so. \:D/ \:D/
Jetzt bin ich dann schonmal einen großen Schritt weiter. Vielen Dank für die Hilfe!! [-o< [-o<
Grüße!!
Bean
PS.: Das nächste was ich mir kauf wird wohl ein neues Multimeter sein... :-)
-
Hab deinen Code mal auf CodeVision umgestrickt.
Er rechnet mit den vorgegebenen Werten richtig.
Stimmen deine vorgegebenen Konstanten ?
Code:
#include <mega8.h>
#include <stdlib.h>
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
#define F_CPU = 4000000UL
#define ad_nullwert 311
#define si_multiplyer 60
#define si_const 12
#define ADSC 6
#define ADEN 7
// uint16_t readADC(uint8_t); //Prototyp von readADC
// void display_temp(uint16_t result); //Prototyp von display
char buffer[8]; //Array für itoa anlegen
signed int uint16_t;
signed long int si_temp1; //Hilfvariable für Temperaturberechnung anlegen
signed long int si_temp2;
signed long int si_temp3;
signed long int si_ones;
signed long int si_komma;
void display_temp(unsigned int uint16_t)
{
lcd_init(16); //LCD initialisieren
lcd_gotoxy(0,0); //Cursor an erste Stelle setzen
lcd_putsf("Temp.:"); //"Temperatur" ausgeben
lcd_gotoxy(0,1); // Cursor in die zweite Zeile setzen
itoa(uint16_t,buffer); //AD-Wert umrechnen
lcd_puts(buffer); //AD-Wert in der zweiten Zeile ausgeben
lcd_gotoxy(0,9); // Cursor hinter "Temperatur:" setzen
//Berechnung der Temperatur
si_temp1= (uint16_t-ad_nullwert);
si_temp2= (si_temp1*si_multiplyer);
si_temp3= (si_temp2/si_const);
// Die Ganzen Grade Berechnen
si_ones=si_temp3/10;
//Die eine Nachkommastelle Berechnen
si_komma=si_temp3%10;
// Die Zehnerstellen ans Display ausgeben
itoa(si_ones,buffer);
lcd_puts(buffer);
lcd_putchar(',');
itoa(si_komma,buffer);
lcd_puts(buffer);
lcd_putchar(0xdf);
lcd_putchar('C');
}
int read_adc(unsigned char uc_channel)
{
unsigned char uc_i=0;
unsigned int ui_result;
//Den ADC aktivieren und Teilungsfaktor auf 32 stellen
ADCSRA = 0b10000101; //(1<<ADEN) | (1<<ADPS0) | (1<<ADPS2);
//Kanal des Multiplexers waehlen (ADC 0)
uc_channel &=0b00000111;
uc_channel |=0b11000000;
//interne Referenzspannung verwenden (also 2,56 V)
ADMUX = uc_channel;
//Den ADC initialisieren und einen sog. Dummyreadout machen
ADCSRA |= (1<<ADSC);
while(ADCSRA & (1<<ADSC));
//Jetzt 3x die analoge Spannung and Kanal channel auslesen
//und dann Durchschnittswert ausrechnen.
for(uc_i=0; uc_i<3; uc_i++)
{
// Eine Wandlung
ADCSRA |= (1<<ADSC);
// Auf Ergebnis warten...
while(ADCSRA & (1<<ADSC));
ui_result += ADCW;
}
//ADC wieder deaktivieren
ADCSRA &= ~(1<<ADEN);
ui_result /= 3;
return ui_result;
}
void main(void)
{
DDRB = 0xff; //PORT B als Ausgang
while (1)
{
//Auslesen der analogen Spannungen an Pin 0, also ADC0. In result steht das Ergebnis.
uint16_t = read_adc(0);
display_temp(uint16_t); //Umrechnung und Ausgabe der Temperatur auf Display und LED`s
}
}
Auf deinem C- Compiler wird aber das vermutlich nicht passen.
-
Hallo
Denke im Grunde auch dass das ganze so passt. Ich hab jetzt noch einmal versucht das ganze mit Eiswasser abzugleichen. Da ist mir als erstes aufgefallen dass wenn der Wert unter 0°C springt, dann das ganze als "minus füntausendirgendwas...." (Entschuldigt den ungenauen Wert, hab ihn mir leider nicht aufgeschrieben) angezeigt wird. Dann hab ich an si_const und si_multiplyer so lang rumgespielt bis ich genau 0° hatte. Nehme ich den Sensor aber nun aus dem Wasser heraus, so steigt das ganze recht schnell in die Höhe und zeigt mir bei Zimmertemperatur 30° an. Das kann ja nicht sein. Ich denke also dass die Kennlinie nun wieder zu steil eingestellt ist. Versuche das mit "spielen an den Werten" wieder weg zu bekommen.
Grüße!!
Bean
-
Lass doch dein Programm mal durch den Simulator im Einzelschrittmodus laufen und schau welcher Programmteil die Fehler produziert.
Da die Variablen im RAM seinsollten brauchst Du eigentlich nur nach den entsprechenden Rechenschritten die zugehörigen Speicheradressen auslesen und in Dezimal umrechnen.
Dann wird Dir schnell klar wo der Fehler liegt.
Hab noch mal ein wenig rumprobiert.
Der ad_nullwert hab ich als const signed long int definiert, dann berechnete er die negativen Werte richtig.
Ich hab jetzt noch ein kleines Problem mit den Nachkommastellen entdeckt, aber das kriegst Du dann ja noch selber raus.
-
Wieso macht ihr die Float<->char* Umwandlung so Kompliziert?
dtostrf ist dein Freund.
-
Hallo
Also bei meiner letzten Version sind das jetzt alles int Werte die berechnet werden. War nur am Anfang als die Berechnung mit float Werten gemacht wurde . :-b Kannst Deine dtostrf Funktion mal genauer beschreiben? Kenne die leider wie so vieles noch nicht. 8-[
Grüße!!
Bean
-
Okay. Typische Anwendung:
Code:
char str[6];
float f=1.341;
dtostrf(f,6,3,str);
lcd_puts((char*)str);
Grüße,
Simon