Forum: PC-Programmierung C Pointer auf Array an Funktion übergeben


von youth (Gast)


Lesenswert?

Hallo,

ich habe Probleme mit folgenden Code. Und zwar versuche ich an die 
Funktion MesseFeuchte ein Array zu übergeben. Dies mach ich über einen 
Pointer auf das Array aus der main-funktion. In der Funktion 
MesseFeuchte verändere ich den Wert des Pointers, also das array. 
funktioniert aber nicht. Ich bekomme dann folgende Warnung für den code 
in Zeile 106 und 107, also überall wo *str steht.

../LCD_Test.c:107: warning: passing argument 4 of 'dtostrf' makes 
pointer from integer without a cast

Ich muss wohl irgendeine Typenkonvertierung durchführen. Jedenfalls 
steht auf meinen LCD immernoch "Test", das Array wurde also nicht 
verändert. Ich bitte um Hilfe.
1
 
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include "lcd-routines.h"
5
#include <util/delay.h>
6
#include <stdlib.h>
7
#include "i2cmaster.h"
8
#ifndef F_CPU
9
#define F_CPU 1000000
10
#endif
11
#ifndef TRUE
12
#define TRUE 1
13
#define FALSE 0
14
#endif
15
16
volatile unsigned char NrOverflows = 0;               // Anzahl der Timer Overflows die während
17
                                                      // der Messung passiert sind
18
volatile unsigned int  StartTime = 0;                 // ICR-Wert bei 1.High-Flanke speichern
19
volatile unsigned int  EndTime = 0;                   // ICR-Wert bei 2.High-Flanke speichern
20
volatile unsigned char Messung;                       // Job Flag
21
22
ISR( TIMER1_CAPT_vect )
23
{
24
  static unsigned char ErsteFlanke = TRUE;
25
  if( Messung )                                        // Die Ergebnissen der vorhergehenden wurden noch nicht ausgegeben
26
  return;                                              // Messung noch nicht upgedated. Die naechste Messung
27
                                                       // verzögern, bis die Start und EndTime Variablen wieder
28
                                                       // gefahrlos beschrieben werden koennen
29
30
  // Bei der ersten Flanke beginnt die Messung, es wird der momentane
31
  // Timer beim Input Capture als Startwert gesichert
32
  if( ErsteFlanke )
33
  {
34
    StartTime = ICR1;
35
    NrOverflows = 0;
36
    ErsteFlanke = FALSE;                                // Die naechste Flanke ist das Ende der Messung
37
  }
38
39
  // das ist die zweite Flanke im Messzyklus. Die Messung wird gestoppt
40
  else
41
  {
42
    EndTime = ICR1;
43
    Messung = TRUE;                                     // Eine vollständige Messung. Sie kann ausgewertet werden
44
    ErsteFlanke = TRUE;                                 // Bei der naechsten Flanke beginnt der naechste Messzyklus
45
  }
46
}
47
48
49
ISR( TIMER1_OVF_vect )
50
{
51
  NrOverflows++;
52
}
53
54
55
void MesseFeuchte(char *str)
56
{
57
58
  short    i = 0;
59
  double   freq = 0.0;                                  
60
  double   zwe = 0.0;                                  
61
  double   sens =0.0;                                   
62
  double   sensmsb = 0.0;
63
  double   senslsb = 0.0;
64
  double   offset =0.0;                                 
65
  double   offmsb=0.0;                                  
66
  double   offlsb=0.0;                                 
67
  double   rh =0.0;  
68
 
69
  i2c_init();                                           
70
  i2c_start(0xA2);                                      
71
  i2c_write(0x0A);                                      
72
  i2c_start(0xA3);                                      
73
  sensmsb = i2c_readAck();                              
74
  senslsb = i2c_readAck();                              
75
  offmsb = i2c_readAck();                               
76
  offlsb = i2c_readNak();                               
77
  i2c_stop();                                           
78
  offmsb = offmsb*16*16;                                
79
  offset = offmsb+offlsb;                               
80
  sensmsb = sensmsb *16*16;        
81
  sens = sensmsb+senslsb;        
82
83
  
84
   if( Messung )
85
    {
86
      //
87
      // Die Zeitdauer zwischen den Flanken bestimmen
88
      // Da EndTime und StartTime unsigned sind, braucht nicht
89
      // darauf Ruecksicht genommen werden, dass EndTime auch
90
      // kleiner als StartTime sein kann. Es kommt trotzdem
91
      // das richtige Ergebnis raus.
92
      // Allerdings muss die Anzahl der Overflows in der Messperiode
93
      // beruecksichtigt werden
94
      //
95
      // Die Zeitdauer wird als Anzahl der Taktzyklen zwischen den
96
      // beiden gemessenen Flanken berechnet ...
97
      freq = (NrOverflows * 65536) + EndTime - StartTime;
98
      // ... mit der bekannten Taktfrequenz ergibt sich dann die Signalfrequenz
99
      freq = F_CPU / freq;                               // f = 1 / t
100
      if(freq>5000 && freq < 10000)                      // gültigen Frequenzbereich festlegen
101
         {
102
           zwe= zwe +freq;
103
           ++i;
104
           if(i>500)                                     // Genauigkeit festlegen
105
            {
106
             rh = ((offset-(zwe/i))*sens/4096);          // Relative Luftfeuchtigkeit mit entsprechender Formel berechnen
107
             dtostrf((zwe/i),5,2,*str);               // Das Ergebnis fuer die Anzeige aufbereiten ...
108
             dtostrf(rh,5,2,*str);
109
             i=0;                                        // Variablen zurücksetzen
110
             zwe = 0.0;                                  //
111
             freq =0.0;                                  //
112
            }
113
         }
114
115
      Messung = FALSE;
116
    }    
117
  }
