Mittelwertbildung von Temperatur

Gast #3646804
Lesenswert?

Moin Moin ^^

Ich bin dabei eine Temperaturanzeige zu programmieren. Das klappt soweit 
auch alles. Was mir nicht gefällt, ist das der Wert sich viel zu oft im 
Display ( 7- Segment) ändert. Dies habe ich versuch mit hilfe einer 
"Mittelwertbildung" zu unterdrücken. Der Sensor braucht ca. eine Sekunde 
bis er ein neues Ergebniss liefern kann. In meine ISR (wo ich den Wert 
abfrage vom DS1621 & umrechne) springe ich ca. jede 2 Sekunden rein. 
Wenn ich den Wert jetzt 16 x auf summiere, müsste es doch eigentlich "32 
Sekunden" dauern bis ich meinen neuen Wert auf dem Display sehen kann 
oder ?
Aktuell ändert sich der Wert aber fast jede 5 Sekunden.

Hat jemand eine Idee, sieht was ich falsch mache ?
1
#define F_CPU 8000000
2

3
#define DS1621_Write  0x9E
4
#define DS1621_Read   0x9F
5

6
#define Segment_1_AN PORTB &= ~(1<<PB3)
7
#define Segment_1_AUS PORTB |= (1<<PB3)
8

9
#define Segment_2_AN PORTB &= ~(1<<PB2)
10
#define Segment_2_AUS PORTB |= (1<<PB2)
11

12
#define Segment_3_AN PORTB &= ~(1<<PB1)
13
#define Segment_3_AUS PORTB |= (1<<PB1)
14

15
#define Segment_4_AN PORTB &= ~(1<<PB0)
16
#define Segment_4_AUS PORTB |= (1<<PB0)
17

18
#define Mittelwert 16
19

20
int Zahlen[13]= {
21
          0b00111111, // 0
22
          0b00000110, // 1
23
          0b01011011, // 2
24
          0b01001111, // 3
25
          0b01100110, // 4
26
          0b01101101, // 5
27
          0b01111101, // 6
28
          0b00100111, // 7
29
          0b01111111, // 8
30
          0b01101111, // 9
31
            0b01100011, // *
32
            0b01000000, // Minus
33
          0b00000000  // alle Aus
34
        };
35

36
#include <avr/io.h>
37
#include <util/delay.h>
38
#include "i2cmaster.h"
39
#include <avr/interrupt.h>
40

41
volatile unsigned char  TempH, TempL = 0;
42
volatile int16_t    Wert, Summe, Ergebnis;
43
volatile int8_t      TempAbs = 0;
44
volatile uint8_t    IsNegative, I, Done;
45
 
46

47
int main(void)
48
{
49
  DDRB |= ((1<<PB0) | (1<<PB1) | (1<<PB2) | (1<<PB3));
50
  DDRD |= ((1<<PD0) | (1<<PD1) | (1<<PD2) | (1<<PD3) | (1<<PD4) | (1<<PD5) | (1<<PD6));
51
  
52
    OCR1A   = 15624;            // Legt den Wert ZUM Überlaufes fest ( ca. jede 2 Sec. )
53
  TCCR1A |= (1<<WGM11);          // CTC Modus
54
    TIMSK  |= (1<<OCIE1A);          // Compare Match Interrupt enable
55
    TCCR1B |= ((1<<CS12) | (1<<CS10));    // Prescaler auf 1024 setzen (F_CPU/1024)
56
  sei();
57
  
58

59
  i2c_init();
60
  
61
  i2c_start(DS1621_Write); // Starten der Umwandlung (Messung)
62
  i2c_write(0xEE);
63
  i2c_stop();
64
       
65
  i2c_start(DS1621_Write); // Starten der Auslesung (Temperaturregister)
66
  i2c_write(0xAA);
67
  i2c_stop();
68

69
  Segment_1_AUS; Segment_2_AUS; Segment_3_AUS; Segment_4_AUS;
70
  
71
while (1)
72
{
73
  
74
  Segment_1_AN;
75
  PORTD = Zahlen[Wert & 0x000F];
76
  _delay_ms(4);
77
  Segment_1_AUS;
78

79
  Segment_2_AN;
80
  PORTD = Zahlen[(Wert & 0x00F0) >> 4];
81
  _delay_ms(4);
82
  Segment_2_AUS;
83
  
84
  Segment_3_AN;
85
  PORTD = Zahlen[(Wert & 0x0F00) >> 8];
86
  _delay_ms(4);
87
  Segment_3_AUS;
88
  
89
  Segment_4_AN;
90
  PORTD = Zahlen[(Wert & 0xF000) >> 12];
91
  _delay_ms(4);
92
  Segment_4_AUS;
93

94
} // Ende While
95
} // Ende Main
96

97
ISR (TIMER1_COMPA_vect)
98
{
99

100
  if (I <= Mittelwert)
101
  {  
102
    I++;  
103
    i2c_start(DS1621_Read);
104
    TempH = i2c_readAck();
105
    TempL = i2c_readNak();
106
    i2c_stop();
107

108
/*    if ((TempL & 0b10000000) == (0b10000000))
109
    {
110
      TempH++;
111
    }
112
*/      
113
      Summe += TempH;
114
    
115
  }
116

117

118
  if (I == Mittelwert)
119
  {
120
    Ergebnis = Summe / Mittelwert;
121
    
122
    I = 0;
123
    Summe = 0;
124
    
125
    
126
      if (Ergebnis < 0)
127
      {
128
        IsNegative = 1;
129
        TempAbs = ~(Ergebnis) + 1;
130
      }
131
      else
132
      {
133
        IsNegative = 0;
134
        TempAbs = Ergebnis;
135
      }
136

137
      Wert = ((((TempAbs / 10) % 10) << 8) | ((TempAbs % 10) << 4) | (0x0A)); // Wert entspricht dem "Wert" aus dem Array (Zahlen)
138

139
      if (TempAbs == 0)
140
      {
141
        Wert = 0xCC0A;
142
      }
143
      else if (TempAbs >= 100)
144
      {
145
        Wert = (Wert | 0x1000);
146
      }
147
      else if (TempAbs < 10)
148
      {
149
        Wert = (Wert | 0xCC00);
150
      }
151
      else if (TempAbs < 100)
152
      {
153
        Wert = (Wert | 0xC000);
154
      }
155

156
      if (IsNegative == 1)
157
      {
158
        Wert = (Wert & 0x0FFF) | (0xB000);
159
      }
160
    
161
    
162
  }
163
  
164

165
  
166
  
167
}// Ende ISR
#3646856
Lesenswert?

So debugge ich meinen code.
Du willst wissen warum die Aktualisierung nur 5 Sekunden dauert anstatt 
30? Schaue wie schnell die isr aufgerufen wird. Passt das? Dann pack das 
togglen in die if's rein. Passt das? ...
Das ist ne Sache von Minuten da so einen toggle Befehl an verschiedenen 
stellen nacheinander einzufügen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren