Forum: Mikrocontroller und Digitale Elektronik Taster über externe Stromquelle - GND verbinden?


von Christoph (christoph13524)


Angehängte Dateien:

Lesenswert?

Hallo!

Ich bin Anfänger mit Mikrocontroller und habe eine Frage, wo ich noch 
nichts im Internet auf die Schnelle gefunden habe.

Ich möchte wissen ob das funktioniert:
Mein Atmega8 ist ganz normal an einer 5V Stromversorgung angeschlossen.
Ich möchte einen Taster mit Pulldown-Widerstand von einer anderen 5V 
Stromquelle anschließen. Muss ich die GND-Leitungen der beiden 
Stromversorgungen verbinden oder nicht? Strom braucht ja immer einen 
Kreis.. aber hier bin ich mir nicht ganz sicher. Schadet natürlich 
nicht, aber ich würde gerne darauf verzichten, wenn möglich.
Vereinfachter Schaltplan ist angehängt.

Ich habe nämlich ein Problem mit irgendwelchen Störungen an einem 
Projekt, wo der Taster hin und wieder zufällig ausgelöst wird, wenn der 
Taster an der gleichen Stromversorgung, wie vom Mikrocontroller hängt. 
Erstmal wäre einfach eine kurze Antwort zur genannten Frage hilfreich. 
Wenn ich die GND verbinden muss, werde ich das Problem wahrscheinlich 
wieder haben. Dann kann ich das genauer beschreiben und vielleicht hilft 
mir wer dann bei der Problemsuche.

Danke erstmals,
Christoph

von Peter D. (peda)


Lesenswert?

Galvanische Trennung geht gut mit einem AQY212 Halbleiterrelais.

von Thomas S. (thomas_s72)


Lesenswert?

Ja!
Die Massen müssen verbunden sein, sonst funktioniert es nicht.
Falls das nicht gewünscht oder möglich ist kann man auch einen 
Optokoppler verwenden.

von HildeK (Gast)


Lesenswert?

Christoph K. schrieb:
> Ich möchte wissen ob das funktioniert:

Nein, das funktioniert nicht!
Die GNDs müssen verbunden sein.

von Christoph (christoph13524)


Lesenswert?

Ok, danke für die Info - habe ich mir schon gedacht.

Wie funktioniert das mit dem Optokoppler? Kann den vielleicht wer in 
meinen Schaltplan einzeichnen? Der muss ja die GND verbinden aber auch 
galvanisch trennen? Check ich gerade nicht wirklich...

von Thomas S. (thomas_s72)


Lesenswert?


von HildeK (Gast)


Lesenswert?

Christoph K. schrieb:
> Wie funktioniert das mit dem Optokoppler?
1
          VCC
2
           +
3
           |
4
    .------+-----.     VCC
5
    |            |      +
6
    |            |      |       .-----------.
7
    |            |     .-.      |           |
8
    |            |     | |      |           |
9
    |            |     | |     .-.          |
10
    |            |     '_'     | |        | o
11
    |            |      |      | |      |=|>
12
    |            +------o      '-'        | o
13
    |            |      |       |           |
14
    |            |       \|     |           |
15
    |            |        |  <- V          ---
16
    |            |       <|     -           -
17
    '------+-----'      |  OK   |           |
18
           |            |       '-----------'
19
           |           ===
20
          ===          GND
21
          GND
22
(created by AACircuit v1.28.6 beta 04/19/05 www.tech-chat.de)

von Dussel (Gast)


Lesenswert?

Vielleicht als Anmerkung: OK steht für Optokoppler. Das ist kein 
Transistor.
Vielleicht war ich einfach zu dumm, aber ich habe das erstmal als 
Bipolartransistor interpretiert und das OK als 'Ok, kann man so machen'. 
Dann habe ich mich gewundert, wie das funktionieren soll. ;-)

von MaWin (Gast)


Lesenswert?

Christoph K. schrieb:
> Strom braucht ja immer einen Kreis

Richtig.

Also eine Hin und eine Rückleitung.

Aber: was passiert wenn man GND verbindet ? Bei manchen Geräten kann es 
funken, weil sie schon woanders verbunden sind. Und bei anderen kann der 
Anschluss von weit entferntem sich Störungen einfangen.

Was passiert, wenn das eine Gerät eingeschaltet ist und das andere noch 
nicht ? Und andersrum.

Daher kann eine Trennung über Optokoppler oder Relais sinnvoll sein. 
Erzähle also mehr über die Geräte.

von Christoph (christoph13524)


Angehängte Dateien:

Lesenswert?

Danke für die Antworten.

Lassen wir mal das mit dem Optokoppler - ich hätte das eigentlich anders 
gemeint.

Jetzt zum ursprünglichen Problem eigentlich:
Angehängt ist der Schaltplan; grob und schlecht bzw. schematisch 
gezeichnet aber ich hoffe man versteht und erkennt alles - sonst bitte 
nachfragen. Die roten strichlierten Linien sind natürlich auch normale 
Leitungen...

Kurze Funktionserklärung:
Ich habe eine Silikonheizmatte, die von einem Temp.-Controller geregelt 
wird und einen Lüfter. Ich habe 4 Servomotoren, die ich (jeweils 2) 
ansteuere. Weiters noch einen motorisierten Kugelhahn, eine LED und eine 
Niveausonde (wenn Wasser steigt, fließt Strom und wird erkannt).
Alles zusammen wird von dem Atmega8 und Attiny45 gesteuert. Der Attiny 
war nur eine Notlösung, weil ich Probleme hatte, den ganzen Code nur auf 
den Atmega8 zu packen. Der Attiny harmoniert mit dem Atmega und steuert 
dann nur die LED an.
Einen Taster gibt es auch noch. Wenn ich den Taster drücke, schaltet die 
Heizung und Lüfter aus, der Kugelhahn schließt sich, die Servos springen 
kurz an und die LED leuchtet anders. Ein erneutes Drücken schaltet das 
ganze System wieder ein. So kann man sich das alles ungefähr vorstellen. 
Wenn die Niveausonde Kontakt mit Wasser hat, schließt diese nur den 
Kugelhahn.

Die beiden Widerstände an den Servoleitungen sind da, dass die Servos 
beim Stromausfall nicht kurz zucken - hilft etwas mit den Widerständen.

Alles funktioniert eigentlich einwandfrei nur es gibt 1 Problem: Der 
Taster wird komplett zufällig alle paar Minuten ohne irgendwelche 
Ereignisse geschalten. Ich habe schon so viel ausprobiert an was das 
liegen kann aber ich komme nicht drauf.

Was ich probiert habe, um das Problem zu beheben:

1. Taster mit Pullup-Widerstand gemacht - erfolglos
2. Den Taster einfach mal an 2 Signalleitungen (PB0 und PC0) gehängt (so 
wie es im Schaltplan derzeit eingezeichnet ist) - natürlich auch 
erfolglos
3. Das Problem tritt nicht auf, wenn ich die Silikonheizmatte abstecke! 
Ich denke es treten irgendwo Wirbelströme oder Magnetfelder auf, die den 
Taster willkürlich auslösen - durch den Wechselstrom irgendwie.
4. Taster funktioniert einwandfrei; Problem tritt auch ganz ohne Taster 
auf.