118
119
120
121
int main(void)
122
{
123
  char feu[8] = "Test";
124
125
  TCCR1B = (1<<ICES1)  | (1<<CS10);                     
126
  TIMSK = (1<<TICIE1) | (1<<TOIE1);
127
  sei();
128
  DDRB = 0b11111110;
129
130
131
  // Initialisierung des LCD
132
  _delay_ms(2000);
133
  lcd_init();
134
135
136
  while(1)
137
  {
138
       lcd_setcursor( 0, 1 );
139
     //lcd_string("Feuchte: ");
140
     //lcd_setcursor( 9, 1 );
141
     lcd_string(feu);
142
  }
143
  return 0;
144
145
}

von youth (Gast)


Lesenswert?

Mit folgenden Text passt die Ausgabe auf dem LCD mit "Feuchte: 40.45".
Ich möchte die main allerdings etwas übersichtlich halten und versuche 
deswegen eine Funktion für das Messen der Feuchte zu erstellen.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include "lcd-routines.h"
4
#include <util/delay.h>
5
#include <stdlib.h>
6
#include "i2cmaster.h"
7
#ifndef F_CPU
8
#define F_CPU 1000000
9
#endif
10
#ifndef TRUE
11
#define TRUE 1
12
#define FALSE 0
13
#endif
14
15
volatile unsigned char NrOverflows = 0;               // Anzahl der Timer Overflows die während
16
                                                      // der Messung passiert sind
