Motor stoppt nicht wenn Endanschlagschalter außgelöst wird

OP #2387810
Lesenswert?

Hallo,

ein Atmega16 bekommt von 3 DS18S20 3 Temperaturen:
p_temp  //Temperatur der Probe
k_temp  //Temperatur vom Kältebad (kaltes Wasser mit einem Eiswürfel)
w_temp  //Temperatur vom Wärmebad (heißes Wasser aus der Leitung)

Die Temperaturen werden alle richtig erkannt.
Ein Motor soll die Probe imer wieder zwischen den Bädern hin und her 
fahren. Bei Beiden Bädern ist noch jeweils ein Anschlagschalter, damit 
der Motor weis wann er mit drehen aufhören soll.
Das soll eigentlich so ablaufen das die Probe sofort in das andere Bad 
gefahren wird wenn die Probe die Temperatur des Bades angenommen hat.

Nun ist das Problem das der Motor entweder einfach so los fährt, bevor 
die Probe auch nur im entferntesten die Temperatur des Bades angenommen 
hat.
1
      //+-2 damit das Testen schneller geht.
2
      k_temp = k_temp + 2;
3
      w_temp = w_temp - 2;
4

5
      //Wenn Taster vom K?ltebad an (d.h. Probe ist im Kältebad)
6
      if((PINB & (1<<KB)))
7
      {
8
        //Motor erst mal grundlegend ausschalten, um einen definierten Startwert zu haben
9
      PORTB &= ~ (1<<CCW);  //Motor aus
10
      PORTB &= ~ (1<<CW);    //Motor aus
11

12

13
        if((p_temp <= k_temp))   //fals Probentemp gleich Kältebadtemp ist
14
        {
15

16
         //ins Wärmebad fahren)
17
         //PORTB &= ~ (1<<CCW);
18
         PORTB |= (1<<CW); 
19
        }
20
      }
21
         
22
      //Wenn Taster vom Wärmebad an (d.h. Probe ist im Wärmebad)
23
      if((PINB & (1<<WB)))
24
      {
25
        //Motor erst mal grundlegend ausschalten, um einen definierten Startwert zu haben
26
      PORTB &= ~ (1<<CCW);  //Motor aus
27
      PORTB &= ~ (1<<CW);    //Motor aus
28
        
29
      
30
        if((p_temp >= w_temp))// fals Probentemp gleich Wärmebadtemp ist
31
        {
32
         //ins Kältebad fahren
33
         //PORTB &= ~ (1<<CW);
34
         PORTB |= (1<<CCW);
35
         
36
        }
37
      }
Angehängte Dateien:
Gast #2388024
Lesenswert?

Das sollte mit einer Ablaufkette (State Machine) programmiert werden.
Nur mit Abfragen zu arbeiten für in der Regel zu instabilen Systemen.

wenn k_temp <= k_soll und p_temp == k_temp
dann setzen Motor zum Wärmebad

wenn Endschalter Wärmebad
dann rücksetzen Motor zum Wärmebad

warte Zeit x Sekunden für Messung

wenn w_temp >= w_soll und p_temp == w_temp
dann setzen Motor zum Kältebad

wenn Endschatler Kältebad
dann rücksetzen Motor zum Kältebad

warte Zeit x Sekunden für Messung

zurück zum Anfang

Gruß Reiner
OP #2388165
Lesenswert?

Tasten entprellen ist Neuland, habe mir angesehen was die Idee dahinter 
ist, kann es aber nicht programmiertechnisch umsetzen... Reicht es im 
einfachsten Fall delay_us() auszuführen?
Kann mir jemand mal soetwas an meinem Programm zeigen damit ich verstehe 
wie so etwas aussehen muss?

Hoffe der Code ist nicht zu lang
1
//B2 Taster K?ltebad
2
//B3 Taster W?rmebad
3

4

5

6
#include <avr/io.h>
7
#include <avr/interrupt.h>
8
#define F_CPU 2000000
9
#include <util/delay.h>
10
#include <inttypes.h>
11
#include <stdint.h>
12

13
#define TRUE 1
14
#define FALSE 0
15

16
// Anchlussbelegung:
17

18
#define KTEMP_DDR DDRD        //Temperatur Input vom Kältebad
19
#define WTEMP_DDR DDRC        //Temperatur Input vom Wärmebad
20
#define PTEMP_DDR DDRA        //Temperatur Input von Probe
21

