Go Down

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

keraino

Hallo, ich würde mir gern eine kleine Steuerung aufbauen. Die Hardware habe ich (Arduino Mega und eine 16 Kanal Relaiskarte) beide sind schon verbunden und funktionieren auch technisch. Mit dem Anfänger Sketch "Blink" alle Relais schon einmal ausprobiert. Nur das die Relais auf OUTPUT LOW anziehen und auf HIGH abfallen, das ist aber kein Problem denke ich, muss man halt umdenken.
Nur am programmieren haperts jetzt bei mir.
Ich bräuchte folgende eigentlich simple Funktionen:

1.Anforderung:
Taster 1 gedrückt - Relais 1 schaltet an und bleibt an bis man Taster 1 ein weiteres mal drückt Taster 1 erneut drücken - Relais 1 schaltet wieder an... usw, also Taster als Schalter sozusagen. Das kann man denn ja kopieren für Taster 2 -Relais 2 u.s.w.
Habe in den Beispielsketches immer nur Taster gedrückt LED an, Taster loslassen LED aus gefunden.

2.Anforderung
Taster Automatik soll einen Zeitlichen Ablauf starten.
Taster Automatik drücken Relais 2 schaltet,hält für ca 30s fällt dann ab, Relais 3 schaltet nach 5s
hält dann für 10s und fällt dann ab. Das ganze auf weitere Relais, wenn man das Grundprinzip weiss kann man es ja erweitern.
Wichtig wäre nur das der Ablauf immer bis zum Ende ausgeführt wird, egal ob man den Automatiktaster zwischendrin betätigt und das der Ablauf immer am Anfang startet.

Für eure Programmiertipps wäre ich sehr dankbar.

Joghurt

Mach Dich mal mit dem Thema "Debounce" oder "Entprellen" vertraut, z.B. hier.

sth77

Immer Schritt für Schritt vorgehen, daher erst einmal die Vorgehensweise für die erste Anforderung:
Um es möglichst übersichtlich und den Quellcode leicht verständlich zu gestalten, solltest ein sogenanntes Flag setzen, wenn der Taster gedrückt wird. Das ist eine einfache Variable, die den Zustand High bzw. Low annehmen kann, meinetwegen auch 1 oder 0. Dann ist die Abfolge (also die loop) in etwa so:

- wenn Taster gedrückt und Flag ist 0 dann setze Flag auf 1
- wenn Taster gedrückt und Flag ist 1 dann setze Flag auf 0
- wenn Flag auf 1 steht: Relais anschalten
- wenn Flag auf 0 steht: Relais ausschalten

Taster sollte man zusätzlich noch entprellen, wie Joghurt bereits anmerkte.
Mein Arduino-Blog: http://www.sth77.de/ - letzte Einträge: Teensy 3.0 - Teensyduino unter Window 7 - Teensyduino unter Windows 8

Joghurt


- wenn Taster gedrückt und Flag ist 0 dann setze Flag auf 1
- wenn Taster gedrückt und Flag ist 1 dann setze Flag auf 0

...wobei darauf zu achten ist dass das Flag nur ein Mal pro Tastendruck umgesetzt wird, daher auch die Sache mit dem Debounce. ;)

Das kannst Du realisieren, indem Du Dir am Ende der Schleife den Zustand des (entprellten) Tasters merkst, und das Flag nur umsetzt, wenn der Taster "an" ist und der Gemerkte Zustand "aus" anzeigt.

Was in der Richtung:
Code: [Select]

  if (lastButtonState == LOW && debouncedButton() == HIGH) {
    flag = !flag; // Umschalten
  }
  lastButtonState = debouncedButton();

maverick1509

#4
Mar 02, 2012, 11:15 am Last Edit: Mar 02, 2012, 11:17 am by maverick1509 Reason: 1
wie schon die Vorgänger geschrieben haben must du dich mit entprellen beschäftigen.
Für den Anfang geht es so, das delay(100) ist im Moment für das Entprellen da, aber so kannst du das mal testen:
Code: [Select]

#define Taster 3
#define Relais1 4  
boolean Letzter, Aktuell, onoff;
//---------------------------------------------------------------------------------
void setup(){
pinMode(Taster, INPUT);
pinMode(Relais1, OUTPUT);
}

//---------------------------------------------------------------------------------
void loop(){
Letzter = Aktuell;
if (digitalRead(Taster) == HIGH ) Aktuell = true; else Aktuell = false; //auslesen des Tasters
 delay(100);
 if(!Letzter && Aktuell){ // reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
  if (onoff)
    digitalWrite(Relais1,HIGH);
   else  
    digitalWrite(Relais1,LOW);
 onoff = !onoff;
}
}

nachtaktiv68

Für Buttons benutze ich diese Bibliothek:

http://arduino.cc/playground/Code/Buttons

Funktioniert bei mir hervorragend!
twitter: @darktom

keraino

