Go Down

Topic: Einsteiger braucht Programmierhilfe (Read 3 times) previous topic - next topic

maverick1509

hallo,
ich glaube das war so eines:
http://www.ebay.de/itm/2-Kanal-5V-Relay-Relais-Module-Modul-Arduino-ARM-MSP430-8051-AVR-/200718454506?pt=Elektromechanische_Bauelemente&hash=item2ebbc08eea#ht_3710wt_1139

aber trotz dreier Kontakte war das Relais ein Schließer und hatte keinen Umschaltkontakt.
Und der war stromlos geschlossen und das steht nicht in der Beschreibung.

sth77

Also das Ding aus dem eBay-Amgebot hat definitiv einen Umschltkontakt. Zum einen muss Relais-seitig das vorgegeben sein (und das ist beim SRD-05VDC-SL-C der Fall), zum anderen müssen die Leiterbahnen auch an die Kontakte geführt werden. In der Angebotsbeschreibung ist auch die Rückseite der Platine abgebildet, da kann man das auch erkennen. Zudem sind die Klemmen K1 und K2 auch entsprechend dargestellt.
Daher meine Frage nochmal, was für ein Produkt ist das denn vom Threadstarter? ;)
Mein Arduino-Blog: http://www.sth77.de/ - letzte Einträge: Teensy 3.0 - Teensyduino unter Window 7 - Teensyduino unter Windows 8

keraino

Also die Relaiskarte ist auch von ebay
http://www.ebay.de/itm/DE-Lager-16-Kanal-5V-Relaismodul-Relay-Board-Module-Arduino-MSP430-TTL-Logik-/220959767873?pt=Elektromechanische_Bauelemente&hash=item33723a7d41

Ja das bringt wirklich Probleme musste ich nun feststellen. Glaubte ja die Sache zu überlisten indem ich den Taster gegen GND schalte anstatt gegen +5V, damit ist der Anfangsschaltzustand der Relais LOW. Vom Prinzip her klappt das auch, nur wenn der Arduino startet, man ihn Resetet oder ihm ein code raufläd, schalten die Relais für einen ganz kurzen Moment an und fallen dann ab. Das kann ich so nicht gebrauchen an den Relais sollen Magnetschalter angeschlossen werden und die dürfen natürlich nicht einfach mal "unkontrolliert in die Hände klatschen"  :(
Da nützt es auch nichts den Umschalt Kontakt zu benutzen, das würde wiederum bedeuten wenn die Relaiskarte Stromlos ist, ziehen die Magnetschalter an.
Ich verstehe das ohnehin nicht, alle anderen Relais der Karte denen ich noch kein Output vom Arduino zugewiesen hab sind ja auch auf LOW, wieso sind die Relais auf HIGH wenn Arduino LOW sendet und umgekehrt???

keraino

Also die Relaiskarte ist wirklich Mist, sie schaltet wenn GND an einem Eingangspin anliegt.
Werde mir jetzt selbst eine bauen nach diesem Vorbild http://www.loetstelle.net/projekte/relaiskarte/relaiskarte.php habe schon mit den Bauteilen auf dem Breadboard getestet. Es funktioniert wie es soll, wenn Arduino HIGH sendet schalten auch die Relais auf HIGH.
Vielen Dank nochmal an maverick1509 auch der Automatik Code
Code: [Select]
#define Taster 3
#define Relais2 5 
#define Relais3 6 

long start;

//---------------------------------------------------------------------------------
void setup(){
pinMode(Taster, INPUT);
pinMode(Relais2, OUTPUT);
pinMode(Relais3, OUTPUT);
}
//---------------------------------------------------------------------------------
void automatik(){
start=millis();
while ((millis()-start) < 30000){
  digitalWrite(Relais2,HIGH);
  if (((millis()-start) > 5000) && ((millis()-start)) < 15000)
    digitalWrite(Relais3,HIGH);
   else
    digitalWrite(Relais3,LOW);
}
digitalWrite(Relais2,LOW);
}
//---------------------------------------------------------------------------------
void loop(){
if (digitalRead(Taster) == HIGH ) {
  delay(100);
automatik();
}
}

funktioniert wie ich es mir vorgestellt habe, es wäre nett wenn Du mir noch sagen könntest wie man den Code richtig auf weitere Relais erweitern kann.
Oder falls es jemand anderes weiss kann er es gern mitteilen  :)