22
#define MOTOR_DDR DDRB        //Datenrichtung zum Motor-Steuer-Atmega festlegen
23
#define MOTOR_OUT PORTB        //Ausgänge zum Motor-Steuer-Atmega
24
#define MOTOR_IN  PINB
25

26
#define CW   PB0          //Motor cw richtung Kältebad
27
#define CCW  PB1          //Motor ccw richtung Wärmebad
28
#define KB   PB2          //Taster Kältebad abfragen 
29
#define WB   PB3          //Taster Wärmebad abfragen
30

31

32
int main(void)
33
{
34
    uint8_t w_temp = 0;          //Variable zum speichern der Zustände vom Wärmebad
35
    uint8_t k_temp = 0;          //Variable zum speichern der Zustände vom Kältebad
36
    uint8_t p_temp = 0;          //Variable zum speichern der Zustände von der Probe
37
         
38
        const uint16_t pause = 200;
39
    const uint16_t pause_2 =80;
40
    
41
    
42
    KTEMP_DDR = 0x00;    //Eing?nge D
43
        WTEMP_DDR = 0x00;    //Eing?nge C
44
    PTEMP_DDR = 0x00;    //Eing?nge A
45

46
    //B0 un B1 als Ausgänge, B2 und B3 als Eingänge:
47
    MOTOR_DDR = (1 << DDB0) | (1 << DDB1);
48

49
    //Pause für 20 Sekunden damit alles andere initialisieren kann
50
    for(int a=0; a<20; a++){_delay_ms( 1000 );}
51

52
        do
53
        {
54
      k_temp = 0;          
55
      p_temp = 0;          
56
      w_temp = 0;          
57
  
58
      //Temperaturen von den LED Anzeigen abholen.
59
      if ( PINA & (1<<PINA0) ) {p_temp = p_temp + 1;}
60
      if ( PINA & (1<<PINA1) ) {p_temp = p_temp + 2;}
61
      if ( PINA & (1<<PINA2) ) {p_temp = p_temp + 4;}
62
      if ( PINA & (1<<PINA3) ) {p_temp = p_temp + 8;}
63
      if ( PINA & (1<<PINA4) ) {p_temp = p_temp + 10;}
64
      if ( PINA & (1<<PINA5) ) {p_temp = p_temp + 20;}
65
      if ( PINA & (1<<PINA6) ) {p_temp = p_temp + 40;}
66
      if ( PINA & (1<<PINA7) ) {p_temp = p_temp + 80;}
67

68
      if ( PINC & (1<<PINC0) ) {w_temp = w_temp + 1;}
69
      if ( PINC & (1<<PINC1) ) {w_temp = w_temp + 2;}
70
      if ( PINC & (1<<PINC2) ) {w_temp = w_temp + 4;}
71
      if ( PINC & (1<<PINC3) ) {w_temp = w_temp + 8;}
72
      if ( PINC & (1<<PINC4) ) {w_temp = w_temp + 10;}
73
      if ( PINC & (1<<PINC5) ) {w_temp = w_temp + 20;}
74
      if ( PINC & (1<<PINC6) ) {w_temp = w_temp + 40;}
75
      if ( PINC & (1<<PINC7) ) {w_temp = w_temp + 80;}
76

77
      if ( PIND & (1<<PIND0) ) {k_temp = k_temp + 1;}
78
      if ( PIND & (1<<PIND1) ) {k_temp = k_temp + 2;}
79
      if ( PIND & (1<<PIND2) ) {k_temp = k_temp + 4;}
80
      if ( PIND & (1<<PIND3) ) {k_temp = k_temp + 8;}
81
      if ( PIND & (1<<PIND4) ) {k_temp = k_temp + 10;}
82
      if ( PIND & (1<<PIND5) ) {k_temp = k_temp + 20;}
83
      if ( PIND & (1<<PIND6) ) {k_temp = k_temp + 40;}
84
      if ( PIND & (1<<PIND7) ) {k_temp = k_temp + 80;}
85

86
      //+-2 damit das Testen schneller geht.
87
      k_temp = k_temp + 2;
88
      w_temp = w_temp - 2;
89

90
      //Wenn Taster vom K?ltebad an (d.h. Probe ist im Kältebad)
91
      if((PINB & (1<<KB)))
92
      {
93
        //Motor erst mal grundlegend ausschalten, um einen definierten Startwert zu haben
94
      PORTB &= ~ (1<<CCW);  //Motor aus
95
      PORTB &= ~ (1<<CW);    //Motor aus
96

97

98
        if((p_temp <= k_temp))   //fals Probentemp gleich Kältebadtemp ist
99
        {
100

101
         //ins Wärmebad fahren)
102
         //PORTB &= ~ (1<<CCW);
103
         PORTB |= (1<<CW); 
104
        }
105
      }
106
         
107
      //Wenn Taster vom Wärmebad an (d.h. Probe ist im Wärmebad)
108
      if((PINB & (1<<WB)))
109
      {
110
        //Motor erst mal grundlegend ausschalten, um einen definierten Startwert zu haben
111
      PORTB &= ~ (1<<CCW);  //Motor aus
112
      PORTB &= ~ (1<<CW);    //Motor aus
113
        
114
      
115
        if((p_temp >= w_temp))// fals Probentemp gleich Wärmebadtemp ist
116
        {
117
         //ins Kältebad fahren
118
         //PORTB &= ~ (1<<CW);
119
         PORTB |= (1<<CCW);
120
         
121
        }
122
      }
123

124
        } //ENDE do
125
    while(1);
126

127
} //ENDE main
OP #2388403
Lesenswert?