GND_1 und GND_2 sind nicht verbunden. Ist ja galvanisch getrennt durch 
das Relais. Könnte man aber ja machen.

Ist der Pulldown Widerstand am Taster zu groß/klein? Das Kabel vom 
Taster ist rund 2m lang. Habe gelesen, dass wenn der Pulldown zu groß 
ist, kein eindeutiges 0V-Signal am Mikrocontroller erkannt wird.

Ich bekomme einfach irgendeine Störung an die Leitung vom Taster von 
GND_1 über den Pulldown.

Kann irgendein Kondensator dort helfen?

Habt ihr Ideen bzw. seht ihr Fehler im Schaltplan?
Kann das Problem wirklich ein Magnetfeld/ Wirbelströme sein? Kann mir 
das schwer vorstellen. Aber es hat auf jeden Fall etwas mit der 
Heizmatte zu tun (denke ich, da das Problem nicht auftritt, wenn 
abgesteckt, wie gesagt).

Silikonheizmatte hat 400W 230VAC. Ist in keiner Spulenform gewickelt...

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Christoph K. schrieb:
> Der
> Taster wird komplett zufällig alle paar Minuten ohne irgendwelche
> Ereignisse geschalten.

Das deutet auf einen typischen Softwarefehler hin. Der Taster wird mit 
einem externen Interrupt eingelesen und die Entprellroutine taugt 
nichts.

von Christoph (christoph13524)


Angehängte Dateien:

Lesenswert?

Habe den Code als Datei angehängt.
Ist extrem schlecht und mit vielen Notlösungen geschrieben - das weiß 
ich selber. Ich hoffe, ihr kennt euch trotzdem irgendwie aus... Ich bin 
Anfänger. Es sollte einfach funktionieren und mehr nicht.

Habe den Taster einfach mit einem 20ms delay entprellt.

: Bearbeitet durch User
von Christoph (christoph13524)


Lesenswert?

Hier nochmal der Code vom Atmega8 hier gepostet:

Ich bin mir nicht sicher, ob es ein Hardware- oder Softwareproblem ist.
1
#define F_CPU 8000000UL
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>        // für Servo
5
#include <util/delay.h>          // für Zeit
6
7
#define button_down    ((PINC & (1<<PINC0)) && (PINC & (1<<PINB0)))  // Taster gedrückt, wenn PC0 UND PB0 = high
8
9
// Der Prescaler muss so gewählt werden, dass der Ausdruck
10
// für MILLISEC_BASE einen Wert kleiner als 128 ergibt
11
// MILLISEC_BASE ist der Timerwert, der 1 Millisekunde Zeitdauer ergeben
12
// soll.
13
//
14
#define PRESCALER      128
15
#define PRESCALER_BITS ( 1 << CS22) | ( 1 << CS20 )
16
17
#define MILLISEC_BASE  ( F_CPU / PRESCALER / 1000 )
18
#define CENTER         ( MILLISEC_BASE / 2 )
19
20
//
21
// Konfiguration der Servoleitungen
22
//
23
#define NR_SERVOS      8
24
#define SERVO_DDR      DDRD
25
#define SERVO_PORT     PORTD
26
uint8_t ServoPuls[NR_SERVOS] = { 1<<PD1, 1<<PD2 };
27
28
// Werte für die Servoposition
29
// Gültige Werte laufen von 0 bis 2 * CENTER
30
// 0           ... ganz links
31
// CENTER      ... Mittelstellung
32
// 2 * CENTER  ... ganz rechts
33
//
34
volatile uint8_t ServoValue[NR_SERVOS];
35
36
ISR (TIMER2_COMP_vect)
37
{
38
  static uint8_t ServoId = 0;
39
40
  //
41
  // den Puls des aktuellen Servos beenden
42
  //
43
  SERVO_PORT &= ~ServoPuls[ServoId];
44
45
  //
46
  // welches ist das nächste aktuelle Servo?
47
  //
48
  if( ++ServoId >= NR_SERVOS )
49
  ServoId = 0;
50
51
  //
52
  // die Ausgangsleitung fuer dieses Servo auf 1; den Puls beginnen
53
  //
54
  SERVO_PORT |= ServoPuls[ServoId];
55
56
  //
57
  // den Timer so einstellen, dass bei Pulsende, die ISR erneut aufgerufen wird
58
  //
59
  OCR2 = MILLISEC_BASE + ServoValue[ServoId];
60
}
61
62
void InitServo()
63
{
64
  //
65
  // Die Servoleitungen auf Ausgang stellen
66
  //
67
  SERVO_DDR = ServoPuls[0] | ServoPuls[1] | ServoPuls[2] | ServoPuls[3] |
68
  ServoPuls[4] | ServoPuls[5] | ServoPuls[6] | ServoPuls[7];
69
70
  //
71
  // Timer auf CTC Modus konfigurieren
72
  //
73
  OCR2 = MILLISEC_BASE + ServoValue[0];
74
  TIMSK |= (1<<OCIE2);
75
  TCCR2 = (1<<WGM21) | PRESCALER_BITS;  // CTC mode
76
}
77
78
enum button {off, on} state;        // off=0, on=1
79
80
int main(void)
81
{
82
  InitServo();              // für Servos
83
  sei();                  // für Servos
84
  
85
  state = on;                // Zustand ist am Anfang AN (wegen Stromausfall)
86
  DDRD |= (1<<PD0);            // PD0 auf Ausgang (SSR)
87
  DDRD |= (1<<PD3);            // PD3 auf Ausgang (Wechsler)
88
  DDRB |= (1<<PB3);            // PB3 auf Ausgang (Signal an ATTINY für LED = weiß)
89
  DDRB |= (1<<PB4);            // PB4 auf Ausgang (Signal an ATTINY für LED = orange)
90
  DDRB |= (1<<PB5);            // PB5 auf Ausgang (Signal an ATTINY für LED = orange blinkend)
91
  DDRC &= ~(1<<PINC0);          // PC0 auf Eingang (Taster)  
92
  DDRB &= ~(1<<PINB0);          // PB0 auf Eingang (Taster)  
93
  DDRC &= ~(1<<PINC1);          // PC1 auf Eingang (Niveausonde)  
94
  
95
  uint8_t a = 0;
96
  uint8_t b = 0;
97
  
98
    while (1) 
99
    {  
100
    if (button_down)          // Wenn Taster gedrückt ist
101
    {
102
      _delay_ms(20);          // Prellzeit abwarten
103
      if (state == off)        // Wenn Zustand zuvor OFF war
104
      {
105
        state = on;
106
      }
107
      else if (state == on)      // Wenn Zustand zuvor ON war
108
      {
109
        state = off;
110
      }
111
      while (button_down);      // Warten bis Taster losgelassen wird
112
    }
113
    
114
    else if (state == on)        // System läuft
115
    {
116
      if (b == 0)
117
      {
118
        PORTD |= (1<<PD0);            // SSR an
119
        TCCR2 = (1<<WGM21) | PRESCALER_BITS;  // Timer an
120
        ServoValue[0] = 0.9 * CENTER;      // Servos 1 ZU
121
        ServoValue[1] = 1.93 * CENTER;      // Servos 2 ZU
122
        _delay_ms(2000);
123
        TCCR2 = 0;                // Timer aus
124
        b = 1;      
125
      }
126
127
      else if ( !(PINC & (1<<PC1)) )        // Wenn Niveausonde Kontakt hat
128
      {    
129
        PORTD &= ~(1<<PD3);            // Wechsler aus (Ventil ZU)            
130
        PORTB &= ~(1<<PB3);            // LED = weiß = aus
131
        PORTB &= ~(1<<PB5);            // LED = orange blinkend = aus
132
        PORTB |= (1<<PB4);            // LED = orange = an        
133
      }
134
      
135
      else if ( PINC & (1<<PC1) )          // wenn Niveausonde keinen Kontakt hat
136
      {
137
        PORTD |= (1<<PD3);            // Wechsler an (Ventil AUF)  
138
        PORTB &= ~(1<<PB5);            // LED = orange blinkend = aus
139
        PORTB &= ~(1<<PB4);            // LED = orange = aus
140
        PORTB |= (1<<PB3);            // LED = weiß = an      
141
      }
142
      a = 1;
143
    }
144
    
145
    else if (state == off)              // System steht
146
    {  
147
      if (a == 1)                  // damit die Schleife nur 1 mal durchlaufen wird
148
      {
149
      PORTD &= ~(1<<PD0);              // SSR aus
150
      PORTD &= ~(1<<PD3);              // Wechsler aus (Ventil ZU)      
151
      PORTB &= ~(1<<PB3);              // LED = weiß = aus        
152
      PORTB &= ~(1<<PB4);              // LED = orange = aus
153
      PORTB |= (1<<PB5);              // LED = orange blinkend = an
154
      _delay_ms(12000);              // Warten bis der Lüfter steht
155
      TCCR2 = (1<<WGM21) | PRESCALER_BITS;    // Timer an
156
      ServoValue[0] = 2.8 * CENTER;        // Servos 1 AUF
157
      ServoValue[1] = -0.8;            // Servos 2 AUF  
158
      PORTB &= ~(1<<PB5);              // LED = orange blinkend = aus  (LED bleibt aus)        
159
      _delay_ms(2000);            
160
      TCCR2 = 0;                  // Timer aus
161
      a = 2;
162
      b = 0;
163
      }
164
    }
165
    }
166
}