maverick1509

Hallo,
also Erweiterung bedarf schon noch einiger Infos, das ist nicht ganz so einfach. Ich hab ja geschrieben, das der Sketch so funktioniert,
ABER durch die "while" Schleife hängt sich das Programm ja für 30 Sek in der Prozedur "Automatik" auf.
In dieser Zeit sind keine weiteren Tastereingaben möglich. Wenn du mehrere Taster parallel betreiben willst, die verschiedene Relais
schalten sollen, dann wird es komplizierter. Soll das so sein? Da bedarf es noch näherer Infos.
Gruß
Bernward

keraino

Hallo maverick1509,
Danke für Deine Bereitschaft mir zu Helfen.
Also Konkret soll das Ganze im Endstadium folgendermassen funktionieren.

Es sind insgesamt 14 Relais zu steuern.
- 2 sollen ausschliesslich mit Taster als Schalter per Hand funktionieren haben wir ja schon  :)
- 12 sollen mit Taster als Schalter per Hand funktionieren und per zeitlichen Ablauf steuerbar sein,
wobei die Handsteuerung der Relais übergeordnet sein soll. Heisst auch wenn die Automatik abläuft sollen die Relais noch per Hand steuerbar sein

- es soll 3 Automatik Modi geben
- AutomatikA betätigt mit Taster AutomatikA = Relais 1-6 schalten nach einem zeitlich vorgegebenen Ablauf (wie es in Deinem Code schon funktioniert nur mit 6 Relais und Relais1 soll auf HIGH bleiben nach Ablauf)
- AutomatikB betätigt mit Taster AutomatikB = Relais 1 und 7-11 schalten nach einem zeitlich vorgegebenen Ablauf (Im Grunde wie AutomatikA)
- AutomatikC betätigt mit Taster AutomatikC = AutomatikA & AutomatikB laufen gleichzeitig ab.

Ich hoffe das ist jetzt nicht zu viel  :*

maverick1509

Oje, das ist aber viel auf einmal, da muss man aber schon einiges an Zeit investieren.
Ganz schön sportlich für einen Anfänger.

keraino

Ja ich dachte auch das ist einfacher  :*
Kleine Korrektur noch, die Handsteurung soll doch nicht über der Automatik stehen.
Ich habe jetzt mal beide Codes zusammen geführt und vom Prinzip her funktioniert es schon so wie es soll nur halt mit zu wenig Tastern und Relais und erstmal mit einem Automatik Mode
Code: [Select]

#define TasterA 2
#define Taster1 10
#define Taster2 9
#define Taster3 8
#define Relais1 24
#define Relais2 22
#define Relais3 23
long start;
boolean Letzter, Aktuell, onoff;
boolean Letzter1, Aktuell1, onoff1;
boolean Letzter2, Aktuell2, onoff2;
//---------------------------------------------------------------------------------
void setup(){
pinMode(TasterA, INPUT);
pinMode(Taster1, INPUT);
pinMode(Taster2, INPUT);
pinMode(Taster3, INPUT);
pinMode(Relais1, OUTPUT);
pinMode(Relais2, OUTPUT);
pinMode(Relais3, OUTPUT);
}

//---------------------------------------------------------------------------------
void automatik(){
start=millis();
while ((millis()-start) < 15000){
  digitalWrite(Relais2,HIGH);
  if (((millis()-start) > 14500) && ((millis()-start)) < 15000)
    digitalWrite(Relais3,HIGH);
   else
    digitalWrite(Relais3,LOW);
}
digitalWrite(Relais2,LOW);
}
//---------------------------------------------------------------------------------
void loop(){
Letzter = Aktuell;
if (digitalRead(Taster1) == HIGH ) Aktuell = true; else Aktuell = false; //auslesen des Tasters
  delay(50);
  if(!Letzter && Aktuell){ // reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
   if (onoff)
     digitalWrite(Relais1,LOW);
    else 
     digitalWrite(Relais1,HIGH);
  onoff = !onoff;
}

Letzter1 = Aktuell1;
if (digitalRead(Taster2) == HIGH ) Aktuell1 = true; else Aktuell1 = false; //auslesen des Tasters
  delay(50);
  if(!Letzter1 && Aktuell1){ // reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
   if (onoff1)
     digitalWrite(Relais2,LOW);
    else 
     digitalWrite(Relais2,HIGH);
  onoff1 = !onoff1;
}

  Letzter2 = Aktuell2;
if (digitalRead(Taster3) == HIGH ) Aktuell2 = true; else Aktuell2 = false; //auslesen des Tasters
  delay(50);
  if(!Letzter2 && Aktuell2){ // reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
   if (onoff2)
     digitalWrite(Relais3,LOW);
    else 
     digitalWrite(Relais3,HIGH);
  onoff2 = !onoff2;
}
if (digitalRead(TasterA) == HIGH ) {
  delay(100);
automatik();
}
}