Die 4 Atmegas sind auf jeden Fall zu viele. Ich habe das Projekt 
angefangen, weil ich so ein Gerät unbedingt brauche. allerdings habe ich 
programmieren auch parallel dazu gelernt. Bin und war also Einsteiger.
Ich hoffe Ihr helft mir trotzdem.

Entprellen würde ich damit, weil ich hier zumindest noch den code 
kapiere, alle anderen Routinen sind mir zu kompliziert um sie zum 
verstehen:
1
unsigned char PINC_clean(){
2
    wait_ms(20);
3
    return PINC;
4
  }

^^ich weis nur nicht wo ich die Funktion aufrufen soll?
Schreiben würde ich das ganze vor der main.

Danke für die Hilfe
#2389232
Lesenswert?

Vergiss das mit dem Warten mal ganz schnell und benutze es nie wieder!

Die gebräuchlichste Methode zum Entprellen ist Mehrfaches Messen. D.h. 
der Eingang wird mehrmals gemessen und wenn er bei allen Messungen wahr 
war gilt es als Tastendruck.

Z.b. 4 Messungen:
1 1 0 1 --> Taste nicht gedrückt
1 1 1 1 --> Taste gedrückt

Das ganze wird mit einem Zähler in Verbindung mit einem Timer 
realisiert.

Wenn der Timer überläuft, wird geprüft ob die Taste gedrückt ist, wenn 
ja wird der Zähler erhöht wenn nein auf 0 gesetzt. Erreicht der Zähler 
den Wert x gilt die Taste als gedrückt.

Probier das mal aus selbst zu schreiben - dann hast du es auch 
verstanden.

PS: Ich habe noch nie mehrere Avs gleichzeitig benutzt. Aber schon viele 
Tasten mit einem entprellt. Das letztere ist deutlich einfacher.
OP #2389235
Lesenswert?

mag sein, aber noch einmal: ICH BIN ANFÄNGER! Alles was ich weis ist 
irgendwie selbst angelesen und durch Probieren entstanden.

Ich bräuchte immer noch einen Tip wie ich die Tastenentprellung in 
meinen Code einbauen soll. Ich würde ja die Super-Entprell Routine von 
Peter Dannegger nehmen, aber davon kapier ich rein garnichts.

Ich versuch es mal mit der Warteschleifenvariante mit Maske und Pointer 
(nach Christian Riggenbach).
http://www.mikrocontroller.net/articles/Entprellung

Trotzdem macht es nicht was es soll. Ich habe ja 3 DS18S20 (je einen im 
Kältebad, einen im Wärmebad und einen zur Probentemperaturermittlung). 
Im Kältebad werden 7°C angezeigt, Im Wärmebad 36°C und die Probe hat 
22°C.
Laut meinem Programm sollte sich der Motor nun nicht drehen, bis Die 
Brobe die Temperatur vom Kältebad angenommen hat...Motor dreht sich aber 
trotzdem. << ich hoffe da sieht einer von Euch den Fehler