17
volatile unsigned int  StartTime = 0;                 // ICR-Wert bei 1.High-Flanke speichern
18
volatile unsigned int  EndTime = 0;                   // ICR-Wert bei 2.High-Flanke speichern
19
volatile unsigned char Messung;                       // Job Flag
20
21
ISR( TIMER1_CAPT_vect )
22
{
23
  static unsigned char ErsteFlanke = TRUE;
24
  if( Messung )                                        // Die Ergebnissen der vorhergehenden wurden noch nicht ausgegeben
25
  return;                                              // Messung noch nicht upgedated. Die naechste Messung
26
                                                       // verzögern, bis die Start und EndTime Variablen wieder
27
                                                       // gefahrlos beschrieben werden koennen
28
29
  // Bei der ersten Flanke beginnt die Messung, es wird der momentane
30
  // Timer beim Input Capture als Startwert gesichert
31
  if( ErsteFlanke )
32
  {
33
    StartTime = ICR1;
34
    NrOverflows = 0;
35
    ErsteFlanke = FALSE;                                // Die naechste Flanke ist das Ende der Messung
36
  }
37
38
  // das ist die zweite Flanke im Messzyklus. Die Messung wird gestoppt
39
  else
40
  {
41
    EndTime = ICR1;
42
    Messung = TRUE;                                     // Eine vollständige Messung. Sie kann ausgewertet werden
43
    ErsteFlanke = TRUE;                                 // Bei der naechsten Flanke beginnt der naechste Messzyklus
44
  }
45
}
46
47
48
ISR( TIMER1_OVF_vect )
49
{
50
  NrOverflows++;
51
}
52
53
54
int main(void)
55
{
56
  char str[8];
57
  short    i = 0;
58
  double   freq = 0.0;                                  
59
  double   zwe = 0.0;                                  
60
  double   sens =0.0;                                   
61
  double   sensmsb = 0.0;
62
  double   senslsb = 0.0;
63
  double   offset =0.0;                                 
64
  double   offmsb=0.0;                                  
65
  double   offlsb=0.0;                                 
66
  double   rh =0.0;  
67
 
68
  i2c_init();                                           
69
  i2c_start(0xA2);                                      
70
  i2c_write(0x0A);                                      
71
  i2c_start(0xA3);                                      
72
  sensmsb = i2c_readAck();                              
73
  senslsb = i2c_readAck();                              
74
  offmsb = i2c_readAck();                               
75
  offlsb = i2c_readNak();                               
76
  i2c_stop();                                           
77
  offmsb = offmsb*16*16;                                
78
  offset = offmsb+offlsb;                               
79
  sensmsb = sensmsb *16*16;        
80
  sens = sensmsb+senslsb;        
81
82
  TCCR1B = (1<<ICES1)  | (1<<CS10);                     
83
  TIMSK = (1<<TICIE1) | (1<<TOIE1);
84
  sei();
85
  DDRB = 0b11111110;
86
87
88
  // Initialisierung des LCD
89
  _delay_ms(2000);
90
  lcd_init();
91
92
93
  while(1)
94
  {
95
   if( Messung )
96
    {
97
      //
98
      // Die Zeitdauer zwischen den Flanken bestimmen
99
      // Da EndTime und StartTime unsigned sind, braucht nicht
100
      // darauf Ruecksicht genommen werden, dass EndTime auch
101
      // kleiner als StartTime sein kann. Es kommt trotzdem
102
      // das richtige Ergebnis raus.
103
      // Allerdings muss die Anzahl der Overflows in der Messperiode
104
      // beruecksichtigt werden
105
      //
106
      // Die Zeitdauer wird als Anzahl der Taktzyklen zwischen den
107
      // beiden gemessenen Flanken berechnet ...
108
      freq = (NrOverflows * 65536) + EndTime - StartTime;
109
      // ... mit der bekannten Taktfrequenz ergibt sich dann die Signalfrequenz
110
      freq = F_CPU / freq;                               // f = 1 / t
111
      if(freq>5000 && freq < 10000)                      // gültigen Frequenzbereich festlegen
112
         {
113
           zwe= zwe +freq;
114
           ++i;
115
           if(i>500)                                     // Genauigkeit festlegen
116
            {
117
             rh = ((offset-(zwe/i))*sens/4096);          // Relative Luftfeuchtigkeit mit entsprechender Formel berechnen
118
             dtostrf((zwe/i),5,2,str);               // Das Ergebnis fuer die Anzeige aufbereiten ...
119
             dtostrf(rh,5,2,str);
120
             i=0;                                        // Variablen zurücksetzen
121
             zwe = 0.0;                                  //
122
             freq =0.0;                                  //
123
            }
124
         }
125
126
      Messung = FALSE;
127
    }    
128
       lcd_setcursor( 0, 1 );
129
     lcd_string("Feuchte: ");
130
     lcd_setcursor( 9, 1 );
131
     lcd_string(str);
132
  }
133
  return 0;
134
135
}

von Floh (Gast)


Lesenswert?

youth schrieb:
> dtostrf((zwe/i),5,2,*str);

Probiers mal ohne Stern. dtostrf erwartet glaub ich einen Pointer.
Also so:
dtostrf((zwe/i),5,2,str);

von youth (Gast)


Lesenswert?

Floh schrieb:
> Probiers mal ohne Stern. dtostrf erwartet glaub ich einen Pointer.