maverick1509

den manuellen Teil erweitern sollte ja kein Problem sein,einfach mehr Taster, Relais und Variablen.
Probleme sehe ich Moment beim Automatik-Teil. Der muss komplett anders aufgesetzt werden, da ja
wie schon gesagt in der Automatik-Schleife das eigentliche "Void..loop" unterbrochen wird. 

keraino

Hallo maverick1509 und alle anderen natürlich auch  :),
habe mir jetzt den Code mal so erweitert wie es für die AutomatikA ablaufen soll.

Ist das jetzt generell ein Problem das der eigentliche "Void..loop" unterbrochen wird? Das verhindert ja auch in gewisserweise das die "Handsteuerung" wärend des Ablaufs nicht reagiert, was von mir ja eigentlich auch gewollt ist.

Code: [Select]

#define TasterA 2   
#define Taster1 3   
#define Taster2 4   
#define Taster3 5   
#define Taster4 6   
#define Taster5 7   
#define Taster6 8   
#define Taster7 9   
#define Taster8 10 

#define LedA 12     
#define Relais1 22 
#define Relais2 23 
#define Relais3 24 
#define Relais4 25 
#define Relais5 26 
#define Relais6 27 
#define Relais7 28 
#define Relais8 29 

long start;
boolean Letzter1, Aktuell1, onoff1;
boolean Letzter2, Aktuell2, onoff2;
boolean Letzter3, Aktuell3, onoff3;
boolean Letzter4, Aktuell4, onoff4;
boolean Letzter5, Aktuell5, onoff5;
boolean Letzter6, Aktuell6, onoff6;
boolean Letzter7, Aktuell7, onoff7;
boolean Letzter8, Aktuell8, onoff8;

//---------------------------------------------------------------------------------
void setup(){
pinMode(TasterA, INPUT);
pinMode(Taster1, INPUT);
pinMode(Taster2, INPUT);
pinMode(Taster3, INPUT);
pinMode(Taster4, INPUT);
pinMode(Taster5, INPUT);
pinMode(Taster6, INPUT);
pinMode(Taster7, INPUT);
pinMode(Taster8, INPUT);

pinMode(LedA, OUTPUT);
pinMode(Relais1, OUTPUT);
pinMode(Relais2, OUTPUT);
pinMode(Relais3, OUTPUT);
pinMode(Relais4, OUTPUT);
pinMode(Relais5, OUTPUT);
pinMode(Relais6, OUTPUT);
pinMode(Relais7, OUTPUT);
pinMode(Relais8, OUTPUT);
}