von Peter D. (peda)


Lesenswert?

Christoph K. schrieb:
> if (button_down)          // Wenn Taster gedrückt ist
>     {
>       _delay_ms(20);          // Prellzeit abwarten

Sowas hatte ich befürchtet. Planloses Delay ist noch lange kein 
Entprellen. Du müßtest mindestens danach nochmal prüfen, ob noch 
gedrückt oder nur Preller.
Am besten ist natürlich, sämtliche Eingänge parallel zu entprellen im 
Timerinterrupt. Dann kann sich das Main auf die Anwendung konzentrieren 
und wird übersichtlicher.

Christoph K. schrieb:
> if (state == off)        // Wenn Zustand zuvor OFF war
>       {
>         state = on;
>       }
>       else if (state == on)      // Wenn Zustand zuvor ON war

Das ist Unsinn. Wenn nur 2 Zustände möglich sind, dann liegt beim else 
automatisch der andere Zustand vor. Der 2. Test ist daher überflüssig.

von Christoph (christoph13524)


Lesenswert?

Ok, danke für den Hinweis!
Ich weiß, dass es andere und bessere Entprell-Codes gibt, wollte es aber 
nicht zu schwierig für mich machen..

Wäre also das hier ok?
Nach den 20ms nochmal abfragen, ob der Taster immer noch gedrückt ist.
Und statt dem überflüssigen else if nur else geschrieben.
1
 
2
   if (button_down)          // Wenn Taster gedrückt ist
3
    {
4
      _delay_ms(20);          // Prellzeit abwarten
5
      if (button_down)          // Wenn Taster immer noch gedrückt ist
6
      {
7
        if (state == off)        // Wenn Zustand zuvor OFF war
8
        {
9
          state = on;
10
        }
11
        else                 // Wenn Zustand zuvor ON war
12
        {
13
          state = off;
14
        }
15
      }
16
      while (button_down);      // Warten bis Taster losgelassen wird
17
    }

Fehlt noch was? Braucht ein if immer ein else oder so?
LG

von Christoph (christoph13524)


Lesenswert?

Hi,

es klappt einfach nicht, wie es soll.
Der Taster wird nun nach der Codeänderung nicht mehr ausgelöst, jedoch 
passieren wieder zufällig alle paar Minuten andere komische Dinge 
(gerade ist der Fehler erst nach 1 Stunde gekommen).

Die LED ist nun ausgegangen und ich konnte den Taster nicht mehr 
drücken. Einfach keine Funktion mehr... Lüfter und Heizung liefen jedoch 
weiter. Servos haben sich auch nicht verstellt.
Es ist im Code unmöglich, dass die LED ausgeht, ohne dass die Servos 
runter fahren...

Ich glaube nach wie vor, dass ich irgendeine Störung von der 230VAC 
Silikonheizmatte hinein bekomme. Wenn ich diese abstecke, habe ich die 
Probleme noch nie gehabt.

Hat wer eine Idee/Lösungsvorschläge?

Kann man (wenn das Problem wirklich die Heizmatte ist) die Heizmatte im 
Notfall mit Gleichstrom betreiben? Eventuell einfach einen Gleichrichter 
davor packen? Die ist nur ein Heizdraht ohne Elektronik mit 
Bimetall-Sicherung. Hat 400W. Verändert sich dann dadurch die Leistung? 
Wird sowieso auf niedrige 55°C geregelt.
1
#define F_CPU 8000000UL
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>        // f¸r Servo
5
#include <util/delay.h>          // f¸r Zeit
6
7
#define button_down    ((PINC & (1<<PINC0)) && (PINC & (1<<PINB0)))  // Taster gedr¸ckt, wenn PC0 UND PB0 = high
8
9
// Der Prescaler muss so gew‰hlt werden, dass der Ausdruck
10
// f¸r MILLISEC_BASE einen Wert kleiner als 128 ergibt
11
// MILLISEC_BASE ist der Timerwert, der 1 Millisekunde Zeitdauer ergeben
12
// soll.
13
//
14
#define PRESCALER      128
15
#define PRESCALER_BITS ( 1 << CS22) | ( 1 << CS20 )
16
17
#define MILLISEC_BASE  ( F_CPU / PRESCALER / 1000 )
18
#define CENTER         ( MILLISEC_BASE / 2 )
19
20
//
21
// Konfiguration der Servoleitungen
22
//
23
#define NR_SERVOS      8
24
#define SERVO_DDR      DDRD
25
#define SERVO_PORT     PORTD
26
uint8_t ServoPuls[NR_SERVOS] = { 1<<PD1, 1<<PD2 };
27
28
// Werte f¸r die Servoposition
29
// G¸ltige Werte laufen von 0 bis 2 * CENTER
30
// 0           ... ganz links
31
// CENTER      ... Mittelstellung
32
// 2 * CENTER  ... ganz rechts
33
//
34
volatile uint8_t ServoValue[NR_SERVOS];
35
36
ISR (TIMER2_COMP_vect)
37
{
38
  static uint8_t ServoId = 0;
39
40
  //
41
  // den Puls des aktuellen Servos beenden
42
  //
43
  SERVO_PORT &= ~ServoPuls[ServoId];
44
45
  //
46
  // welches ist das n‰chste aktuelle Servo?
47
  //
48
  if( ++ServoId >= NR_SERVOS )
49
  ServoId = 0;
50
51
  //
52
  // die Ausgangsleitung fuer dieses Servo auf 1; den Puls beginnen
53
  //
54
  SERVO_PORT |= ServoPuls[ServoId];
55
56
  //
57
  // den Timer so einstellen, dass bei Pulsende, die ISR erneut aufgerufen wird
58
  //
59
  OCR2 = MILLISEC_BASE + ServoValue[ServoId];
60
}
61
62
void InitServo()
63
{
64
  //
65
  // Die Servoleitungen auf Ausgang stellen
66
  //
67
  SERVO_DDR = ServoPuls[0] | ServoPuls[1] | ServoPuls[2] | ServoPuls[3] |
68
  ServoPuls[4] | ServoPuls[5] | ServoPuls[6] | ServoPuls[7];
69
70
  //
71
  // Timer auf CTC Modus konfigurieren
72
  //
73
  OCR2 = MILLISEC_BASE + ServoValue[0];
74
  TIMSK |= (1<<OCIE2);
75
  TCCR2 = (1<<WGM21) | PRESCALER_BITS;  // CTC mode
76
}
77
78
enum button {off, on} state;        // off=0, on=1
79
80
int main(void)
81
{
82
  InitServo();              // f¸r Servos
83
  sei();                  // f¸r Servos
84
  
85
  state = on;                // Zustand ist am Anfang AN (wegen Stromausfall)
86
  DDRD |= (1<<PD0);            // PD0 auf Ausgang (SSR)
87
  DDRD |= (1<<PD3);            // PD3 auf Ausgang (Wechsler)
88
  DDRB |= (1<<PB3);            // PB3 auf Ausgang (Signal an ATTINY f¸r LED = weifl)
89
  DDRB |= (1<<PB4);            // PB4 auf Ausgang (Signal an ATTINY f¸r LED = orange)
90
  DDRB |= (1<<PB5);            // PB5 auf Ausgang (Signal an ATTINY f¸r LED = orange blinkend)
91
  DDRC &= ~(1<<PINC0);          // PC0 auf Eingang (Taster)  
92
  DDRB &= ~(1<<PINB0);          // PB0 auf Eingang (Taster)  
93
  DDRC &= ~(1<<PINC1);          // PC1 auf Eingang (Niveausonde)  
94
  
95
  uint8_t a = 0;
96
  uint8_t b = 0;
97
  uint16_t i = 0;
98
  
99
    while (1) 
100
    {  
101
    if (button_down)                // Wenn Taster gedr¸ckt ist
102
    {
103
      _delay_ms(20);                // Prellzeit abwarten
104
      if (button_down)              // Wenn Taster immer noch gedr¸ckt ist
105
      {
106
        if (state == off)            // Wenn Zustand zuvor OFF war
107
        {
108
          state = on;
109
        }
110
        else if (state == on)          // Wenn Zustand zuvor ON war
111
        {
112
          state = off;
113
        }
114
      }  
115
      while (button_down);            // Warten bis Taster losgelassen wird
116
    }
117
    
118
    else if (state == on)              // System l‰uft
119
    {
120
      if (b == 0)
121
      {
122
        PORTD |= (1<<PD0);            // SSR an
123
        TCCR2 = (1<<WGM21) | PRESCALER_BITS;  // Timer an
124
        ServoValue[0] = 0.9 * CENTER;      // Servos 1 ZU
125
        ServoValue[1] = 1.93 * CENTER;      // Servos 2 ZU
126
        _delay_ms(2000);
127
        TCCR2 = 0;                // Timer aus
128
        b = 1;
129
        a = 1;    
130
      }
131
132
      if ( !(PINC & (1<<PC1)) )          // Wenn Niveausonde Kontakt hat
133
      {    
134
        PORTD &= ~(1<<PD3);            // Wechsler aus (Ventil ZU)            
135
        PORTB &= ~(1<<PB3);            // LED = weifl = aus
136
        PORTB &= ~(1<<PB5);            // LED = orange blinkend = aus
137
        PORTB |= (1<<PB4);            // LED = orange = an        
138
      }
139
      
140
      else if ( (PINC & (1<<PC1)) && (i == 0) )  // wenn Niveausonde keinen Kontakt hat; i damit nur alle 5 Minuten aufgerufen wird
141
      {
142
        PORTD |= (1<<PD3);            // Wechsler an (Ventil AUF)  
143
        PORTB &= ~(1<<PB5);            // LED = orange blinkend = aus
144
        PORTB &= ~(1<<PB4);            // LED = orange = aus
145
        PORTB |= (1<<PB3);            // LED = weifl = an      
146
      }
147
      
148
      i++;                    // i um 1 erhˆhen
149
      _delay_ms(10);
150
      
151
      if (i >= 30000)                // 10ms * 30000 Durchg‰nge = 5min 
152
      {
153
        i = 0;
154
      }    
155
    }
156
    
157
    else if ( (state == off) && (a == 1) )      // System steht; a == 1 damit die Schleife nur 1 mal durchlaufen wird
158
    {  
159
      PORTD &= ~(1<<PD0);              // SSR aus
160
      PORTD &= ~(1<<PD3);              // Wechsler aus (Ventil ZU)      
161
      PORTB &= ~(1<<PB3);              // LED = weifl = aus        
162
      PORTB &= ~(1<<PB4);              // LED = orange = aus
163
      PORTB |= (1<<PB5);              // LED = orange blinkend = an
164
      _delay_ms(12000);              // Warten bis der L¸fter steht
165
      TCCR2 = (1<<WGM21) | PRESCALER_BITS;    // Timer an
166
      ServoValue[0] = 2.8 * CENTER;        // Servos 1 AUF
167
      ServoValue[1] = -0.8;            // Servos 2 AUF  
168
      PORTB &= ~(1<<PB5);              // LED = orange blinkend = aus  (LED bleibt aus)        
169
      _delay_ms(2000);            
170
      TCCR2 = 0;                  // Timer aus
171
      a = 0;
172
      b = 0;
173
    }
174
    }
175
}

von Peter D. (peda)


Lesenswert?

Christoph K. schrieb:
> es klappt einfach nicht, wie es soll.

Das Problem wird sein, daß die Entprellerei fest mit dem restlichen Code 
verheiratet ist. Damit stören sämtliche Laufzeiten die Tastenabfrage. 
Die kleinsten Änderung an der Laufzeit der Mainloop und die Entprellung 
verhält sich völlig anders und unvorhersehbar.

Es hat schon seinen Grund, warum man Tasten im Timerinterrupt mit einem 
konstanten und definierten Intervall entprellt. Alles andere ist Murks.

Das Arbeiten mit Events ist nicht nur auf dem PC sinnvoll, es entkrampft 
auch vieles auf einem kleinen ATtiny13.

von Christoph (christoph13524)


Lesenswert?

Ok danke! Bevor ich mich ran wage, den Taster nun richtig zu entprellen, 
möcht ich nochmal genau nachhaken:

Die genannten seltsamen Probleme treten auf, OHNE den Taster je gedrückt 
zu haben. Man schaltet die Stromquelle ein und das System ist ja so 
programmiert, dass gleich alles angeht.
Also ohne je den Taster gedrückt zu haben, passieren diese Dinge - das 
heißt ja, dass die derzeitige Entprellroutine nie aufgerufen wurde.
Ist dann deine Behauptung weiterhin möglich?

Hardwareseitig entprellen wäre auch eine Option...

Sonst muss ich mich an das für mich schwierige softwaretechnische 
Entprellen heranwagen - habe ja schon einen Timer für die Servos in 
Verwendung. Und der Attiny85 ist nur als Notlösung da, weil ichs damals 
auch nicht geschafft habe, einen zweiten Timer irgendwie zu starten. 
Naja was solls; muss dann wohl probieren aber brauche wahrscheinlich 
Unterstützung.

von Christoph (christoph13524)


Lesenswert?

Habe hier im Thread https://www.mikrocontroller.net/articles/Entprellung
den Punkt Flankenerkennung entdeckt.
Diese Art von Entprellung wäre doch auch möglich oder? Ganz ohne 
Interrupt.
Ich muss ja nichts zählen mit dem Taster. Der soll ja nur was schalten.

Jedoch verstehe ich nicht, wie bei dieser Methode die Entprellung 
funktioniert. Meiner Logik nach, entprellt hier nichts.
„Die Entprellung geschieht dabei durch die ganze Laufzeit des Programms. 
Die Routine gibt den Zustand 1 für steigende Flanke aus, sonst 0“.

Steigende Flanken habe ich jedoch mehrere während dem Prellen. Also 
schwankt doch der Zustand (rw) während dem Prellen mehrmals zwischen 1 
und 0. Also wird hier gar nichts entprellt? Wo ist mein Denkfehler?

von Christoph (christoph13524)


Lesenswert?

Edit:
Eigentlich bräuchte ich doch gar keine Entprellung.

Wenn der Taster gedrückt wird, führt dieser ja sofort bei der ersten 
Flankenänderung einen Befehl aus. Also schaltet das System gleich ein 
oder aus. Und dieses Ein- oder Ausschalten dauert sowieso deutlich 
länger (durch delays), als dass der Taster prellt.

von Joachim B. (jar)


Lesenswert?

Christoph K. schrieb:
> Edit:
> Eigentlich bräuchte ich doch gar keine Entprellung.

kannst du ja glauben, vielleicht klappts, aber sauber geht anders!

PeDa hats erklärt und das funktioniert sicher!

https://www.mikrocontroller.net/articles/Entprellung

machs im Timer IRQ nach dannegger

von Christoph (christoph13524)


Lesenswert?

Hab jetzt gar keine Entprellung im Code gemacht.
Soweit funktioniert alles wie gehabt. Also Taster kann man normal 
drücken usw.
...bis nach zufälliger Zeit wieder komische Dinge passieren.
.. z.B. Taster nicht mehr drückbar oder LED geht aus (was wie gesagt, 
nicht passieren kann, ohne dass die Servos herunter fahren).

Wenn ich jetzt gar keine Entprellung habe, weil ich diese einfach nicht 
brauche, wo ist der Fehler / wo ist die Störung?

Werde morgen die Silikonheizmatte mit einem Brückengleichrichter mit 
Gleichspannung betreiben. Bimetallschalter habe ich gelesen, darf man 
nicht mit Gleichspannung betreiben.
1
#define F_CPU 8000000UL
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>        // f¸r Servo
5
#include <util/delay.h>          // f¸r Zeit
6
7
#define button_down    ((PINC & (1<<PINC0)) && (PINC & (1<<PINB0)))  // Taster gedr¸ckt, wenn PC0 UND PB0 = high
8
9
// Der Prescaler muss so gew‰hlt werden, dass der Ausdruck
10
// f¸r MILLISEC_BASE einen Wert kleiner als 128 ergibt
11
// MILLISEC_BASE ist der Timerwert, der 1 Millisekunde Zeitdauer ergeben
12
// soll.
13
//
14
#define PRESCALER      128
15
#define PRESCALER_BITS ( 1 << CS22) | ( 1 << CS20 )
16
17
#define MILLISEC_BASE  ( F_CPU / PRESCALER / 1000 )
18
#define CENTER         ( MILLISEC_BASE / 2 )
19
20
//
21
// Konfiguration der Servoleitungen
22
//
23
#define NR_SERVOS      8
24
#define SERVO_DDR      DDRD
25
#define SERVO_PORT     PORTD
26
uint8_t ServoPuls[NR_SERVOS] = { 1<<PD1, 1<<PD2 };
27
28
// Werte f¸r die Servoposition
29
// G¸ltige Werte laufen von 0 bis 2 * CENTER
30
// 0           ... ganz links
31
// CENTER      ... Mittelstellung
32
// 2 * CENTER  ... ganz rechts
33
//
34
volatile uint8_t ServoValue[NR_SERVOS];
35
36
ISR (TIMER2_COMP_vect)
37
{
38
  static uint8_t ServoId = 0;
39
40
  //
41
  // den Puls des aktuellen Servos beenden
42
  //
43
  SERVO_PORT &= ~ServoPuls[ServoId];
44
45
  //
46
  // welches ist das n‰chste aktuelle Servo?
47
  //
48
  if( ++ServoId >= NR_SERVOS )
49
  ServoId = 0;
50
51
  //
52
  // die Ausgangsleitung fuer dieses Servo auf 1; den Puls beginnen
53
  //
54
  SERVO_PORT |= ServoPuls[ServoId];
55
56
  //
57
  // den Timer so einstellen, dass bei Pulsende, die ISR erneut aufgerufen wird
58
  //
59
  OCR2 = MILLISEC_BASE + ServoValue[ServoId];
60
}
61
62
void InitServo()
63
{
64
  //
65
  // Die Servoleitungen auf Ausgang stellen
66
  //
67
  SERVO_DDR = ServoPuls[0] | ServoPuls[1] | ServoPuls[2] | ServoPuls[3] |
68
  ServoPuls[4] | ServoPuls[5] | ServoPuls[6] | ServoPuls[7];
69
70
  //
71
  // Timer auf CTC Modus konfigurieren
72
  //
73
  OCR2 = MILLISEC_BASE + ServoValue[0];
74
  TIMSK |= (1<<OCIE2);
75
  TCCR2 = (1<<WGM21) | PRESCALER_BITS;  // CTC mode
76
}
77
78
enum button {off, on} state;        // off=0, on=1
79
80
int main(void)
81
{
82
  InitServo();              // f¸r Servos
83
  sei();                  // f¸r Servos
84
  
85
  state = on;                // Zustand ist am Anfang AN (wegen Stromausfall)
86
  DDRD |= (1<<PD0);            // PD0 auf Ausgang (SSR)
87
  DDRD |= (1<<PD3);            // PD3 auf Ausgang (Wechsler)
88
  DDRB |= (1<<PB3);            // PB3 auf Ausgang (Signal an ATTINY f¸r LED = weifl)
89
  DDRB |= (1<<PB4);            // PB4 auf Ausgang (Signal an ATTINY f¸r LED = orange)
90
  DDRB |= (1<<PB5);            // PB5 auf Ausgang (Signal an ATTINY f¸r LED = orange blinkend)
91
  DDRC &= ~(1<<PINC0);          // PC0 auf Eingang (Taster)  
92
  DDRB &= ~(1<<PINB0);          // PB0 auf Eingang (Taster)  
93
  DDRC &= ~(1<<PINC1);          // PC1 auf Eingang (Niveausonde)  
94
  
95
  uint8_t a = 0;
96
  uint8_t b = 0;
97
  uint16_t i = 0;
98
  
99
    while (1) 
100
    {  
101
    if (button_down)                // Wenn Taster gedr¸ckt ist
102
    {
103
//      _delay_ms(20);                // Prellzeit abwarten
104
//      if (button_down)              // Wenn Taster immer noch gedr¸ckt ist
105
//      {
106
        if (state == off)            // Wenn Zustand zuvor OFF war
107
        {
108
          state = on;
109
        }
110
        else if (state == on)          // Wenn Zustand zuvor ON war
111
        {
112
          state = off;
113
        }
114
//      }  
115
      while (button_down);            // Warten bis Taster losgelassen wird
116
    }
117
    
118
    if (state == on)                // System l‰uft
119
    {
120
      if (b == 0)
121
      {
122
        PORTD |= (1<<PD0);            // SSR an
123
        TCCR2 = (1<<WGM21) | PRESCALER_BITS;  // Timer an
124
        ServoValue[0] = 0.9 * CENTER;      // Servos 1 ZU
125
        ServoValue[1] = 1.93 * CENTER;      // Servos 2 ZU
126
        _delay_ms(2000);
127
        TCCR2 = 0;                // Timer aus
128
        b = 1;
129
        a = 1;    
130
      }
131
132
      if ( !(PINC & (1<<PC1)) )          // Wenn Niveausonde Kontakt hat
133
      {    
134
        PORTD &= ~(1<<PD3);            // Wechsler aus (Ventil ZU)            
135
        PORTB &= ~(1<<PB3);            // LED = weifl = aus
136
        PORTB &= ~(1<<PB5);            // LED = orange blinkend = aus
137
        PORTB |= (1<<PB4);            // LED = orange = an        
138
      }
139
      
140
      else if ( (PINC & (1<<PC1)) && (i == 0) )  // wenn Niveausonde keinen Kontakt hat; i damit nur alle 5 Minuten aufgerufen wird
141
      {
142
        PORTD |= (1<<PD3);            // Wechsler an (Ventil AUF)  
143
        PORTB &= ~(1<<PB5);            // LED = orange blinkend = aus
144
        PORTB &= ~(1<<PB4);            // LED = orange = aus
145
        PORTB |= (1<<PB3);            // LED = weifl = an      
146
      }
147
      
148
      i++;                    // i um 1 erhˆhen
149
      _delay_ms(10);
150
      
151
      if (i >= 30000)                // 10ms * 30000 Durchg‰nge = 5min 
152
      {
153
        i = 0;
154
      }    
155
    }
156
    
157
    else if ( (state == off) && (a == 1) )      // System steht; a == 1 damit die Schleife nur 1 mal durchlaufen wird
158
    {  
159
      PORTD &= ~(1<<PD0);              // SSR aus
160
      PORTD &= ~(1<<PD3);              // Wechsler aus (Ventil ZU)      
161
      PORTB &= ~(1<<PB3);              // LED = weifl = aus        
162
      PORTB &= ~(1<<PB4);              // LED = orange = aus
163
      PORTB |= (1<<PB5);              // LED = orange blinkend = an
164
      _delay_ms(12000);              // Warten bis der L¸fter steht
165
      TCCR2 = (1<<WGM21) | PRESCALER_BITS;    // Timer an
166
      ServoValue[0] = 2.8 * CENTER;        // Servos 1 AUF
167
      ServoValue[1] = -0.8;            // Servos 2 AUF  
168
      PORTB &= ~(1<<PB5);              // LED = orange blinkend = aus  (LED bleibt aus)        
169
      _delay_ms(2000);            
170
      TCCR2 = 0;                  // Timer aus
171
      a = 0;
172
      b = 0;
173
    }
174
    }
175
}

von Joachim B. (jar)


Lesenswert?

Christoph K. schrieb:
> Wenn ich jetzt gar keine Entprellung habe, weil ich diese einfach nicht
> brauche, wo ist der Fehler / wo ist die Störung?

die kommt wenn du es nicht vermutest, mal eine Funkstörung, mal einen 
Puls auf der Installation.

Sicher geht anders, aber mach wie du denkst und dann komme bitte nicht 
mit unerklärliche sporadische Fehler!
Heulthreads gibts schon genug auf dieser Welt.
Beitrag "uC bleibt hängen - Ursache unklar - Fehler nicht reproduzierbar"

: Bearbeitet durch User
von Christoph (christoph13524)


Lesenswert?

Joachim B. schrieb:
> die kommt wenn du es nicht vermutest, mal eine Funkstörung, mal einen
> Puls auf der Installation.

und genau so eine Störung möchte ich gerne unterbinden, wenn das 
hardwaretechnisch möglich ist. Dafür reicht mein Wissen leider nicht 
aus.

Joachim B. schrieb:
> Heulthreads gibts schon genug auf diese Welt.

Gibt auch genug Threads, wo man seine Aggressionen raus lassen kann...
Immer das selbe hier mit manchen Leuten. Helft, oder lasst es doch 
einfach sein.

Joachim B. schrieb:
> Sicher geht anders,

Das weiß ich. Ich habe einfach nur die Entprellung rausgenommen, da ich 
wissen wollte, ob die das Problem ist oder nicht.
Und meines Wissens nach nicht, wenn ich mir die Ergebnisse anschaue; 
aber belehrt mich gerne anders.

Werde demnächst auch hardwareseitig mal entprellen probieren mit einem 
RC-Tiefpass inkl. 74HC14.

von georg (Gast)


Lesenswert?

Christoph K. schrieb:
> weil ichs damals
> auch nicht geschafft habe, einen zweiten Timer irgendwie zu starten

Must du auch nicht. In einer Timer-Routine mit 1 ms kannst du das 
Entprellen miterledigen. Ich habe oft einen Basis-Timer, der mehrere 
Aufgaben erledigt, je nachdem was gerade anliegt, es darf nur niemals 
länger dauern als die eingestellte Taktzeit.

Praktisch erledigt dieser Timer alles was im Hintergrund laufen soll, 
z.B. Datenempfang über UART, manchmal bleibt für die Main Loop kaum noch 
was übrig. Ausser z.B. auf eine Message die Antwort zusammenszustellen, 
wenn sie vollständig und fehlerfrei empfangen wurde. Gesendet wird die 
Antwort dann wieder im Time Interrupt.

Und der multiplext nebenbei die Anzeige, regelt eine Temperatur, 
schaltet einen Motor ein oder aus...

Georg

von HildeK (Gast)


Lesenswert?

Christoph K. schrieb:
> Ist der Pulldown Widerstand am Taster zu groß/klein? Das Kabel vom
> Taster ist rund 2m lang. Habe gelesen, dass wenn der Pulldown zu groß
> ist, kein eindeutiges 0V-Signal am Mikrocontroller erkannt wird.
>
> Ich bekomme einfach irgendeine Störung an die Leitung vom Taster von
> GND_1 über den Pulldown.
>
> Kann irgendein Kondensator dort helfen?

Ich habe nicht alles gelesen und erst recht nicht deinen Code. Gerade 
Entprellroutinen haben es in sich, man übersieht leicht was. Es gäbe da 
eine schöne und gut funktionierende Vorlage von Peter D.

Mit Hardwaremaßnahmen kann man aber auch eine Menge ausrichten. Auch mit 
der Leitungsführung, auch des GNDs.
Zu dem obigen Punkt ist natürlich 2m Kabel zum Taster eine perfekte 
Quelle für Einstreuungen. Insbesondere wenn du daneben noch kräftige 
Lasten schaltest.
Jedenfalls: die 10k Pulldown am Taster sind entschieden zu hoch. Nimm 1k 
oder sogar 500Ω.
Ein C (10n - 100n) parallel zum Eingang reduziert ebenfalls die 
Empfindlichkeit auf Einstreuungen. Einen 74C14 o.ä. brauchst du nicht, 
der ATMega hat Schmitttriggereingänge. Ich würde mal folgende 
Beschaltung vorschlagen:
1
            VCC              
2
.---------.  +               
3
|         |  |              
4
|     VCC o--o-----------------.          Taster, 2m abgesetzt
5
|         |                    |            .---.
6
|         |                    |            |   |
7
|         |         10k        |           /    o |
8
|         |          ___       'XXXXXXXXXXX       |=|
9
|     PB0 o-----o---|___|--o---'           \    o |
10
|         |     |          |                |   |
11
|         |     |          |                '---'
12
|         |     |         .-.
13
|         |    ===        | |
14
|         |     |  10n    | |500R...1k
15
|         |     |         '-'
16
|     GND o-----o          |
17
|         |     |          |
18
'---------'     o----------'
19
                |
20
               ===
21
               GND
22
(created by AACircuit v1.28.6 beta 04/19/05 www.tech-chat.de)
Die 'XXXXXX' sollen ein verdrilltes Kabel mit den 2m zum Taster 
darstellen.

Ich hoffe, du hast auch nahe an jedem µC die Entkoppelkondensatoren 
nicht vergessen. Ich sehe jedenfalls nur einen eingezeichnet und den 
auch noch eher am Netzteil. Dort könntest du 10µ anbringen und jeweils 
100nF direkt an den Versorgungspins der beiden µCs.

von Joachim B. (jar)


Lesenswert?

Christoph K. schrieb:
> Helft, oder lasst es doch
> einfach sein.

was genau  hast du an:

Joachim B. schrieb:
> PeDa hats erklärt und das funktioniert sicher!
>
> https://www.mikrocontroller.net/articles/Entprellung
>
> machs im Timer IRQ nach dannegger

nicht verstanden?

Christoph K. schrieb:
> da ich
> wissen wollte, ob die das Problem ist oder nicht.
> Und meines Wissens nach nicht, wenn ich mir die Ergebnisse anschaue;

das muss ja nicht der Fehler sein, aber KÖNNTE und deswegen macht man es 
richtig und lässt es drin!
Dann ist zumindest EINE Fehlermöglichkeit schon mal ausgeschlossen!

dein:

Christoph K. schrieb:
> Und meines Wissens nach nicht, wenn ich mir die Ergebnisse anschaue;

ist wie die Momentaufnahme wenn der Chef zur Tür reinschaut und dich mit 
den Kollegen quatschen und kaffeetrinken sieht! aber nie sieht wie du 
schwitzend arbeitest!

von Christoph (christoph13524)


Angehängte Dateien:

Lesenswert?

Danke für die Antworten!

Dieses Entprellverfahren von Dannegger würde ich wenn möglich vermeiden, 
einfach nur, weil meine Fähigkeiten dafür derzeit nicht ausreichen. Da 
schreiben wir sicher Tage hin und her, bis das funktioniert. Vor allem 
weil ich schon einen Timer für die Servos am laufen habe und ich dafür 
auch fast kein Wort verstehe. Alles rauskopiert natürlich.
Würde dieses Entprellverfahren von Dannegger auch eben Störungen 
rausfiltern irgendwie oder ist dieses wirklich nur für das Entprellen 
da?

HildeK schrieb:
> die 10k Pulldown am Taster sind entschieden zu hoch. Nimm 1k
> oder sogar 500Ω.

Werde ich probieren! Das würde man machen, dass der Pin PB0 dann 
sozusagen sicherer mit GND verbunden ist?

Den 10kOhm Widerstand und den Kondensator, den du eingezeichnet hast, 
würde nur die Einstreuung reduzieren? Oder ist das auch als Entprellen 
gedacht? Durch den 10kOhm Widerstand ist man doch dann erst recht bei 
11kOhm dann wieder (10+1)?

Hab vorher schon ein bisschen recherchiert und bin zu dem gleichen 
Schaltplan mit anderen Werten gekommen - was einer Entprellung 
entsprechen sollte. Bild ist angehängt. Mit 1uF, 22kOhm und 10kOhm.

Kabel verdrillen ist ein guter Tipp.

Also morgen kommt der Gleichrichter, den ich probieren werde.
Die Wirbelströme sind dann (laut Recherche) nicht weg, aber kleiner und 
hochfrequenter, weil der Gleichstrom nicht geglättet ist (normaler 
Brückengleichrichter) - behebt eventuell das ganze Problem.

Vorher würde ich dann einfach nur den derzeitigen 10kOhm Pulldown 
austauschen gegen 1kOhm und zusätzlich Kabel verdrillen.

Kondensator hab ich derzeit leider nicht hier.

HildeK schrieb:
> Ich hoffe, du hast auch nahe an jedem µC die Entkoppelkondensatoren
> nicht vergessen. Ich sehe jedenfalls nur einen eingezeichnet und den
> auch noch eher am Netzteil.

Habe tatsächlich nur den 1 eingezeichneten eingebaut.. Den dafür nahe an 
den ATmega8 Kontakten. Der ATtiny ist aber nicht weit entfernt.. Ist das 
ein großes Problem? Hab gelesen, dass man bei "einfachen" Anwendungen 
sogar auf die verzichten kann.

Joachim B. schrieb:
> das muss ja nicht der Fehler sein, aber KÖNNTE und deswegen macht man es
> richtig und lässt es drin!
> Dann ist zumindest EINE Fehlermöglichkeit schon mal ausgeschlossen!

Ja daran wage ich mich, wenn alles scheitert.. wie gesagt, schwer für 
mich die Umsetzung

von Stefan F. (Gast)


Lesenswert?

Christoph K. schrieb:
> Muss ich die GND-Leitungen der beiden Stromversorgungen verbinden?

Ja

> Strom braucht ja immer einen Kreis..

Genau deswegen.

Gegen deine Störungen wird wohl ein R/C Filter (Tiefpass) wirksam sein. 
Du hast zwei Schaltungsvorschläge dazu bekommen, ich finde sie beide OK, 
allerdings kommen mir die 10nF sehr klein bemessen vor. Ich hätte 
mindestens 100nF genommen.

10kΩ * 10nF ergeben nur ungefähr eine Millisekunde. Kürzere Impulse 
werden unterdrückt.

von Peter D. (peda)


Lesenswert?

Du weißt aber schon, daß in den Wartezeiten 12s und 2s bei Dir keine 
Tasten abgefragt werden können. Das ist der Nachteil, wenn die Meinloop 
auch noch entprellen soll.

von Christoph (christoph13524)


Lesenswert?

Ja das weiß ich. Das soll auch so sein - ist sogar gut so.

von Christoph (christoph13524)


Angehängte Dateien:

Lesenswert?

Hi,

hatte die letzten Wochen keine Zeit zu testen aber ab jetzt bin ich 
wieder dran.

Ich habe nun einiges probiert:

1. Habe den Gleichrichter eingebaut - hat nichts gebracht.
2. Habe einige Versuche über mehrere Stunden gemacht OHNE Heizmatte -> 
das System funktioniert einwandfrei. Kein einziges mal ist ein Fehler 
aufgetreten.
3. Heizmatte wieder angeschlossen und nach ein paar Minuten sind die 
ersten Fehler da. Jedes mal.

Die Fehler nochmal zusammengefasst:
1. Taster hat sich nicht mehr drücken lassen, also keine Funktion 
ausgelöst. Nur ein Neustart (Strom aus, an) hilft.
2. Niveausonde hat oft Fehlgeschalten

Den 1. Fehler mit dem Taster habe ich denke ich mit euren Ratschlägen 
behoben.
Ich habe den 10kOhm Pull-Down Widerstand gegen 1kOhm getauscht, sodass 
einfach mehr Strom fließt. Mit Kondensatoren gegen die Störung habe ich 
nichts gemacht. Bis jetzt ist der Taster noch nie "steckengeblieben", 
also denke ich wie gesagt hoffentlich, dass das Problem behoben ist - 
aber mal weiter prüfen.

Außerdem habe ich nun einen 2. 100nF Kondensator für den ATtiny85 
angelötet. Zuvor hatte ich ja nur einen nahe bei dem ATmega8.

2. Fehler mit der Niveausonde ist nach wie vor vorhanden. Alles 
funktioniert jetzt, nur wird öfter mal die Niveausonde Fehlgeschalten. 
Ich denke es ist ein ähnliches Problem wie mit dem Taster - man muss die 
Schaltung "sicherer" auslegen, sodass mehr Strom fließt, damit das 
System nicht so sensibel auf irgendwelche Störungen der Heizmatte 
reagiert.
Habt ihr einen Vorschlag, wie man die Niveausondenelektronik (Transistor 
+ die beiden Widerstände) anpassen könnte? Ich würde meinen, den 
Basiswiderstand auf 10kOhm zu erhöhen (derzeit 5,6kOhm) und den 
10kOhm-Widerstand vor dem Transistor auf 5,6kOhm zu reduzieren.
Die Niveausonde ist, wie in den vorherigen Beiträgen erwähnt, 2 Kontakte 
und wenn Wasser steigt, fließt Strom durch die beiden Kontakte (als 
Taster im Schaltplan angedeutet).

Angefügt der Schaltplan mit den Infos, was ich angepasst habe.

: Bearbeitet durch User
von HildeK (Gast)


Lesenswert?

Christoph K. schrieb:
> Den 10kOhm Widerstand und den Kondensator, den du eingezeichnet hast,
> würde nur die Einstreuung reduzieren? Oder ist das auch als Entprellen
> gedacht?
Beides. Ob ein Wackeln des eingangs durch eine prellende Taste oder 
durch einen Einstreuung hervorgerufen wird, bleibt sich weitgehend 
gleich. Allerdings hatte meine Dimensionierung eher HF-Einstreuungen im 
Fokus. Zum Entprellen sollte man das C deutlich größer machen.
Der niederohmig Pulldown sorgt für mehr Strom durch den Taster, eine 
Einstreuung hat es also schwerer, den Pin zu bewegen.

> Durch den 10kOhm Widerstand ist man doch dann erst recht bei
> 11kOhm dann wieder (10+1)?
Die 10k und der Kondensator sollten auch nahe am Prozessor zu liegen 
kommen. Er Eingang selber ist auch viel höherohmig auf LOW ziehbar.
Mit dem 1k macht man nur die 'Quelle' LOW bei offenem Taster niederohmig 
und damit immuner gegen Einstreuungen.

> Hab vorher schon ein bisschen recherchiert und bin zu dem gleichen
> Schaltplan mit anderen Werten gekommen - was einer Entprellung
> entsprechen sollte. Bild ist angehängt. Mit 1uF, 22kOhm und 10kOhm.
Denn Arbeitswiderstand des Tasters darf hier bei der längeren Leitung 
schon niederohmiger sein, also 1k statt 10k, wie ich schon mehrfach 
genannt habe.
Der verringert nur die Empfindlichkeit auf Einstreuungen und hat wenig 
mit Entprellen zu tun.
Die 22k und 1µ verlängern halt die Zeitkonstante auf 22ms, das wäre mir 
für die Betätigung einer Taste schon etwas zu langsam und so lange 
prellt eh kein Taster. Beim Bedienen musst du dann die Taste u.U. 
mindestens 20-30ms lang drücken, damit die Bedienung erkannt wird. Also: 
kann man auch so machen.

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.