Kann ja nicht sein, weil der Quellcode der läuft erhält als char array 
und da funktioniert es ohne Warnung. Hab es aber auch schon in der 
Quellcode ganz oben so versucht wie du sagst. Dann gibts eine Warnung 
und es funktioniert auch nicht :(

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

1
void MesseFeuchte(char *str)
2
{
3
  ...
4
  dtostrf((zwe/i),5,2,*str);

Das ist ganz definitiv falsch und der Compiler gibt an dieser Stelle 
auch eine Fehlermeldung aus.

dtostrf erwartet als letzten Parameter einen Pointer auf char, und 
nicht einen char. Den aber erzeugst Du durch die Dereferenzierung des 
Pointers.

Allerdings rufst Du die Funktion MesseFeuchte in Deinem ersten 
Codebeispiel überhaupt nicht auf, von daher ist es kein Wunder, daß der 
falsche Aufruf von dtostrf keine besondere Auswirkung hat.

Dein zweites Codebeispiel ruft dtostrf auch vollkommen korrekt ohne 
Dereferenzierung auf.

von Karl H. (kbuchegg)


Lesenswert?

youth schrieb:
> Floh schrieb:
>> Probiers mal ohne Stern. dtostrf erwartet glaub ich einen Pointer.
>
> Kann ja nicht sein,

Doch.
Das kann nicht nur sein, das ist auch so.

dotostrf erwartet an dieser Stelle einen Pointer. Dein str ist ein 
Pointer. Passt also perfekt

> weil der Quellcode der läuft erhält als char array
> und da funktioniert es ohne Warnung.

Logisch. Weil der Name eines Arrays an dieser Stelle ohne eine 
Dereferenzierung automatisch als Pointer auf den Anfang der Daten 
fungiert.

Oder banal ausgedrückt: Ein Array wird immer übergeben, indem der 
Empfänger einen Pointer auf die Daten bekommt. Wenn die empfangende 
Funktion ihrerseits wieder eine andere Funktion aufruft, der sie das 
Array 'weitergeben' möchte, dann übergibt sie ganz einfach den Pointer. 
Eine empfangende Funktion kann nicht feststellen, ob der Pointer den sie 
bekommt die Startadresse eines Arrays ist oder nicht. Sie bekommt 
einfach nur einen Pointer.

von youth (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Allerdings rufst Du die Funktion MesseFeuchte in Deinem ersten
> Codebeispiel überhaupt nicht auf, von daher ist es kein Wunder, daß der
> falsche Aufruf von dtostrf keine besondere Auswirkung hat.

Sorry die is tmit drin. Oben nur vergessen.
1
 
2
  while(1)
3
  {
4
       MesseFeuchte(feu);
5
       lcd_setcursor( 0, 1 );
6
     //lcd_string("Feuchte: ");
7
     //lcd_setcursor( 9, 1 );
8
9
     lcd_string(feu);
10
  }

Ok, aber auch wenn ich die *str in str ändere. Dann gibt mir das LCD 
immer nur Test aus. Das heißt die Messung funktioniert nicht oder das 
array wird nicht bearbeitet.

von DirkB (Gast)


Lesenswert?

Du hast das dtostrf hinter 3 if-Anweisungen gepackt.
Wobei die letzte if(i>500) immer scheitert, da du in MessFeuchte keine 
Schleife hast.
Das i ist lokal und nicht static.

von youth (Gast)


Lesenswert?

Hallo DirkB,

da hast du vollkommen Recht. i wird so bei jedem Funktionsaufruf auf 0 
zurück gesetzt. Jetzt hab ich die Variablen global gemacht und damit 
erreicht man auch die innerste if bedingung. Dennoch steht jetzt 
schätzungsweise 1 Minute auf dem LCD "Test" da und dann gibt er erst 
einen Messwert aus, der auch schätzungsweise nur einmal pro Minute 
aktualisiert. Wo ist das Problem? Wenn ich den Code nicht in eine 
Funktion auslagere, dann aktualisiert er wesentlich schneller und jetzt 
sehr sehr sehr träge. Kann mir vielleicht jemand den Code meines 2. 
Beitrag so ausgliedern in eine Funktion, dass es auch funktioniert. Mein 
aktueller Code ist:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#include "lcd-routines.h"
4
#include <util/delay.h>
5
#include <stdlib.h>
6
#include "i2cmaster.h"
7
#ifndef F_CPU
8
#define F_CPU 1000000
9
#endif
10
#ifndef TRUE
11
#define TRUE 1
12
#define FALSE 0
13
#endif
14
15
volatile unsigned char NrOverflows = 0;               // Anzahl der Timer Overflows die während
16
                                                      // der Messung passiert sind
17
volatile unsigned int  StartTime = 0;                 // ICR-Wert bei 1.High-Flanke speichern
18
volatile unsigned int  EndTime = 0;                   // ICR-Wert bei 2.High-Flanke speichern
19
volatile unsigned char Messung;                       // Job Flag
20
21
ISR( TIMER1_CAPT_vect )
22
{
23
  static unsigned char ErsteFlanke = TRUE;
24
  if( Messung )                                        // Die Ergebnissen der vorhergehenden wurden noch nicht ausgegeben
25
  return;                                              // Messung noch nicht upgedated. Die naechste Messung
26
                                                       // verzögern, bis die Start und EndTime Variablen wieder
27
                                                       // gefahrlos beschrieben werden koennen
28
29
  // Bei der ersten Flanke beginnt die Messung, es wird der momentane
30
  // Timer beim Input Capture als Startwert gesichert
31
  if( ErsteFlanke )
32
  {
33
    StartTime = ICR1;
34
    NrOverflows = 0;
35
    ErsteFlanke = FALSE;                                // Die naechste Flanke ist das Ende der Messung
36
  }
37
38
  // das ist die zweite Flanke im Messzyklus. Die Messung wird gestoppt
39
  else
40
  {
41
    EndTime = ICR1;
42
    Messung = TRUE;                                     // Eine vollständige Messung. Sie kann ausgewertet werden
43
    ErsteFlanke = TRUE;                                 // Bei der naechsten Flanke beginnt der naechste Messzyklus
44
  }
45
}
46
47
ISR( TIMER1_OVF_vect )
48
{
49
  NrOverflows++;
50
}
51
  short i = 0;
52
  double   freq = 0.0;                                  
53
  double   zwe = 0.0;                                  
54
  double   sens =0.0;                                   
55
  double   sensmsb = 0.0;
56
  double   senslsb = 0.0;
57
  double   offset =0.0;                                 
58
  double   offmsb=0.0;                                  
59
  double   offlsb=0.0;                                 
60
  double   rh =0.0;  
61
62
void MesseFeuchte(char *str)
63
{
64
  i2c_init();                                           
65
  i2c_start(0xA2);                                      
66
  i2c_write(0x0A);                                      
67
  i2c_start(0xA3);                                      
68
  sensmsb = i2c_readAck();                              
69
  senslsb = i2c_readAck();                              
70
  offmsb = i2c_readAck();                               
71
  offlsb = i2c_readNak();                               
72
  i2c_stop();                                           
73
  offmsb = offmsb*16*16;                                
74
  offset = offmsb+offlsb;                               
75
  sensmsb = sensmsb *16*16;        
76
  sens = sensmsb+senslsb;        
77
78
  
79
   if( Messung )
80
    {
81
      //
82
      // Die Zeitdauer zwischen den Flanken bestimmen
83
      // Da EndTime und StartTime unsigned sind, braucht nicht
84
      // darauf Ruecksicht genommen werden, dass EndTime auch
85
      // kleiner als StartTime sein kann. Es kommt trotzdem
86
      // das richtige Ergebnis raus.
87
      // Allerdings muss die Anzahl der Overflows in der Messperiode
88
      // beruecksichtigt werden
89
      //
90
      // Die Zeitdauer wird als Anzahl der Taktzyklen zwischen den
91
      // beiden gemessenen Flanken berechnet ...
92
      freq = (NrOverflows * 65536) + EndTime - StartTime;
93
      // ... mit der bekannten Taktfrequenz ergibt sich dann die Signalfrequenz
94
      freq = F_CPU / freq;                               // f = 1 / t
95
      if(freq>5000 && freq < 10000)                      // gültigen Frequenzbereich festlegen
96
         {
97
           zwe= zwe +freq;
98
           ++i;
99
           if(i>500)                                     // Genauigkeit festlegen
100
            {
101
             rh = ((offset-(zwe/i))*sens/4096);          // Relative Luftfeuchtigkeit mit entsprechender Formel berechnen
102
             dtostrf((zwe/i),5,2,str);               // Das Ergebnis fuer die Anzeige aufbereiten ...
103
             dtostrf(rh,5,2,str);
104
             i=0;                                        // Variablen zurücksetzen
105
             zwe = 0.0;                                  //
106
             freq =0.0;                                  //
107
            }
108
         }
109
110
      Messung = FALSE;
111
    }    
112
  }
113
114
int main(void)
115
{
116
  char feu[8] = "Test";
117
118
  TCCR1B = (1<<ICES1)  | (1<<CS10);                     
119
  TIMSK = (1<<TICIE1) | (1<<TOIE1);
120
  sei();
121
  DDRB = 0b11111110;
122
123
  // Initialisierung des LCD
124
  _delay_ms(2000);
125
  lcd_init();
126
127
  while(1)
128
  {
129
       MesseFeuchte(feu);
130
       lcd_setcursor( 0, 1 );
131
     //lcd_string("Feuchte: ");
132
     //lcd_setcursor( 9, 1 );
133
134
     lcd_string(feu);
135
  }
136
  return 0;
137
}

von DirkB (Gast)


Lesenswert?

Du hast jetzt bei jedem Funktionsaufruf
1
i2c_init();                                           
2
  i2c_start(0xA2);                                      
3
  i2c_write(0x0A);                                      
4
  i2c_start(0xA3);                                      
5
  sensmsb = i2c_readAck();                              
6
  senslsb = i2c_readAck();                              
7
  offmsb = i2c_readAck();                               
8
  offlsb = i2c_readNak();                               
9
  i2c_stop();
Muss das sein?
Vorher has du das einmal beim Programmstart gemacht.

youth schrieb:
> Jetzt hab ich die Variablen global gemacht

static hätte gereicht.

Besser ist es den Wert in einer Funktion zu berechnen und in einer 
anderen auszugeben.

von youth (Gast)


Lesenswert?

DirkB schrieb:
> Muss das sein?
> Vorher has du das einmal beim Programmstart gemacht.

Eigentlich nicht, damit werden nur Koeffizienten ausgelesen. Würde glaub 
ich auch einmalig reichen.

DirkB schrieb:
> Besser ist es den Wert in einer Funktion zu berechnen und in einer
> anderen auszugeben.

Das möchte ich ja versuchen. Ich wollte eine Funktion in der die Feuchte 
komplett gemessen wird. Der Wert soll dann an main zurückgegeben werden 
um die dann auszugeben. Nur leider scheitere ich ja gerade daran wie du 
siehst.

von youth (Gast)


Lesenswert?

DirkB schrieb:
> Muss das sein?
> Vorher has du das einmal beim Programmstart gemacht.

Aber du hast Recht, damit ist das Problem für die träge Messung 
beseitigt. Wahrscheinlich hat das Auslesen der Koeffizienten zu viel 
Zeit beansprucht um das dauerhaft zu machen.

Dann hab ich den Code zwar in der main Funktion mit drin, aber das ist 
besser so. Danke dir.

von Karl H. (kbuchegg)


Lesenswert?

Das andere ist, dass du ständig auf das LCD malst, selbst dann, wenn 
sich die Anzeige gar nicht verändert, weil du noch gar keine Messung 
gemacht hast. Du musst auf dem LCD nur dann updaten, wenn tatsächlich in 
Messung auch ein neuer Wert bestimmt wird (und eigentlich auch nur dann, 
wenn sich dieser Wert vom gerade angezeigten Wert unterscheidet. Aber 
das lassen wir jetzt erst mal).

Wann immer dein µC in einer der LCD-Routinen rumtrödelt, dauert es seine 
Zeit, biser dann wieder zu der Stelle kommt an der er nachsieht ob eine 
neue Messung vorliegt. Auch das kostet Zeit.

von Karl H. (kbuchegg)


Lesenswert?

youth schrieb:
> DirkB schrieb:
>> Muss das sein?
>> Vorher has du das einmal beim Programmstart gemacht.
>
> Aber du hast Recht, damit ist das Problem für die träge Messung
> beseitigt. Wahrscheinlich hat das Auslesen der Koeffizienten zu viel
> Zeit beansprucht um das dauerhaft zu machen.
>
> Dann hab ich den Code zwar in der main Funktion mit drin, aber das ist
> besser so.

Nein. Ist es nicht.
Was hindert dich daran, eine Funktion: GetCoefficients() zu machen, in 
die du diese Sequenz verbannst? Dann hast du sie auch aus der main() 
draussen.

von Karl H. (kbuchegg)


Lesenswert?

Und die Sache mit den Jobflags

verstreu sie nicht über das ganze Programm. Lass die Auswertung ruhig in 
der Hauptschleife
1
void MesseFeuchte(char *str)
2
{
3
  static uint16_t i = 0;
4
5
  //
6
  // Die Zeitdauer zwischen den Flanken bestimmen
7
  // Da EndTime und StartTime unsigned sind, braucht nicht
8
  // darauf Ruecksicht genommen werden, dass EndTime auch
9
  // kleiner als StartTime sein kann. Es kommt trotzdem
10
  // das richtige Ergebnis raus.
11
  // Allerdings muss die Anzahl der Overflows in der Messperiode
12
  // beruecksichtigt werden
13
  //
14
  // Die Zeitdauer wird als Anzahl der Taktzyklen zwischen den
15
  // beiden gemessenen Flanken berechnet ...
16
  freq = (NrOverflows * 65536) + EndTime - StartTime;
17
18
  // ... mit der bekannten Taktfrequenz ergibt sich dann die Signalfrequenz
19
  freq = F_CPU / freq;                               // f = 1 / t
20
 
21
  if( freq > 5000 && freq < 10000)                      // gültigen Frequenzbereich festlegen
22
  {
23
    zwe = zwe + freq;
24
    ++i;
25
26
    if( i > 500 )                                     // Genauigkeit festlegen
27
    {
28
      rh = ((offset-(zwe/i))*sens/4096);          // Relative Luftfeuchtigkeit mit entsprechender Formel berechnen
29
      dtostrf((zwe/i),5,2,str);               // Das Ergebnis fuer die Anzeige aufbereiten ...
30
      dtostrf(rh,5,2,str);
31
  
32
      i = 0;                                        // Variablen zurücksetzen
33
      zwe = 0.0;                                  //
34
      freq =0.0;                                  //
35
    }
36
  }
37
}
38
39
int main(void)
40
{
41
  char feu[8] = "Test";
42
43
  TCCR1B = (1<<ICES1)  | (1<<CS10);                     
44
  TIMSK = (1<<TICIE1) | (1<<TOIE1);
45
  sei();
46
  DDRB = 0b11111110;
47
48
  // Initialisierung des LCD
49
  _delay_ms(2000);
50
51
  lcd_init();
52
  GetCoefficients();
53
54
  while(1)
55
  {
56
    if( Messung )
57
    {
58
       MesseFeuchte(feu);
59
       lcd_setcursor( 0, 1 );
60
       lcd_string(feu);
61
62
       Messung = FALSE;
63
    }
64
  }
65
  return 0;
66
}

PS: i ist ein ganz schlechter Name füt einen Zaehler der die Anzahl der 
Messungen zählt. Genauso wie zwe

Warum nennst du die Dinge nicht nach dem was sie bedeuten.
anzMessungen bzw. sumMessungen
sind doch noch ganz handhabbare Bezeichnungen.

Jetzt ist es ein bischen besser, weil das i lokal in der Funktion ist. 
Aber eine globale Variable namens i ist ein definitives "ask for 
trouble". Das fordert Fehler geradezu heraus.

von youth (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Was hindert dich daran, eine Funktion: GetCoefficients() zu machen, in
> die du diese Sequenz verbannst?

Nichts, nur dann muss ich die ganzen Variablen immer an die Funktion 
übergeben oder teilweise zurückholen und in dem Zusammenhang wohl auch 
mit mehreren Pointern arbeiten. Bin ich nicht so geübt drin.

Das mit dem LCD stimmt natürlich, wie würdest du das denn umgehen? Den 
Char Array in einen zweiten Kopieren und immer mit den vorherigen Array 
vergleichen ob die identisch sind? Und nur dann die LCD Routinen 
aufrufen?

von Karl H. (kbuchegg)


Lesenswert?

youth schrieb:
> Karl Heinz Buchegger schrieb:
>> Was hindert dich daran, eine Funktion: GetCoefficients() zu machen, in
>> die du diese Sequenz verbannst?
>
> Nichts, nur dann muss ich die ganzen Variablen immer an die Funktion
> übergeben oder teilweise zurückholen und in dem Zusammenhang wohl auch
> mit mehreren Pointern arbeiten.

Du hast sie ja doch sowieso als globale Variablen.

> Das mit dem LCD stimmt natürlich, wie würdest du das denn umgehen?

Siehe letzten Vorschlag. Der erledigt das gleich mit

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.