//----------------------------Automatikteil
void automatik(){
start=millis();
while ((millis()-start) < 10000){
  digitalWrite(Relais1,HIGH);
  digitalWrite(Relais3,HIGH);
  digitalWrite(LedA,HIGH);
  if (((millis()-start) > 1000) && ((millis()-start)) < 9000)
    digitalWrite(Relais2,HIGH);
   else
    digitalWrite(Relais2,LOW);
  if (((millis()-start) > 3000) && ((millis()-start)) < 8000)
    digitalWrite(Relais4,HIGH);
   else
    digitalWrite(Relais4,LOW);
  if (((millis()-start) > 2000) && ((millis()-start)) < 7000)
    digitalWrite(Relais5,HIGH);
   else
    digitalWrite(Relais5,LOW);
  if (((millis()-start) > 7000) && ((millis()-start)) < 11000)
    digitalWrite(Relais6,HIGH);
   else
    digitalWrite(Relais6,LOW);
}
digitalWrite(Relais1,HIGH);
digitalWrite(Relais3,LOW);
digitalWrite(LedA,LOW);
}
//---------------------------Handsteurungsteil
void loop(){

Letzter1 = Aktuell1;
if (digitalRead(Taster1) == HIGH ) Aktuell1 = true; else Aktuell1 = false; //auslesen des Tasters
  delay(100);
  if(!Letzter1 && Aktuell1){ // reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
   if (onoff1)
     digitalWrite(Relais1,LOW);
    else 
     digitalWrite(Relais1,HIGH);
  onoff1 = !onoff1;
}

  Letzter2 = Aktuell2;
if (digitalRead(Taster2) == HIGH ) Aktuell2 = true; else Aktuell2 = false; //auslesen des Tasters
  delay(100);
  if(!Letzter2 && Aktuell2){ // reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
   if (onoff2)
     digitalWrite(Relais2,LOW);
    else 
     digitalWrite(Relais2,HIGH);
  onoff2 = !onoff2;
}

  Letzter3 = Aktuell3;
if (digitalRead(Taster3) == HIGH ) Aktuell3 = true; else Aktuell3 = false; //auslesen des Tasters
  delay(100);
  if(!Letzter3 && Aktuell3){ // reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
   if (onoff3)
     digitalWrite(Relais3,LOW);
    else 
     digitalWrite(Relais3,HIGH);
  onoff3 = !onoff3;
}

  Letzter4 = Aktuell4;
if (digitalRead(Taster4) == HIGH ) Aktuell4 = true; else Aktuell4 = false; //auslesen des Tasters
  delay(100);
  if(!Letzter4 && Aktuell4){ // reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
   if (onoff4)
     digitalWrite(Relais4,LOW);
    else 
     digitalWrite(Relais4,HIGH);
  onoff4 = !onoff4;
}

  Letzter5 = Aktuell5;
if (digitalRead(Taster5) == HIGH ) Aktuell5 = true; else Aktuell5 = false; //auslesen des Tasters
  delay(100);
  if(!Letzter5 && Aktuell5){ // reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
   if (onoff5)
     digitalWrite(Relais5,LOW);
    else 
     digitalWrite(Relais5,HIGH);
  onoff5 = !onoff5;
}

  Letzter6 = Aktuell6;
if (digitalRead(Taster6) == HIGH ) Aktuell6 = true; else Aktuell6 = false; //auslesen des Tasters
  delay(100);
  if(!Letzter6 && Aktuell6){ // reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
   if (onoff6)
     digitalWrite(Relais6,LOW);
    else 
     digitalWrite(Relais6,HIGH);
  onoff6 = !onoff6;
}

  Letzter7 = Aktuell7;
if (digitalRead(Taster7) == HIGH ) Aktuell7 = true; else Aktuell7 = false; //auslesen des Tasters
  delay(100);
  if(!Letzter7 && Aktuell7){ // reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
   if (onoff7)
     digitalWrite(Relais7,LOW);
    else 
     digitalWrite(Relais7,HIGH);
  onoff7 = !onoff7;
}

  Letzter8 = Aktuell8;
if (digitalRead(Taster8) == HIGH ) Aktuell8 = true; else Aktuell8 = false; //auslesen des Tasters
  delay(100);
  if(!Letzter8 && Aktuell8){ // reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
   if (onoff8)
     digitalWrite(Relais8,LOW);
    else 
     digitalWrite(Relais8,HIGH);
  onoff8 = !onoff8;
}



if (digitalRead(TasterA) == HIGH ) {
  delay(100);
automatik();
}
}


Hätte da noch 1-2 Fragen  :*
- Relais5 soll nach Programmende auf HIGH bleiben und bei Programmstart auch auf HIGH bis 2000ms dann LOW und bei 7000ms wieder HIGH und bleiben.
habs erstmal improvisiert mit dem auf HIGH bleiben, wie kann man das besser machen?
- zum Taster entprellen wird ja erstmal delay 100 benutzt, wie kann man auch dieses besser machen?

maverick1509