Bin ja echt begeistert wie schnell man hier Hilfe bekommt, komme ja kaum mit dem Probieren nach  XD, DANKE erstmal dafür.
Der oder das Sketch (wie heisst es eigentlich richtig?) von Jr.Member funktioniert Klasse.
Da meine Relais ja förmlich negiert schalten, bei OUTPUT LOW sind die auf HIGH, war nach dem übertragen des Codes das Relais immer gleich auf HIGH, habe das gelöst indem ich den Taster jetzt gegen GND schalte statt an 5V nun ist es beim Start oder nach Reset zuerst auf LOW. Werde gleich mal auf 3Relais erweitern und probieren und dann hätte ich ja schon meine erste Anforderung erfüllt.
Danke für die Lösung der 1. Anforderung

keraino

Meinte natürlich Scetch von maverick1509

maverick1509

beim zweiten könnte ich dir auch helfen wenn ichs denn verstehe.
Ein Taster für 2 Relais, welche zeitversetzt an und ausgeschaltet werden sollen?

keraino

Ja bei der 2.Anforderung soll ein zeitlicher Ablauf wie oben beschrieben stattfinden aber eigentlich mit 4-5 Relais. Nochmal zu Deinem 1. Sketch, bin zu blöd den auf weitere Taster und Rlais zu erweitern, habs so probiert

Code: [Select]

#define Taster1 10
#define Taster2 9
#define Taster3 8
#define Relais1 23
#define Relais2 22
#define Relais3 25
boolean Letzter, Aktuell, onoff;
//---------------------------------------------------------------------------------
void setup(){
pinMode(Taster1, INPUT);
pinMode(Taster2, INPUT);
pinMode(Taster3, INPUT);
pinMode(Relais1, OUTPUT);
pinMode(Relais2, OUTPUT);
pinMode(Relais3, OUTPUT);
}

//---------------------------------------------------------------------------------
void loop(){
Letzter = Aktuell;
if (digitalRead(Taster1) == HIGH ) Aktuell = true; else Aktuell = false; //auslesen des Tasters
  delay(10);
  if(!Letzter && Aktuell){ // reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
   if (onoff)
     digitalWrite(Relais1,LOW);
    else 
     digitalWrite(Relais1,HIGH);
  onoff = !onoff;
}
{
Letzter = Aktuell;
if (digitalRead(Taster2) == HIGH ) Aktuell = true; else Aktuell = false; //auslesen des Tasters
  delay(10);
  if(!Letzter && Aktuell){// reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
   if (onoff)
     digitalWrite(Relais2,LOW);
    else 
     digitalWrite(Relais2,HIGH);
  onoff = !onoff;
}
}


aber das will er nicht, bin halt neu und so einfach Copy Paste scheint es doch nicht zu sein, für ne kleine Hilfe wär ich dankbar

maverick1509

#10
Mar 02, 2012, 12:18 pm Last Edit: Mar 02, 2012, 12:20 pm by maverick1509 Reason: 1
Das zweite kannst du auf die schnelle mal so testen:
Ist allerdings nicht die "feine englische Art" da das Programm für 30 Sek in eine Prozedur springt.
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();
}
}

maverick1509

als erstes ist eine geschweifte Klammer "falsch herum"
{
Letzter = Aktuell;

und dann mußt dufür jeden Taster die Variablen deklarieren,
(start1, start2,letzter1..., aktueller1...onoff1....)
dann sollte es gehen.

keraino

Das hat funktioniert der Code sieht jetz so aus
Code: [Select]

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

//---------------------------------------------------------------------------------
void loop(){
Letzter = Aktuell;
if (digitalRead(Taster1) == HIGH ) Aktuell = true; else Aktuell = false; //auslesen des Tasters
  delay(10);
  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(10);
  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(10);
  if(!Letzter2 && Aktuell2){ // reagiert auf Tasterwechsel von nicht gedrückt auf gedrückt
   if (onoff2)
     digitalWrite(Relais3,LOW);
    else 
     digitalWrite(Relais3,HIGH);
  onoff2 = !onoff2;
}
}

und es klappt super mit 3Tastern und 3Relais, weiss jetzt wie ich das richtig erweitere.
DANKE  :D
Hab jetzt leider keine Zeit mehr um die Automatik zu probieren, erst am Montag wieder.
Wichtig wäre noch zur Automatik zu sagen das z.T. die gleichen Relais wie mit den Tastern geschaltet werden sollen.

maverick1509

noch was zu deiner Relaiskarte, so eine hatte ich auch mal.
Ich finde die äußerst "blöd", wie kann man eine Relaiskarte bauen, die ständig unter Strom steht,
alle Pins müssen immer auf "HIGH" sein und sind auf "LOW", wenn das Relais anzieht.
Vielleicht kann mir ja einer erklären, warum das so gemacht wird, ich versteh es nicht.

sth77

Um welche Relaisplatine handelt es sich denn? Viele Relais haben ja einen Umschaltkontakt, in diesem Produkt sind diese Umschalter als 3 poliger Anschluss (pro Relais) herausgeführt:
http://www.exp-tech.de/product_info.php?info=p201_12v-16-channel-relay-shield.html
Damit hat man also sowohl Öffner- als auch Schließerkontakt. Muss man eben immer schauen, was man denn braucht und was man bekommt... ;)
Mein Arduino-Blog: http://www.sth77.de/ - letzte Einträge: Teensy 3.0 - Teensyduino unter Window 7 - Teensyduino unter Windows 8

Go Up