Damit sieht der Code nun so aus:
1
//B2 Taster K?ltebad
2
//B3 Taster W?rmebad
3

4

5

6
#include <avr/io.h>
7
#include <avr/interrupt.h>
8
#define F_CPU 2000000
9
#include <util/delay.h>
10
#include <inttypes.h>
11
#include <stdint.h>
12

13
#define TRUE 1
14
#define FALSE 0
15

16
// Anchlussbelegung:
17

18
#define KTEMP_DDR DDRD        //Temperatur Input vom Kältebad
19
#define WTEMP_DDR DDRC        //Temperatur Input vom Wärmebad
20
#define PTEMP_DDR DDRA        //Temperatur Input von Probe
21

22
#define MOTOR_DDR DDRB        //Datenrichtung zum Motor-Steuer-Atmega festlegen
23
#define MOTOR_OUT PORTB        //Ausgänge zum Motor-Steuer-Atmega
24
#define MOTOR_IN  PINB
25

26
#define CW   PB0          //Motor cw richtung Kältebad
27
#define CCW  PB1          //Motor ccw richtung Wärmebad
28
#define KB   PB2          //Taster Kältebad abfragen 
29
#define WB   PB3          //Taster Wärmebad abfragen
30

31
void entprellung( volatile uint8_t *port, uint8_t maske ) {
32
  uint8_t   port_puffer;
33
  uint8_t   entprellungs_puffer;
34
 
35
  for( entprellungs_puffer=0 ; entprellungs_puffer!=0xff ; ) {
36
    entprellungs_puffer<<=1;
37
    port_puffer = *port;
38
    _delay_us(150);
39
    if( (*port & maske) == (port_puffer & maske) )
40
      entprellungs_puffer |= 0x01;
41
  }
42
}
43

44