#25
Mar 07, 2012, 12:19 pm Last Edit: Mar 07, 2012, 12:22 pm by maverick1509 Reason: 1
Hallo keraino,
es ist kein wirkliches Problem, wenn die Loop unterbrochen wird, ist allerdings nicht bester Programmierstil,
aber da sind wir ja noch nicht, verbessern kann man immer.
Das mit dem delay(100) würde ich erst einmal so lassen.
Aber hier mal ein Tipp, wie man das Programm übersichtlicher machen kann.
Wenn man 8 mal das gleiche macht, sollte man Felder deklarieren, dann wird alles übersichtlicher.
Was in deiner Schleife die Relais 1 bis 8 machen geht auch so:
wobei ich jetzt nicht drauf geachtet habe, ob alle Ports richtig sind.
Und i<8 weil Felder immer ab 0 gezählt werden, d.h. Relais[0] ist das erste Relais u.s.w.
:-) sieht doch besser aus, oder :-)
Code: [Select]

#define LedA 12
int Taster[]= {2,3,4,5,6,7,8,9,10};
int Relais[] = {22,23,24,25,26,27,28,29};

long start;
boolean Letzter[8], Aktuell[8], onoff[8];
int i;
//---------------------------------------------------------------------------------
void setup(){
pinMode(LedA, OUTPUT);
for (int i = 0; i < 8; i++){
  pinMode(Taster[i],OUTPUT);
  pinMode(Relais[i],OUTPUT);
}
}
//---------------------------Handsteurungsteil
void loop(){
for (i==0;i<8;i++){
 Letzter[i] = Aktuell[i];
if (digitalRead(Taster[i]) == HIGH ) Aktuell[i] = true; else Aktuell[i] = false; //auslesen des Tasters
 delay(100);
 if(!Letzter[i]&& Aktuell[i]){ // reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
  if (onoff[i])
    digitalWrite(Relais[i],LOW);
   else  
    digitalWrite(Relais[i],HIGH);
 onoff[i] = !onoff[i];
}
}
}

keraino

#26
Mar 07, 2012, 03:11 pm Last Edit: Mar 07, 2012, 03:18 pm by keraino Reason: 1
Danke meverick1509 für die Einkürzung.
In Deinem Code waren 2 Fehler, wolltest Du mich testen  :) ?
Code: [Select]
pinMode(Taster[i],OUTPUT); musste INPUT heissen und hier
Code: [Select]
void loop(){
for (i==0;i<8;i++){
war ein = zu viel. Habs durch probieren rausgefunden, aber gut so. Ich wills ja auch lernen und nicht nur die "Guttenberg Copy & Paste Methode"  XD
Mit dem delay100 hab ich das Gefühl je mehr Taster ich in den Code reinnehme, desto schlechter reagieren die, kann das so sein? Daher hab ich mal auf delay10 verkleinert.


sth77

Das delay greift ja nur, wenn der Taster tatsächlich gedrückt wurde. Daher verschlechtert sich das Verhalten nicht bei bloßer Erhöhung der Tasterzahl. Eine Verringerung der Pausenzeit kann zur Folge haben, dass dein Taster wieder prellt, welche Mindestzeit möglich ist kann man eigentlich nur durch Ausprobieren herausfinden.
Die Wikipedia schreibt hierzu: "Typische Prellzeiten bei elektromechanischen Schaltern und Tastern liegen im Zeitbereich einiger 100 µs bis in den Zeitbereich zu einigen 10 Millisekunden." Von daher ist der Ansatz 100 ms schon richtig, wenn man vom worst case ausgeht.
Mein Arduino-Blog: http://www.sth77.de/ - letzte Einträge: Teensy 3.0 - Teensyduino unter Window 7 - Teensyduino unter Windows 8

keraino

Also wenn der Taster prellen würde, würde sich das ja auf das Relais übertragen und dieses statt sauber zu schalten, klackern oder schnarren oder wie auch immer, richtig? Konnte ich jetzt so aber noch nicht feststellen.

Joghurt

Nicht zwangsweise, wenn die träger sind als der Schalter prellt hörst Du das nicht, der Arduino wird dann nur einzelne Phasen überspringen, wenn das Programm hinter dem Taster so angelegt ist...

Go Up