Forum: Mikrocontroller und Digitale Elektronik Nur ganze Zahlen? Wie Fliesskoma?


von Fox (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen

So habe Hilfe eines bestehenden Beitrages das Display DIP-204-4 zu 
laufen gebracht! JUHU! (siehe 
Beitrag "LCD EA DIP204-4 Initialisieren") Vielen Dank für das 
Hinaufstellen  Jochen A. (neurotoxer).

Jetzt habe ich ein kleines Problem. Integer sind ja ganze Zahlen. Die 
Temperatur wird umgerechnet und anschliessend als ganze Zahl ausgegeben. 
Wie bekomme ich da ein Komma über? also z.B. 23.1°C???


Dann habe ich noch eine Frage: Wieso bekomme ich negative Zahlen, wenn 
ich den ADCW-Wert / 1024 * 150 rechne? Oder gar keine Zahl je nach 
Anordnung? Wenn ich aber mache 150/1024 = 0.1465 daher die Umwanldung 
auf die Temperatur value = value * 0.1465; funktioniert es.

150°C habe ich bei 1024 Bit.

Danke und Gruss Fox



1
#include <avr/io.h>
2
#include "display.h"
3
#include <stdlib.h>
4
5
#define F_CPU 8000000UL     /* Quarz mit 8.0Mhz */
6
#include <util/delay.h>
7
8
int main(void){
9
//  DDRC=0b00000001;    //led an PC0
10
  display_init();
11
  display_ptext("Display EA-DIP204-4",1,0);     //erstes Koma = Reihe  zweites Koma = Zeichenabstand von links
12
  display_ptext("mit ATMega8",2,0);
13
  display_ptext("Version 1.0",3,0);
14
  display_ptext("Temperaturmessung",4,0);
15
  //Endlosschleife
16
17
18
19
   DDRC = 0b11111100;            //
20
   PORTC = 0b0000000;             //
21
22
23
  ADMUX = 0;        // Für interne Referenzspannung   ADMUX = 0b11000000;
24
                          // auch ADMUX = 2; (Kanalnummer) oder ADMUX = 0b00000010;
25
  ADCSRA = 1<<ADEN | 1<<ADPS2 | 1<<ADPS1 | 1<<ADPS0;    // Initialisierung des ADC über das ADCSRA-Register
26
27
_delay_ms(3000);
28
display_command(LCD_CLEAR);  
29
30
31
32
33
34
35
36
37
  int x = 0;
38
int value;
39
int summe = 0;
40
int x1=0;
41
42
while(1){
43
44
45
46
while (x1<20){  //Mittelwertbildung aus 20Messungen
47
48
ADMUX = 0;  
49
  ADCSRA |= (1<<ADSC);              // eine ADC-Wandlung 
50
  while ( ADCSRA & (1<<ADSC) ) {
51
     ;     // auf Abschluss der Konvertierung warten 
52
  }
53
54
summe = summe + ADCW;
55
56
x1 = x1 + 1;
57
58
59
60
}
61
62
x1 = 0;
63
summe = summe * 0.05; //Division der 20 Messungen
64
65
       char ADCW0[20]; // in diesem {} lokal
66
       itoa( summe, ADCW0, 10 ); 
67
68
69
70
71
value = ADCW;
72
value = value * 0.1465;    // Umwandlung des ADCW-Wert
73
        char TempW[20]; // in diesem {} lokal
74
       itoa( value, TempW, 10 ); 
75
76
77
78
79
80
ADMUX = 1;  
81
82
  ADCSRA |= (1<<ADSC);              // eine ADC-Wandlung 
83
  while ( ADCSRA & (1<<ADSC) ) {
84
     ;     // auf Abschluss der Konvertierung warten 
85
  }
86
87
        char ADCW1[20]; // in diesem {} lokal
88
       itoa( ADCW, ADCW1, 10 ); 
89
90
91
92
93
x = x+1;
94
95
        char Counter[20]; // in diesem {} lokal
96
       itoa( x, Counter, 10 ); 
97
98
99
100
101
102
103
104
  display_ptext( "Counter:",1,0);
105
  display_ptext( Counter,1,9);
106
107
  display_ptext( "Bitwert ADC 0:",2,0);
108
  display_ptext( ADCW0,2,15);
109
110
  display_ptext( "Bitwert ADC 1:",3,0);
111
  display_ptext( ADCW1,3,15);
112
113
  display_ptext( "Temperatur:",4,0);
114
  display_ptext( "    ",4,15);
115
  display_ptext( TempW,4,15);
116
  display_ptext( "C",4,18);
117
118
119
120
_delay_ms(333);
121
122
123
124
125
126
127
128
}
129
130
131
132
  while(1!=2);
133
  return 1;
134
}

von Uwe .. (uwegw)


Lesenswert?

Das Komma bekommt man, indem man die Temperatur nicht in  Grad, sondern 
in Zehntelgrad berechnet. Also statt 23,1 eben 231. Und bei der Ausgabe 
aufs LCD setzt man dann einfach ein Komma an der richtigen Stelle 
dazwischen.

von Fox (Gast)


Lesenswert?

Ok das tönt super! Kein Problem zu Berechnen. Diese Idee hatte ich auch 
schon.

Aber wie kann ich dieses Komma dort hineinfügen? Da habe ich keinen 
blassen Schimmer.

von Fox (Gast)


Lesenswert?

Das wäre super, dann würde sich auch ein anderes Problem lösen, Wie kann 
ich an einen Bestehenden Wert noch C schreiben, also 23.1 C.

Das wäre ja dann hier irgendwo:
1
  display_ptext( TempW,4,15);

habe schon probiert mit & Zeichen also TempW & " C" ... geht aber nicht 
so.

von Jonny O. (-geo-)


Lesenswert?

Komma bekommst du so:

int Variableohnekomma = 231;
int hintermkomma;

hintermkomma = Variableohnekomma % 10;
Variableohnekomma /= 10;

// Inhalt von hintermkomma ist 1
// Inhalt von Variableohnekomma ist 23


//Jetzt einfach erst die Variableohnekomma ausgeben und anschließend ein 
Komma ausgeben und zum Schluss hintermkomma ausgeben.
printf("%d",Variableohnekomma);
printf(",");
printf("%d",hintermkomma);

Gruß
geo

von Franz H. (dl7avf)


Lesenswert?

Hallo Fox,

das Komma kannst du einbauen, wenn du die Zahl in zwei Komponenten 
zerlegst:
Vorkomma- und Nachkommaziffern, z.B. mit 'div' und 'sprintf':

char *sitofix2 ( char *string, int i )
  {
  div_t di = div(i, 100);    // Struktur für Quotient und Rest.
  char *sformat = i < 0 ? "-%d,%02d" : "%d,%02d";
  sprintf(string, sformat, abs(di.quot), abs(di.rem));
  return string;
  }

Hier wird aus der ganzen Zahl i ein String mit 2 Nachkommastellen 
erzeugt,
z.B. bei i=1234 wird string="12,34", also etwa so:

char s[20];
display_ptext( sitofix(s, 1234), 1, 0);

Schöne Grüsse,

Franz

von Falk B. (falk)


Lesenswert?


von Fox (Gast)


Lesenswert?

So Danke für Hilfe

Die Lösung ist nach  Jonny Obivan realisiert.
Nach  Franz Hamberger bekomme ich Fehler beim Komplieren: (sitofix2 ist 
nicht deklariert etc.


Jetzt funktioniert es:
1
//------------------------------------------------------------------------
2
//              Temperatur mit Koma Trennung
3
//------------------------------------------------------------------------
4
5
int Variableohnekomma = value;
6
int hintermkomma;
7
8
hintermkomma = Variableohnekomma % 10;
9
Variableohnekomma /= 10;
10
11
// Inhalt von hintermkomma ist 1
12
// Inhalt von Variableohnekomma ist 23
13
14
15
  printf("%d",Variableohnekomma);
16
        char Printf1[20]; // in diesem {} lokal
17
         itoa( Variableohnekomma, Printf1, 10 ); 
18
19
  display_ptext( Printf1,4,14);
20
21
22
  display_ptext( ".",4,16); //    printf(",");
23
24
25
  printf("%d",hintermkomma);
26
        char Printf2[20]; // in diesem {} lokal
27
         itoa( hintermkomma, Printf2, 10 ); 
28
29
  display_ptext( Printf2,4,17);

von Fox (Gast)


Lesenswert?

So jetzt kommts langsam gut!

Was denkt Ihr, dass der Counter anspricht, muss ich praktisch Real-Time 
haben. Das Problem ist, dass mir der Wert pro Sekunde weiss nicht wie 
viel Male aktualisiert wird.

Was wäre die schlauste Lösung für ein Update alle 500-1000ms?

Gruss Fox

von Franz H. (dl7avf)


Lesenswert?

Hallo Fox,

hier die korrigierte Version:

... das Komma kannst du einbauen, wenn du die Zahl in zwei Komponenten
zerlegst:
Vorkomma- und Nachkommaziffern, z.B. mit 'div' und 'sprintf':

char *sitofix2 ( char *string, int i )
   {
   div_t di = div(i, 100);    // Struktur für Quotient und Rest.
   char *sformat = i < 0 ? "-%d,%02d" : "%d,%02d";
   sprintf(string, sformat, abs(di.quot), abs(di.rem));
   return string;
   }

Hier wird aus der ganzen Zahl i ein String mit 2 Nachkommastellen
erzeugt,
z.B. bei i=1234 wird string="12,34", also etwa so:

char s[20];
display_ptext( sitofix2(s, 1234), 1, 0); // <-- muss sitofix2 heissen.

Schöne Grüsse,

Franz

von Alain F. (fox82)


Angehängte Dateien:

Lesenswert?

Super stark! Jetzt kann ich beide Varianten anwenden.

Vielen Dank Franz Hamberger.

Der Code ist jetzt folgendermassen:
1
//------------------------------------------------------------------------
2
//              Temperatur mit Komma Trennung
3
//------------------------------------------------------------------------
4
5
6
char *sitofix2 ( char *string, int i )
7
   {
8
   i=value;                            //Temperaturmittelwerte
9
   div_t di = div(i, 10);                      // Struktur für Quotient und Rest. (10 bei 1 Komma 234 = 23.4)
10
   char *sformat = i < 0 ? "-%d.%01d" : "%d.%01d";        //(d= Digit daher 1 Kommastelle = 01d / . oder ,
11
   sprintf(string, sformat, abs(di.quot), abs(di.rem));
12
   return string;
13
   }
14
15
  
16
char s[20];
17
display_ptext( sitofix2(s, 1234), 4, 13); // <-- muss sitofix2 heissen.

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.