Forum: Mikrocontroller und Digitale Elektronik Arduino Timer für Campingwaschmaschine


von Christoph S. (155christo)


Angehängte Dateien:

Lesenswert?

Guten Tag!
Ich repariere gerade eine Campingwaschmaschine. Das Waschprogramm wurde 
durch einen mechanischen Timer gesteuert.
Dieser hat den Geist aufgegeben. Einige Zahnräder waren völlig 
abgenuddelt. Ich könnte zwar irgendwo in China
einen neuen mechanischen Timer kaufen, aber ich befürchte, dass es 
diesem nach einiger Zeit genauso ergeht.
Also will ich den mechanischen Timer durch einen Arduino und Relais 
ersetzen.
Dafür habe ich das gepostete Programm geschrieben und das Ganze 
entsprechen der beiliegenden Schaltung verdrahtet.
Die Campingwaschmaschine wechselt ca alle 30 Sekunden die Laufrichtung 
des Motors. Dafür wird die Phase abwechselnd
auf unterschiedliche Kontakte des Motorkondensators gelegt.
Ein Bild im Schaltplan zeigt die Details.
Das Programm funktioniert ... im Prinzip.
Ohne Strom auf dem Motor zu geben, also nur das Programm solo, tut was 
es soll. Alle Relais schalten, wie sie sollen.
Jedoch wenn ich den Motor tatsächlich anschließe, bricht das 
Waschprogramm nach kurzer Zeit ab.
Und zwar geschieht dies, wenn der Motor nach einem Wechsel der 
Laufrichtung neu starten soll.
Ich vermute, der Arduino macht an dieser Stelle im Programm einen Reset. 
WARUM?
Produziert der Motor zu viel Störungen, sodass der Arduino aus dem Tritt 
gerät?
Habe ich ein Fehler in Programm?
Ist was an der Schaltung falsch?
Ich bin für Hilfe und Tips dankbar.
Danke fürs Lesen!
1
#include <TimerOne.h>
2
#include <SPI.h>
3
#include <Wire.h>
4
#include <Adafruit_GFX.h>
5
#include <Adafruit_SSD1306.h>
6
#define startPin 2 // 
7
#define stopPin 3 // 
8
#define taktPin 9 // 
9
#define relay1Pin 10 // 
10
#define relay2Pin 11 // 
11
//#define relay3Pin 12 //
12
#define potiPin  A3 // 
13
#define DISPLAY_I2C_ADDRESS 0x3C
14
#define DISPLAY_WIDTH 128  // Breite in Pixeln
15
#define DISPLAY_HEIGHT 32  // Höhe in Pixeln  
16
Adafruit_SSD1306 display(DISPLAY_WIDTH, DISPLAY_HEIGHT, &Wire, -1);
17
// arduino UNO, NANO SDA=A4, SCL=A5
18
19
void setup() {
20
  Serial.begin(9600); //   
21
  pinMode(startPin, INPUT_PULLUP);                                   // Die Buttons schaltem gg GND
22
  pinMode(stopPin, INPUT_PULLUP);
23
  pinMode(taktPin, OUTPUT);
24
  pinMode(relay1Pin, OUTPUT); 
25
  pinMode(relay2Pin, OUTPUT);
26
  pinMode(relay3Pin, OUTPUT); 
27
  Timer1.initialize(1000000);
28
  Timer1.attachInterrupt(blink);                                           // Initialisierung der Timer Interruptroutine mit einer Zeitkonstante von 1 Sekunde
29
  attachInterrupt(digitalPinToInterrupt(stopPin), stop_all, LOW);          // Die Buttons schaltem gg GND, daher Interr.startet mit LOW
30
  attachInterrupt(digitalPinToInterrupt(startPin), Waschroutine, LOW);   // Interrupt schaltet Waschvorgang ein
31
if(!display.begin(SSD1306_SWITCHCAPVCC, DISPLAY_I2C_ADDRESS)) {
32
      Serial.println("SSD1306 nicht gefunden");
33
      }
34
}
35
  