45
int main(void)
46
{
47
    uint8_t w_temp = 0;          //Variable zum speichern der Zustände vom Wärmebad
48
    uint8_t k_temp = 0;          //Variable zum speichern der Zustände vom Kältebad
49
    uint8_t p_temp = 0;          //Variable zum speichern der Zustände von der Probe
50
         
51
        const uint16_t pause = 200;
52
    const uint16_t pause_2 =80;
53
    
54
    
55
    KTEMP_DDR = 0x00;    //Eing?nge D
56
        WTEMP_DDR = 0x00;    //Eing?nge C
57
    PTEMP_DDR = 0x00;    //Eing?nge A
58

59
    //B0 un B1 als Ausgänge, B2 und B3 als Eingänge:
60
    MOTOR_DDR = (1 << DDB0) | (1 << DDB1);
61

62
    //Pause für 20 Sekunden damit alles andere initialisieren kann
63
    for(int a=0; a<20; a++){_delay_ms( 1000 );}
64

65
        do
66
        {
67
      k_temp = 0;          
68
      p_temp = 0;          
69
      w_temp = 0;          
70
  
71
      //Temperaturen von den LED Anzeigen abholen.
72
      if ( PINA & (1<<PINA0) ) {p_temp = p_temp + 1;}
73
      if ( PINA & (1<<PINA1) ) {p_temp = p_temp + 2;}
74
      if ( PINA & (1<<PINA2) ) {p_temp = p_temp + 4;}
75
      if ( PINA & (1<<PINA3) ) {p_temp = p_temp + 8;}
76
      if ( PINA & (1<<PINA4) ) {p_temp = p_temp + 10;}
77
      if ( PINA & (1<<PINA5) ) {p_temp = p_temp + 20;}
78
      if ( PINA & (1<<PINA6) ) {p_temp = p_temp + 40;}
79
      if ( PINA & (1<<PINA7) ) {p_temp = p_temp + 80;}
80

81
      if ( PINC & (1<<PINC0) ) {w_temp = w_temp + 1;}
82
      if ( PINC & (1<<PINC1) ) {w_temp = w_temp + 2;}
83
      if ( PINC & (1<<PINC2) ) {w_temp = w_temp + 4;}
84
      if ( PINC & (1<<PINC3) ) {w_temp = w_temp + 8;}
85
      if ( PINC & (1<<PINC4) ) {w_temp = w_temp + 10;}
86
      if ( PINC & (1<<PINC5) ) {w_temp = w_temp + 20;}
87
      if ( PINC & (1<<PINC6) ) {w_temp = w_temp + 40;}
88
      if ( PINC & (1<<PINC7) ) {w_temp = w_temp + 80;}
89

90
      if ( PIND & (1<<PIND0) ) {k_temp = k_temp + 1;}
91
      if ( PIND & (1<<PIND1) ) {k_temp = k_temp + 2;}
92
      if ( PIND & (1<<PIND2) ) {k_temp = k_temp + 4;}
93
      if ( PIND & (1<<PIND3) ) {k_temp = k_temp + 8;}
94
      if ( PIND & (1<<PIND4) ) {k_temp = k_temp + 10;}
95
      if ( PIND & (1<<PIND5) ) {k_temp = k_temp + 20;}
96
      if ( PIND & (1<<PIND6) ) {k_temp = k_temp + 40;}
97
      if ( PIND & (1<<PIND7) ) {k_temp = k_temp + 80;}
98

99
      //+-2 damit das Testen schneller geht.
100
      k_temp = k_temp + 2;
101
      w_temp = w_temp - 2;
102

103
      //Wenn Taster vom K?ltebad an (d.h. Probe ist im Kältebad)
104
      entprellung( &PINB, (1<<PINB2) ); // ggf. Prellen abwarten
105
      if((PINB & (1<<KB)))
106
      {
107
        //Motor erst mal grundlegend ausschalten, um einen definierten Startwert zu haben
108
      PORTB &= ~ (1<<CCW);  //Motor aus
109
      PORTB &= ~ (1<<CW);    //Motor aus
110

111

112
        if((p_temp <= k_temp))   //fals Probentemp gleich Kältebadtemp ist
113
        {
114

115
         //ins Wärmebad fahren)
116
         //PORTB &= ~ (1<<CCW);
117
         PORTB |= (1<<CW); 
118
        }
119
      }
120
         
121
      //Wenn Taster vom Wärmebad an (d.h. Probe ist im Wärmebad)
122
      entprellung( &PINB, (1<<PINB3) ); // ggf. Prellen abwarten
123
      if((PINB & (1<<WB)))
124
      {
125
        //Motor erst mal grundlegend ausschalten, um einen definierten Startwert zu haben
126
      PORTB &= ~ (1<<CCW);  //Motor aus
127
      PORTB &= ~ (1<<CW);    //Motor aus
128
        
129
      
130
        if((p_temp >= w_temp))// fals Probentemp gleich Wärmebadtemp ist
131
        {
132
         //ins Kältebad fahren
133
         //PORTB &= ~ (1<<CW);
134
         PORTB |= (1<<CCW);
135
         
136
        }
137
      }
138

139
        } //ENDE do
140
    while(1);
141

142
} //ENDE main

Gruß Rocco
#2389269
Lesenswert?

Rocco L. schrieb:
> if ( PIND & (1<<PIND0) ) {k_temp = k_temp + 1;}
>       if ( PIND & (1<<PIND1) ) {k_temp = k_temp + 2;}
>       if ( PIND & (1<<PIND2) ) {k_temp = k_temp + 4;}
>       if ( PIND & (1<<PIND3) ) {k_temp = k_temp + 8;}
>       if ( PIND & (1<<PIND4) ) {k_temp = k_temp + 10;}
>       if ( PIND & (1<<PIND5) ) {k_temp = k_temp + 20;}
>       if ( PIND & (1<<PIND6) ) {k_temp = k_temp + 40;}
>       if ( PIND & (1<<PIND7) ) {k_temp = k_temp + 80;}

Das geht auch einfacher.

k_temp = PIND;
#2389285
Lesenswert?

Ich weiß dass du Anfänger bist, aber du machst dir das Leben unnötig 
kompliziert. Ein Avr reicht. Und Warteschleifen sollte man halt nur bei 
Initialisierungen verwenden. Schreibe dir deine eigene Entprellroutine 
und du wirst es verstehen. Es nützt nichts 90% des Prozessors mit warten 
zu verbraten, dafür aber dann 5 Stück zu nehmen.
OP #2389302
Lesenswert?

