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
Galvanische Trennung geht gut mit einem AQY212 Halbleiterrelais.
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.
Christoph K. schrieb: > Ich möchte wissen ob das funktioniert: Nein, das funktioniert nicht! Die GNDs müssen verbunden sein.
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...
Google kaputt? https://www.google.com/search?q=optokoppler+arduino&safe=active&sxsrf=ALeKk00VhipOnlhQQE2_bEAVd3HnMDP5NA:1599720832026&tbm=isch&source=iu&ictx=1&fir=KMGDyZi4R6p1GM%252CcRdqtw9dXDlJxM%252C_&vet=1&usg=AI4_-kQUsdiI2xW4eMpVo36OzJv1iXQ_Wg&sa=X&ved=2ahUKEwit1bq_gN7rAhWUTxUIHb_DA6sQ9QF6BAgKEEg&biw=1920&bih=962#imgrc=KMGDyZi4R6p1GM Es gibt 100 Beispiele da.
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) |
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. ;-)
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.
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
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.
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
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 | }
|
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.
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
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 | }
|
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.
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.
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?
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.
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
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 | }
|
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
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.
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
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.
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!
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
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.
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.
Ja das weiß ich. Das soll auch so sein - ist sogar gut so.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.