36
int taktstate = LOW;
37
int relay1state = HIGH;                                              //Die Relais schalten bei LOW ein und bei HIGH aus, Anfangswert daher HIGH
38
int relay2state = HIGH;
39
int potiWert = 0;
40
long Einschaltdauer = 0;
41
int Einschaltdauer_now;
42
int Minutendauer = 0;
43
int taktwert = LOW;
44
int startwert = HIGH;                                                //Die Buttons schaltem gg GND, Anfangswert daher HIGH
45
int relaywert = LOW;
46
int relay1wert = LOW;
47
int relay2wert = LOW;
48
int relay3wert = LOW;
49
int relayzeit_now = 0;
50
int zaehler = 0;
51
52
void blink(void)                                                      // Dies ist die Timer Interruptroutine, die einen Takt von 1 Sekunde erzeugt und entsprechend den Taktpin 5 wackeln läßt
53
{
54
  if (taktstate == LOW) {
55
    taktstate =  HIGH;
56
  } else {
57
    taktstate = LOW;
58
  }
59
  digitalWrite(taktPin, taktstate);
60
}
61
62
void loop()
63
{ 
64
Serial.println("Washtimer mit Arduino, Ersatz f. mech Timer. Arduino IDE: Waschzeit_3R_HIGH_01.ino");  
65
  potiWert = analogRead(potiPin);
66
  Einschaltdauer = map(potiWert, 0, 1023, 60 , 900);                   //Dieser Teil bestimmt die Waschzeit. Die Werte des Potis werden gemappt auf die Range
67
  Minutendauer = (Einschaltdauer / 60);                                //von 60 bis 900 Sekunden = 2 Minuten bis 15 Minuten
68
      taktwert = digitalRead(taktPin);     
69
       if (taktwert == 0) {
70
       (Einschaltdauer_now --);                                 
71
       }                   
72
       if (Einschaltdauer_now < 0) {
73
       (Einschaltdauer_now = 0);       
74
       }
75
       if (Einschaltdauer_now != 0) {                           // Das dritte Relais ist eingeschaltet solange die Waschzeit läuft. Damit wird die Phase geschaltet.
76
        (relay3wert = 1);  
77
        }
78
        if (Einschaltdauer_now == 0) {                           // Das dritte Relais ist eingeschaltet solange die Waschzeit läuft. Damit wird die Phase geschaltet.
79
        (relay3wert = 0);  
80
        }       
81
       if (Einschaltdauer_now == 0) {                            // Das dritte Relais wird ausgeschaltet, wenn die Waschzeit abgelaufen ist. 
82
         digitalWrite(relay3Pin, LOW); 
83
       }
84
      if (digitalRead(taktPin) == HIGH) {                        //Beginn der Waschroutine. Es startet eine Zeitschleife von 0 bis 60 Sekunden
85
       (relayzeit_now ++);
86
       }            
87
      if (relayzeit_now == 60) {
88
       (relayzeit_now = 0);       
89
       }
90
      if ((relayzeit_now >=0) && (relayzeit_now <= 2)) relay1wert = 0;         //Hier wird die Zeitschleife genutzt, um die Relais im Rhythmus zu schalten
91
      if ((relayzeit_now >=3) && (relayzeit_now <= 27)) relay1wert = 1;        //relaywert1 schaltet Relay1, Relay1 schaltet die Phase. Jeweils zum Wechsel der Laufrichtung (s.u.)
92
      if ((relayzeit_now >=28) && (relayzeit_now <= 32)) relay1wert = 0;       //ist Relay1 für einige Sekunden auf 0, dazwischen läuft der Motor.
93
      if ((relayzeit_now >=33) && (relayzeit_now <= 57)) relay1wert = 1;  
94
      if ((relayzeit_now >=58) && (relayzeit_now <= 60)) relay1wert = 0;  
95
      if (relay1wert == 1 && Einschaltdauer_now != 0) {                       
96
      digitalWrite(relay1Pin, LOW);                                        // wird, solange die Waschzeit läuft, also nicht 0 ist. Wie ich bemerken muss klappt das nicht. Das Relais schaltet
97
       }                                                                      // auch nachdem die Zeit schon abgelaufen ist. Die Routine kümmert sich nicht um die && Bedingung! WARUM?
98
      if (relay1wert == 0 && Einschaltdauer_now != 0) {
99
         digitalWrite(relay1Pin, HIGH); 
100
       }             
101
      if ((relayzeit_now >=0) && (relayzeit_now <= 29)) digitalWrite(relay2Pin, HIGH); //Diese Routine schaltet das Relais 2 alle 30 Sekunden um. Damit ändert sich die Laufrichtung. (s.o.) 
102
      if ((relayzeit_now >=30) && (relayzeit_now <= 59)) digitalWrite(relay2Pin, LOW);  //Der Wechsel der Laufrichtung ist bei 0 bzw 30 Sekunden 
103
     if (Einschaltdauer_now == 0) digitalWrite(relay1Pin, HIGH);
104
     if (Einschaltdauer_now == 0) digitalWrite(relay2Pin, HIGH); 
105
     if (Einschaltdauer_now == 0) digitalWrite(relay3Pin, HIGH);                  // Ist eigentlich überflüssig. Soll sicherstellen, dass alle Relais aus sind,                        
106
    display.clearDisplay();  // Display(puffer) löschen
107
      display.setTextSize(2);  // zweite Schriftgröße (Höhe 16px)
108
      display.setTextColor(WHITE);  // helle Schrift, dunkler Grund)
109
      display.setCursor(0, 0);  // links oben anfangen
110
      display.print(Minutendauer);
111
      if (Minutendauer == 1) display.print(" Minute");      
112
      if (Minutendauer > 1)display.print(" Minuten");
113
      display.setCursor(0, 18);  // links oben anfangen       
114
      if (Einschaltdauer_now > 1) {
115
      display.print("noch ");
116
      display.print(Einschaltdauer_now);    
117
      }
118
      if (Einschaltdauer_now == 0) {
119
      display.print("Motor aus");          
120
      }
121
      //display.print(Einschaltdauer_now);    
122
      display.display();
123
            
124
//delay(500);                                                                      //delay bleibt nur zum debuggen. Wenn das Programm fertig ist, werden delay und alle Serial.print Anweisungen gelöscht.
125
}
126
127
void Waschroutine()                                                             
128
  {  
129
     Einschaltdauer_now = Einschaltdauer;  
130
    }