Helmut Lenzen schrieb:
> Rocco L. schrieb:
>> if ( PIND & (1<<PIND0) ) {k_temp = k_temp + 1;}
>>       if ( PIND & (1<<PIND1) ) {k_temp = k_temp + 2;}
>>       if ( PIND & (1<<PIND2) ) {k_temp = k_temp + 4;}
>>       if ( PIND & (1<<PIND3) ) {k_temp = k_temp + 8;}
>>       if ( PIND & (1<<PIND4) ) {k_temp = k_temp + 10;}
>>       if ( PIND & (1<<PIND5) ) {k_temp = k_temp + 20;}
>>       if ( PIND & (1<<PIND6) ) {k_temp = k_temp + 40;}
>>       if ( PIND & (1<<PIND7) ) {k_temp = k_temp + 80;}
>
> Das geht auch einfacher.
>
> k_temp = PIND;

^^das geht nicht, weil die Temp über ein Pseudobinäres LED Array 
ausgegeben und eingelesen wird. So wird die Temp an die LED ausgegeben 
und kann durch adieren der brennenden LED abgelesen werden:
1
           //Konfiguration der Pins für LEDs setzen
2
                // (0 = LED an, 1 = LED aus)
3
                if(tC >= 80) { p |=(1<<7); tC -= 80; } //Pin7 f?r 80?C an
4
                if(tC >= 40) { p |=(1<<6); tC -= 40; } //Pin6 f?r 40?C an
5
                if(tC >= 20) { p |=(1<<5); tC -= 20; } //Pin5 f?r 20?C an
6
                if(tC >= 10) { p |=(1<<4); tC -= 10; } //Pin4 f?r 10?C an
7
                if(tC >= 8)  { p |=(1<<3); tC -= 8;  } //Pin3 f?r 8?C  an
8
                if(tC >= 4)  { p |=(1<<2); tC -= 4;  } //Pin2 f?r 4?C  an
9
                if(tC >= 2)  { p |=(1<<1); tC -= 2;  } //Pin1 f?r 2?C  an
10
                if(tC >= 1)  { p |=(1<<0); tC -= 1;  } //Pin0 f?r 1?C  an

Immernoch dreht sich der Motor einfach so, obwohl die Probentemperatur 
noch nicht <= der Kältebadtemperatur ist...
#2389633
Lesenswert?

Reiner schrieb:
> Das sollte mit einer Ablaufkette (State Machine) programmiert werden.

Sehe ich auch so.
Das ist die Methode, um beliebige Abläufe verstehbar und zuverlässig zu 
implementieren.
Und dann sieht man auch, ob es wirklich am Entprellen liegen könnte.

In Deinem Code kann ich jedenfalls nicht durchsteigen.
Liegt zum Teil auch daran, daß Du die Forenregeln mißachtest:
1
Wichtige Regeln - erst lesen, dann posten!
2

3
    Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang


Peter
#2389778
Lesenswert?

Eine State-Maschine hat etwa dieses Gerüst:
1
#include <avr/io.h>
2

3
enum { RESET, STOP_KALT, FAHRT_WARM, STOP_WARM, FAHRT_KALT };
4

5
void init()
6
{
7
  // hier alles Init-Zeugs
8
}
9

10
int main()
11
{
12
  uint8_t state = RESET;
13

14
  init();
15
  
16
  for(;;){                      // Main-Loop
17
    switch( state ){
18
      case RESET:
19
                        // teste Bedingung
20
                        state = STOP_KALT;      // Aktion
21
                        break;
22
      case STOP_KALT:
23
                        // teste Bedingung
24
                        // Aktion
25
                        break;
26
      case STOP_WARM:
27
                        // teste Bedingung
28
                        // Aktion
29
                        break;
30
      case FAHRT_KALT:
31
                        // teste Bedingung
32
                        // Aktion
33
                        break;
34
      case FAHRT_WARM:
35
                        // teste Bedingung
36
                        // Aktion
37
                        break;
38
    }
39
  }
40
}


Rocco L. schrieb:
> Ich kann ansonsten nochmal versuchen den Code etwas besser zu Ordnen -
> weis aber nicht ob das die Sache wirklich besser macht ;)

Nein.

Peter
#2389806
Lesenswert?

Hallo,

bei welchen Temperaturen passiert es das der Motor losfährt?

Hast Du kontrolliert, das die Temperaturen richtig gelesen werden?