131
132
void stop_all()                                                                 //Diese Routine wird mit dem Stopbutton gestartet. Sie setzt alle Waschroutinen aul Null und
133
{                                                                               //schaltet die Relais aus.
134
  Einschaltdauer = 0;
135
  Einschaltdauer_now = 0;  
136
  relaywert = LOW;
137
  startwert = HIGH;                   
138
  digitalWrite(relay1Pin, HIGH);                                                 //Die Relais schalten bei LOW ein und bei HIGH aus
139
 
140
  digitalWrite(relay2Pin, HIGH);
141
  digitalWrite(relay3Pin, HIGH);
142
143
} 
144
Code

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Da wird deine Spannungsversorgung die Grätsche machen, oder die 
Motorstörungen alles durcheinander bringen, oder gleich beides.

Oliver

von Thomas W. (goaty)


Lesenswert?

Als Zustandsmaschine wäre der Code lesbarer.
Ansonsten stört vermutlich der Waschmaschinenmotor die Versorgung vom 
Arduino?

von Michael B. (laberkopp)


Lesenswert?

Christoph S. schrieb:
> Produziert der Motor zu viel Störungen, sodass der Arduino aus dem Tritt
> gerät

Ja.

Deine Schaltung ist nicht ausreichend EMV fest.
Du siehst, warum Störfestigkeit eine Kunst ist, die andere jahrelang 
erlernen.

Dass ein chinesisches Relaismodul nicht ausreichend isoliert um die 230V 
von den 5V fernzuhalten, hast du offenbar verstanden. Warum aber ein 
zweiter Relaissatz, der auch noch die 5V der Arduinoversorgung versauen 
muss, verstehe ich nicht. Ein 5A Schaltnetzteil scheint mir auch 
übertrieben.

https://dse-faq.elektronik-kompendium.de/dse-faq.htm#F.25.2

von Christoph S. (155christo)


Lesenswert?

Danke für die Antworten.
Der Hinweis auf die dse-faq war hilfreich. Dank dafür.
Ich werde also die Stromversorgung überarbeiten. Z.B. Arduino-Strom und 
Relais-Strom von einander trennen und auch für größere räumliche 
Trennung sorgen.
Ich melde mich wieder, wenns klappt. (Auch wenns nicht klappt.)

von Otto (Gast)


Lesenswert?

Hallo,

vermutlich werden Störungen auf den Tastereingängen die Ursache sein.
Die internen pull-up sind zu hochohmig. Versuche es mal mit zusätzlichen 
externen 2k2.

Tasterauswertung über Interrupt ist sowieso problematisch. Weshalb 
pollst du diese nicht einfach?

Gruß Otto

von Christoph S. (155christo)


Lesenswert?

Otto schrieb:

>
> vermutlich werden Störungen auf den Tastereingängen die Ursache sein.
> Die internen pull-up sind zu hochohmig. Versuche es mal mit zusätzlichen
> externen 2k2.

OK, hab ich noch nicht gehört/gelesen. Probier ich aus.

>
> Tasterauswertung über Interrupt ist sowieso problematisch. Weshalb
> pollst du diese nicht einfach?

Warum problematisch? Ich dachte über Interrupt wäre das zuverlässiger?
Aber ich bin nicht so der große µC Crack. Auch meine Kenntnisse in C/C++ 
sind eher bescheiden. Ich bin daher immer für Tips und Neues offen.
Danke für die Hinweise.

von Otto (Gast)


Lesenswert?

Weil ein kurzer Störimpuls reicht, um die jeweilige Funktion auszulösen.

von Sebastian S. (amateur)


Lesenswert?

Vielleicht bist Du einfach nur zu schnell!

Beim Umschalten der Drehrichtung muss die Trommel (Wasser, Wäsche und 
sonstige "Masse") zur Ruhe gekommen sein bevor es in die andere Richtung 
weitergeht.

Der Auszug aus dem Quellcode bringt dabei nicht viel, da es dabei zu 
viele Unklarheiten gibt.

Ich würde es mal testweise mit längeren Ruhephasen versuchen.
Vielleicht wird dabei einfach nur die Versorgung "überlastet".

Eine weitere Möglichkeit wäre es mal mit "ordentlichen" Rampen bei den 
Drehzahländerungen (Richtungsänderungen) zu versuchen.

von Christoph S. (155christo)


Lesenswert?

Otto schrieb:
> Weil ein kurzer Störimpuls reicht, um die jeweilige Funktion auszulösen.

AAAAchso, jetzt hab' ich Deinen Gedanken verstanden:

Der Motor produziert Störimpulse --> Diese erreichen den Taster der für 
"Stop" zuständig ist --> Der Waschvorgang ist beendet.

Also: Taster gegen Störungen schützen und entprellen und die Auswertung 
über pollen. --> Das Ganze wird rebuster.

Danke, probier ich aus.

von Christoph S. (155christo)


Lesenswert?

Sebastian S. schrieb:
> Vielleicht bist Du einfach nur zu schnell!
>
> Beim Umschalten der Drehrichtung muss die Trommel (Wasser, Wäsche und
> sonstige "Masse") zur Ruhe gekommen sein bevor es in die andere Richtung
> weitergeht.
 ..