Wie oft/schnell änderen sich die Temperaturwerte?

Den Vorschlag von Peter Dannegger mit der Funktion bcd2bin() solltest Du 
auf jeden Fall umsetzen, und zwar nicht deswegen weil es eleganter ist 
sondern weil es eine wichtige Fehlerquelle ausschließt: Was passiert 
wenn sich die Temperaturanzeigen ändern während der Prozesser einen Pin 
nach dem anderen abfragt?

Wie werden die Temperatur-Anzeigen angesteuert? Sind das statische 
Signale oder Multiplex-Signale?

Gruß
Volkmar
OP #2393335
Lesenswert?

Ich habe jetzt versucht nach meinen Möglichkeiten so etwas wie eine 
state machine zu konstruieren.

Soweit passt auch alles. Die switch-case tut auch was sie soll, solange 
ich sc_temp "von Hand" auf 1 oder 2 setze (Zeile 77).

Nutze ich den Vergleich in Zeile 72 / 73 geht es generell nur in 
Richtung Kältebad :(
Angehängte Dateien:
Gast #2393430
Lesenswert?

Du hast das mit der StateMaschine noch nicht so ganz verstanden:
1
void main ( void )
2
{
3
  ...
4

5
  while(1)
6
  {
7
    switch ( state )
8
    //-- warte auf aktion --------------------------------
9
    case 0:
10
      //-- Aktion -------------------
11
      PORTB=...;
12
      //-- weiter? ------------------
13
      if ( ... ) state= 0;
14
      if ( ... ) state= 1;
15
      break;
16

17
    //-- Richtung Wärmebad -------------------------------
18
    case 1:
19
      //-- Aktion -------------------
20
      PORTB=...;  // heizen
21
      //-- weiter? ------------------
22
      if ( ... ) state= 0;
23
      if ( ... ) state= 2;
24
      break;
25

26
    //-- Richtung Kältebad -------------------------------
27
    case 2:
28
      //-- Aktion -------------------
29
      PORTB=...;  // kühlen
30
      //-- weiter? ------------------
31
      if ( ... ) state= 0;
32
      if ( ... ) state= 1;
33
      break;
34

35
    //-- ungültig ----------------------------------------
36
    default:
37
      state:= 0;
38
    }

Das while hat in der Statemaschine nicht zu suchen.

Die
1
if (..) state=
musst du abhängig noch detailieren.
#2393474
Lesenswert?

Was mir an deiner Statemachine auffaellt, man wartet in einer 
Statemachine nicht. Wenn man einen Portpin abfragt in einem State dann 
geht man wenn die Bedingung erfuellt ist zum naechsten State. Also keine 
for oder while Schleifen die auf etwas wrten. Auch sollte man den 
einzelnen States sprechende Namen geben als einfache Ziffern. Wenn du 
das so machst kannst du auch mehrere Aktion quasi gleichzeitig von 
deinem Prozessor steuern lassen.


Also in etwa so:
for(;;)
{
   switch(State) {
   case WARTENPINB:
     if(PINB & (1 << KB)) State = PINBOK;
     break;

   case PINBOK:
     .... und weiter
     State = NEXTSTATE;
     break;
   case NEXTSTATE:
   }

   Hier koennte noch eine weiter Statemachine stehen die einen anderen
   Prozess steuern kann

}
#2393549
Lesenswert?

Rocco L. schrieb:
> Die switch-case tut auch was sie soll, solange
> ich sc_temp "von Hand" auf 1 oder 2 setze (Zeile 77)

Was soll denn sc_temp = 1 oder 2 bedeuten?

Ich hab doch nicht aus purem Jux und Dollerei den Zuständen Namen 
gegeben. Die Zustände sollen beschreiben, was eben gerade gemacht wird. 
Du willst doch das Programm auch verstehen.
Du kannst Dir gerne andere Namen ausdenken. Aber keine Zahlen nehmen, 
das ist Pfui-Bäh.


Und um die Statemaschine gibt es nur ein einziges while und zwar die 
Mainloop.
In der Statemaschine gibt es nur if.
While ist verboten, damit blockierst Du die Statemaschine, sie kann 
nicht mehr arbeiten.
Wie soll in einem while sich ein Zustand ändern oder etwas gemacht 
werden?
Richtig, das geht nicht.


Peter

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