> Ich würde es mal testweise mit längeren Ruhephasen versuchen.
> Vielleicht wird dabei einfach nur die Versorgung "überlastet".

Guter Gedanke. Noch was zum experimentieren :-))
>
> Eine weitere Möglichkeit wäre es mal mit "ordentlichen" Rampen bei den
> Drehzahländerungen (Richtungsänderungen) zu versuchen.

Ok, muss ich dann nicht den Motor anders anschliessen? Einen TRIAC 
bräuchte ich dann wohl in jedem Fall. Das wäre eine etwas größere 
Operation ...

von LDR (Gast)


Lesenswert?

Christoph S. schrieb:
>>
>> Eine weitere Möglichkeit wäre es mal mit "ordentlichen" Rampen bei den
>> Drehzahländerungen (Richtungsänderungen) zu versuchen.
>
> Ok, muss ich dann nicht den Motor anders anschliessen? Einen TRIAC
> bräuchte ich dann wohl in jedem Fall. Das wäre eine etwas größere
> Operation ...

Das wird doch bei der Campingmaschine nur ein kleines Motörchen sein, da 
muss man keinen Sanftanlauf vorsehen.

von Christoph S. (155christo)


Lesenswert?

LDR schrieb:


> Das wird doch bei der Campingmaschine nur ein kleines Motörchen sein, da
> muss man keinen Sanftanlauf vorsehen.

Auf der Maschine steht irgendwas von 135 Watt...

von LDR (Gast)


Lesenswert?

Christoph S. schrieb:
> LDR schrieb:
>
>> Das wird doch bei der Campingmaschine nur ein kleines Motörchen sein, da
>> muss man keinen Sanftanlauf vorsehen.
>
> Auf der Maschine steht irgendwas von 135 Watt...

Winzig.

von Joe (Gast)


Lesenswert?

An D2 und D3 sollte ist der interne Pullup aktiviert.
Das ist ok, aber dann an D2 und D3 noch einen 1uF bis 10uF Kondensator 
anschließen.
A3 kann auch noch einen solchen Kondensator gebrauchen.

von Manfred (Gast)


Lesenswert?

Christoph S. schrieb:
> Und zwar geschieht dies, wenn der Motor nach einem Wechsel der
> Laufrichtung neu starten soll.

Den Programmcode schaue ich nicht an.
Ist da eine Totzeit drin - also Motor aus, Pause, andere Richtung?

> Ich vermute, der Arduino macht

Ich vermute und frage mal im Forum, anstatt selbst zu suchen?

Der Uno kann problemlos Daten zum PC senden, also ein paar 
serial.print("Text") ins Programm und zugucken, wann / ob der aussteigt.

Eine andere Variante wäre, zu Testzwecken Statusinfos ins OLED zu 
schreiben, der µC hat je jede Menge Langeweile.

Michael B. schrieb:
> Warum aber ein zweiter Relaissatz,
> der auch noch die 5V der Arduinoversorgung versauen
> muss, verstehe ich nicht.

Das ist eine echte Lachnummer, China-Board anstatt zwei Transistoren.

von Otto (Gast)


Lesenswert?

Joe schrieb:

> Das ist ok, aber dann an D2 und D3 noch einen 1uF bis 10uF Kondensator
> anschließen.

Das würde ich lassen. Bei Betätigung der Taster fließt ein großer Strom, 
welcher die Kontakte schädigt.

von Wolfgang S. (wolfgang_s278)


Lesenswert?

Otto schrieb:
> Bei Betätigung der Taster fließt ein großer Strom,
> welcher die Kontakte schädigt.

Super, bei mir laufen derartige Taster seit mehr als 10 Jahren.
Wie groß wäre denn deiner Meinung nach der Strom, der dir Kontakte 
verbrennt?

Dann hängt man halt noch einen 100Ohm Widerstand in die Leitung und ist 
damit das Problem los.

von Otto (Gast)


Lesenswert?

Wolfgang S. schrieb im
> Super, bei mir laufen derartige Taster seit mehr als 10 Jahren.
> Wie groß wäre denn deiner Meinung nach der Strom, der dir Kontakte
> verbrennt?

I=U/R —>  5V / 1 Ohm (Leitung, Steckkontakt) muss der Taster 5A 
vertragen.

> Dann hängt man halt noch einen 100Ohm Widerstand in die Leitung und ist
> damit das Problem los.

ACK

von Michael B. (laberkopp)


Lesenswert?

Sebastian S. schrieb:
> Der Auszug aus dem Quellcode bringt dabei nicht viel, da es dabei zu
> viele Unklarheiten gibt

Hmm, der Prozessor weiss genau, was er tun soll.

Es gibt eigentlich keine klarere Aufgabenbeschreibung als ein Programm.

Kann es sein, dass du sowas nicht lesen kannst?

Wolfgang S. schrieb:
> Super, bei mir laufen derartige Taster seit mehr als 10 Jahren.
> Wie groß wäre denn deiner Meinung nach der Strom, der dir Kontakte
> verbrennt?

Klar. Du gehst auch seit deiner Kindheit bei rot über die Straße.

Der ESR eines 10uF Elkos liegt so bei 2 Ohm, macht an 5V glatt 2.5A, 
dafür sind kleine Taster nicht ausgelegt, es brennt die 
Vergoldungsschicht weg, dann oxidiert der Kontakt, Folge sind 
Kontaktprobleme.

Es ist halt nicht klug, bei rot über die Kreuzung zu gehen, in deinem 
Alter erwischt es dich dann.

Wolfgang S. schrieb:
> Dann hängt man halt noch einen 100Ohm Widerstand in die Leitung und ist
> damit das Problem los.

Ja, so macht man das, wenn es dauerhaft funktionieren soll.

von Christoph S. (155christo)


Angehängte Dateien:

Lesenswert?

Otto hatte recht:

Otto schrieb:
> Hallo,
>
> vermutlich werden Störungen auf den Tastereingängen die Ursache sein.
> Die internen pull-up sind zu hochohmig. Versuche es mal mit zusätzlichen
> externen 2k2.
>
> Tasterauswertung über Interrupt ist sowieso problematisch. Weshalb
> pollst du diese nicht einfach?
>
> Gruß Otto

Ich habe den beiden Tastern jeweils eine Tiefpass-Entprellerschaltung 
gegönnt (siehe Schaltplan), sonst habe ich an der Maschine nichts 
geändert.
Seit dem ist Ruhe und die Maschine läuft.

Ich werde das weiter beobachten und wenn weitere Probleme auftreten die 
Software anpassen und/oder die Stromversorgung überarbeiten.
Dank alle die so konstruktiv mitgewirkt haben.

von Thomas (Gast)


Lesenswert?

Christoph S. schrieb:
> Tiefpass-Entprellerschaltung

Nur aufpassen dass die Kapazität nicht zu groß wird, 50mA Entladestrom 
sind schon reichlich und z.B. bei den üblichen kleinen 
Print-Kurzhub-Tastern an der Grenze.

von Christoph S. (155christo)


Lesenswert?

Thomas schrieb:

> Nur aufpassen dass die Kapazität nicht zu groß wird, 50mA Entladestrom
> sind schon reichlich und z.B. bei den üblichen kleinen
> Print-Kurzhub-Tastern an der Grenze.

Die Taster sind Edelstahl Drucktaster IP65 250V 3A (ist ja eine 
Waschmaschine!). Das sollte schon passen.

von Gerald B. (gerald_b)


Lesenswert?

Joe schrieb:
> Das ist ok, aber dann an D2 und D3 noch einen 1uF bis 10uF Kondensator
> anschließen.
> A3 kann auch noch einen solchen Kondensator gebrauchen.

Haben wir früher bei TTL Logik immer so gemacht. Ein kurzer hoher 
Einschaltstrom ist sogar gut, um Oxidschichten zu durchbrechen, sonst 
funktioniert ein schnöder Messigkontakt irgendwann nicht mehr richtig. 
Im Osten war da nix mit vergoldeten Kontakten, außer es reiste in den 
Weltraum, oder zur Stasi.

von Michael B. (laberkopp)


Lesenswert?

Gerald B. schrieb:
> Haben wir früher ... immer so gemacht

Gerald B. schrieb:
> Im Osten

Daher ist die DDR auch untergegangen.

von Gerald B. (gerald_b)


Lesenswert?

Michael B. schrieb:
> Daher ist die DDR auch untergegangen.

Hätten wir damals so wie heute gewirtschaftet, hätten wir keine 40 Jahre 
durchgehalten
duck und weg

von Manfred (Gast)


Lesenswert?

Christoph S. schrieb:
> Ich habe den beiden Tastern jeweils eine Tiefpass-Entprellerschaltung
> gegönnt

Du hast offenbar den Drang, möglichst viel unsinnigen Aufwand zu 
treiben.

Dir wurde bereits weiter vorne gesagt, dass Tasten im Interrupt wenig 
sinnvoll sind und Du diese einfach pollen kannst. Da reicht ein 
Widerstand, den Rest erledigt die Software.

Falls Dir "pollen" nichts sagt: Es bedeutet, die Leitung regelmäßig 
abzufragen. In der Hauptschleife (void loop()) zyklisch den Port 
abfragen und wenn der sich ändert, das Signal behandeln. Deine 
Waschmaschine und der Mensch am Taster sind aus Sicht des µC unendlich 
langsam, das macht der µC einfach so nebenbei.

Gerald B. schrieb:
> Haben wir früher bei TTL Logik immer so gemacht.

Du vielleicht, korrekte Schaltungen nicht. Die einfachste Möglichkeit 
waren Taster mit Umschaltkontakt an einem RS-FlipFlop. Tastenfelder hat 
man mit einem getakteten D-FF abgefragt. Das war dann kein Bastelkram, 
sondern Seriengeräte mit Tastatur, Display und weiteren Funktionen, wo 
gerne mal 50 Logik-ICs auf der Platine waren, kommerzielle Technik.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Christoph S. schrieb:
> Und zwar geschieht dies, wenn der Motor nach einem Wechsel der
> Laufrichtung neu starten soll.
> Ich vermute, der Arduino macht an dieser Stelle im Programm einen Reset.
> WARUM?
Die üblichen 2 Gründe:
1. dein Schaltungsaufbau ist empfänglich für elektromagnetische 
Störungen
2. deine Software kommt nicht mit Störimpulsen an Eingängen zurecht

> Produziert der Motor zu viel Störungen, sodass der Arduino aus dem Tritt
> gerät?
Ja. Oder besser andersrum: deine Schaltung ist nicht robust genug 
ausgelegt.

> Habe ich ein Fehler in Programm?
Ja. Sogar meherere.
1. du entprellst die externen Eingänge nicht, sondern jeder 
100ns-Störimpuls kann eine Fehlfunktion auslösen, wenn er grade zur 
Unzeit kommt.
2. deine Software kriegt sich nach einem Fehler nicht mehr ein, sondern 
stolpert irgendwo im Nirwana herum und macht, was sie will.

> Ist was an der Schaltung falsch?
Der Pullup im µC ist mit 30..50k viel zu hochohmig. Mein EMV-Spezi sagt: 
alles über 10k ist für die EMV nicht vorhanden. Aus Sicht der EMV ist 
ein CMOS-Eingang mit 30k Pullup also ein offener CMOS-Eingang. Da muss 
ein externer Pullup her. Die 2k2 passen da gut.
Ein zusätzlicher Kondenstaotr sorgt dafür, dass kurze ESD/EMV-Spikes 
nicht gleich den Pegel am Pin umschalten. Das sollte aber ein Kerko sein 
und der sollte dicht am µC-Pin sein.

> Ich habe den beiden Tastern jeweils eine Tiefpass-Entprellerschaltung
> gegönnt (siehe Schaltplan), sonst habe ich an der Maschine nichts
> geändert.
Nur zur Berichtigung: da ist weit und breit keine Entprellung. Das ist 
lediglich ein Tiefpass.

> Seit dem ist Ruhe und die Maschine läuft.
Du hast mit diesem RC-Tiefpass lediglich die Wahrscheinlichkeit eines 
Fehlers reduziert. Denn der Fehler ist nach wie vor der selbe: deine 
Software ist für ideale Digitalsignale geschrieben, sie kommt nicht mit 
kurzen EMV/ESD-Spikes zurecht.

> Ich bin für Hilfe und Tips dankbar.
> void blink(void)                                                      //
> Dies ist die Timer Interruptroutine, die einen Takt von 1 Sekunde
> erzeugt und entsprechend den Taktpin 5 wackeln läßt
Kennst du schon die millis()? Das ist die coolste "Funktion" im Arduino 
schlechthin.

Wofür oder wogegen sind denn eigentlich die D1 und die D2?

Wofür ist das China-Relaismodul? Würde da nicht ein Transistor als 
Treiber für die Umschaltrelais ausreichen?

Und noch was: schreib statt relay einfach Relais, dann liest sich 
die RelaisZeit statt relayzeit auch nicht so holprig. Und statt 
relay1wert könntest du einfach Relais1 schreiben, denn dass diese 
Variable einen "Wert" enthält ist implizit jedem klar.
Allerdings könntest du satt irgendwelchen Relais auch die Funktion 
dort hinschreiben:
Motor und dann noch Werte dafür definieren wie z.B. Aus = 0, Links = 
1, Rechts = 2.

Also etwa so:
1
:
2
enum {AUS = 0, LINKS, RECHTS}
3
uint8_t Motor = AUS;
4
:
5
:
6
void loop()
7
{ 
8
:
9
   if ...
10
      Motor = AUS;
11
   :
12
   :
13
   if ...
14
      Motor =  LINKS;
15
   :
16
   :
17
   if ...
18
      Motor =  RECHTS;
19
   :
20
   :
21
   switch (Motor) {
22
      case LINKS :   digitalWrite(relay1Pin, LOW);  // Richtung
23
                     digitalWrite(relay1Pin, HIGH); // Motor ein
24
                     break;
25
      case RECHTS :  digitalWrite(relay1Pin, HIGH;  // Richtung
26
                     digitalWrite(relay1Pin, HIGH); // Motor aus
27
                     break;
28
      default :      digitalWrite(relay1Pin, HIGH); // Motor aus
29
   }
30
:
31
:
32
}
Sinnigerweise führt man noch ein Timeout ein, dass nach einem AUS nicht 
sofort beide Relais umgeschaltet werden, sondern erst die Richtung 
gesetzt wird und z.B. 200ms später der Motor eingeschaltet wird. Also so 
etwa:
1
:
2
int Totzeit;
3
:
4
:
5
   switch (Motor) {
6
      case LINKS :   digitalWrite(relay1Pin, LOW);     // erst Richtung setzen
7
                     if (millis()-Totzeit>200)         // und erst später
8
                        digitalWrite(relay1Pin, HIGH); // Motor ein
9
                     break;
10
      case RECHTS :  digitalWrite(relay1Pin, HIGH;     // erst Richtung setzen
11
                     if (millis()-Totzeit>200)         // und dann später
12
                        digitalWrite(relay1Pin, HIGH); // Motor ein
13
                     break;
14
      default :      digitalWrite(relay1Pin, HIGH);    // Motor aus
15
                     Totzeit = millis();
16
   }
17
:
18
:

: Bearbeitet durch Moderator
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.