Erfahrung mit Arduino habe ich null aber mit anderen Programmiersprachen wie Java.
Und zwar möchte ich einen Rolladenmotor mittels Taster, Relais und LED mit Blinkfunktion solange der Motor fährt.
Hardware ist auf dem Weg, aber ich hatte noch ein paar kleine Bauteile zum testen hier und Frage mich ob der angesetzte Weg der Richtige ist. Mein aktueller Programmcode, aktuell gibt es noch keine Laufzeit.
/*
*/
int led = 13; // Variable für Pin 13
int button = 8; // Variable für Pin 8
int buttonStatus; // in dieser Variable wird die Information
// abgespeichert ob der Taster gerade gedrückt
// wird oder nicht
int relais1pin = 9; // Relai 1 für Hoch
int relais2pin = 10; // Reali 2 für Runter
int upDown=1; // Status = unten 1, oben 2
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // definiere Pin 13 als Ausgang
pinMode(button, INPUT); // definiere Pin 8 als Eingang
pinMode(relais1pin,OUTPUT);
pinMode(relais2pin,OUTPUT);
}
void loop() {
buttonStatus = digitalRead(button); // prüfe ob Taster gedrückt oder nicht und
// speicher die Information in
// buttonStatus ab
if (buttonStatus == HIGH) // Wenn buttonStatus = 1, also HIGH führe den
{
if(upDown == 1){
digitalWrite(LED_BUILTIN, HIGH); // schalte LED an
delay(1000); // warte 1 sek
digitalWrite(LED_BUILTIN, LOW); // schalte LED aus
delay(1000); // warte 1 Sekunde
digitalWrite(relais1pin, HIGH); // Relai für Hoch
digitalWrite(relais2pin, LOW);
buttonStatus = LOW; //buttonStatus wieder auf LOW
upDown = 2; //Status oben
}
else if (upDown == 2) {
digitalWrite(LED_BUILTIN, HIGH); // schalte LED an
delay(1000); // warte 1 sek
digitalWrite(LED_BUILTIN, LOW); // schalte LED aus
delay(1000); // warte 1 sek
digitalWrite(relais1pin, LOW); // Relai für runter
digitalWrite(relais2pin, HIGH);
buttonStatus = LOW; // buttonStatus wieder auf LOW
upDown=1; // Status unten
}
}
else{
digitalWrite(LED_BUILTIN, HIGH); // pin 13 = 0, mache LED an dauerleuchten
digitalWrite(relais1pin, LOW); // Relais nix machen
digitalWrite(relais2pin, LOW);
}
}
Hier wäre auch die Frage wie ich es umsetze.
Ideen die ich gefunden habe wäre mit millis() und eine do while schleife bis er oben ist oder hat jemand andere ideen.
Setze Deinen Code bitte in Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter ohne *).
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.
Du brauchst keine weitere Schleife, Du hast doch loop.
Wie machst Du Das, wenn Du eine Pizza in den Ofen schiebst?
Du merkst Dir, wann Diese fertig ist.
Beim Arduino geht's ähnlich - Du PRÜFST, ob Diese fertig ist, da Du Dir die STARTzeit gemerkt hast und die aktuelle Zeit mit millis() eh zur Verfügung hast.
Dann nur noch beachten: Tür erst öffnen, wenn die Pizza fertig ist - wofür machen wir das ganze Zeig sonst auch
millis() ist schon mal gut, do while Schleife ist schlecht. Du hast eine Schleife, die nennt sich loop. Mit if verzweigst du dann dahin wo du es willt.
Der Motor soll doch anhalten wenn Du den Taster wieder los lässt. Dann müsste man die Tasterabfrange ausserhal der while Schleife , zum einschalten und innerhal nochmal zum ausschalten machen. Mach dir erst mal einen Ablaufplan, kann auch gerne in Textform sein. Mit etwas Übung kannst Du dann die einzelnen Textzeilen in code umsetzten. Schau Dir das Thema "Funktionen" an , dann kannst Du deine Aufgabe in logische Blöcke aufteilen und z.B das Blinken in eine Funktion auslagern. Das kennst Du doch aus Java.
etwa so.
Wenn taster heben gedrückt
Motor heben ein
blinken
sonst (else)
Motor heben aus
Wenn taster senken gedrückt
Motor senken ein
blinken
sonst (else)
motor senken aus
wenn Taster gedrückt wird
dann blinke
und motor fahre hoch
wenn Taster nochmal gedrückt wird
dann blinke
und fahre herunter.
Aktuell habe ich es so gelöst
/*
*/
const long interval = 1000;
unsigned long previousMillis = 0;
int ledState = LOW;
int led = 13; // Variable für Pin 13
int button = 8; // Variable für Pin 8
int buttonStatus; // in dieser Variable wird die Information
// abgespeichert ob der Taster gerade gedrückt
// wird oder nicht
int relais1pin = 9; // Relai 1 für Hoch
int relais2pin = 10; // Reali 2 für Runter
int upDown=1; // Status = unten 1, oben 2
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // definiere Pin 13 als Ausgang
pinMode(button, INPUT); // definiere Pin 8 als Eingang
pinMode(relais1pin,OUTPUT);
pinMode(relais2pin,OUTPUT);
}
void loop() {
buttonStatus = digitalRead(button); // prüfe ob Taster gedrückt oder nicht und
// speicher die Information in
// buttonStatus ab
if (buttonStatus == HIGH) // Wenn buttonStatus = 1, also HIGH führe den
{
if(upDown == 1){
unsigned long start;
start = millis();
do {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (ledState == LOW) {
ledState = HIGH;
}
else {
ledState = LOW;
}
digitalWrite(led, ledState);
}
digitalWrite(relais1pin, HIGH); // Relai für Hoch
digitalWrite(relais2pin, LOW);
} while (millis() - start < 6000);
buttonStatus = LOW; //buttonStatus wieder auf LOW
upDown = 2; //Status oben
}
else if (upDown == 2) {
unsigned long start;
start = millis();
do {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
if (ledState == LOW) {
ledState = HIGH;
}
else {
ledState = LOW;
}
digitalWrite(led, ledState);
}
digitalWrite(relais1pin, LOW); // Relai für Hoch
digitalWrite(relais2pin, HIGH);
} while (millis() - start < 6000);
buttonStatus = LOW; //buttonStatus wieder auf LOW
upDown = 2; //Status oben
}
else{
digitalWrite(LED_BUILTIN, HIGH); // pin 13 = 0, mache LED an dauerleuchten
digitalWrite(relais1pin, LOW); // Relais nix machen
digitalWrite(relais2pin, LOW);
}
}
}
Klappt auch soweit, jedoch nur beim ersten mal.
Ich wenn ich den Taster das 3 oder 4 mal drücke blinkt zwar die LED aber die Relais schalten nicht mehr durch.
Ich dachte vielleicht liegt es daran, dass ich die variable upDown in der do-while schleife habe und sie dann rausgenommen habe aber brachte keinen Erfolg...
Zu Java ja habe ich gelernt aber das ist schon 10 Jahre her und seitdem habe ich damit auch nichts mehr am Hut.
In Deiner Beschreibung hinkt Es 'etwas' - solange der Taster nicht wieder gelöst wird, wird man Den nicht erneut drücken können.
Etwas Präzision beim Umschreiben erspart eine ganze Menge Zeit beim Schreiben.
Wenn der Button-Status dem Status des Button entsprechen soll, wirst Du Den beim Einlesen (irgendwann) auch wieder als unbetätigt erkennen - Das geht schon automatisch (bei Tastern).
Deine Beschreibung lässt das Lösen des Taster aber komplett außen vor - ob und wann der Taster gelöst werden KANN und ob oder wann der gelöst werden MUSS, fehlt komplett.
prüfe ob oben oder unten
-> wenn Unten
-> dann LEd fange an zu blinken und motor fahre hoch für 10sekunden
-> setze Tastendruck auf LOW
-erneuter Tasterdruck
prüfe ob oben oder unten
-> wenn oben
-> dann LED blinken und Motor für 10sek nach unten.
-> setze taster auf LOW
wenn nichts gedrückt wird
-> LED LEUCHTEND
-> RELAIS aus
und das funktioniert an sich nur das es ich jeweils nur 1 mal hoch und 1 mal runter fahren kann.
Bräuchte quasi einen restart dann
Wenn der Button-Status dem Status des Button entsprechen soll, wirst Du Den beim Einlesen (irgendwann) auch wieder als unbetätigt erkennen - Das geht schon automatisch (bei Tastern).
Deine Beschreibung lässt das Lösen des Taster aber komplett außen vor - ob und wann der Taster gelöst werden KANN und ob oder wann der gelöst werden MUSS, fehlt komplett.
MfG
Ich verstehe nicht was du meinst es ist ja ein Taster kein einrastknopf. also ich drücke kurz drauf und dann startet der Ablauf nur funktioniert das nur 1 mal
Trotzdem musst Du nicht den Taster 'auf LOW setzen' - mit der Flanke des Drückens startest Du die Aktion - da Diese etwas Zeit braucht, ist kein Entprellen nötig (da die Aktion schon gestartet wurde, sind Mehrfach-Tastungen eh 'für die Füße')
Du hast 2 Status
Motor fährt (egal welche Richtung)
Motor steht
Wenn der Motor fährt, prüfst Du 'nur', ob die Zeit um ist - wenn JA, Motor anhalten.
Wenn der Motor NICHT fährt, prüfst Du 'nur', ob Jemand auf den Taster drückt- wenn Nein, war's Das auch schon.
Wenn JA, prüfst Du, ob wir 'oben' stehen -> Richtung 'runter', SONST (und auch, wenn wir unten stehen) Richtung 'hoch'.
Weiter merkst Du Dir die Startzeit und schaltest den Motor AN.
if (motor_ist_an){
//prüfe auf Ende der Laufzeit
if (millis()-startzeit>=laufzeit){
//MOTOR AUS
}
}else{
//hier ist der Motor aus, wir prüfen auf Taster
if (Taster betätigt){
if (Endlage OBEN betätigt){
RICHTUNG=RUNTER;
}else{
RICHTUNG=HOCH;
}
startzeit=millis();
//MOTOR AN
}
}
MfG
PS: Für den Arduino drückst Du EWIGKEITEN auf dem armen Taster rum - Du schreibst aber nicht, wo das Lösen erkannt wird oder der Taster ZWINGEND gelöst sein muß.
Auch in meinem Pseudo-Code ist das Lösen nicht enthalten - wenn Du den Taster 'festklebst' fährt das Gelump die nächsten 35 Jahre nonstop raus und runter - weil eben vor dem Auslösen der Taster nicht losgelassen werden musste.
Der Arduino sollte loop() im ms Takt durchlaufen (oder schneller) - alleine ein Augenzwinkern sind >20ms - und Knöpsche drügge kann der Mensch auch nicht viel flotter.
PPS: Du brauchst nur einen Endschalter - für die obere Endlage.
Sonst - wenn kein Endschalter betätigt ist - fährt der Motor nicht los.
Trotzdem musst Du nicht den Taster 'auf LOW setzen' - mit der Flanke des Drückens startest Du die Aktion - da Diese etwas Zeit braucht, ist kein Entprellen nötig (da die Aktion schon gestartet wurde, sind Mehrfach-Tastungen eh 'für die Füße')
Du hast 2 Status
Motor fährt (egal welche Richtung)
Motor steht
Wenn der Motor fährt, prüfst Du 'nur', ob die Zeit um ist - wenn JA, Motor anhalten.
Wenn der Motor NICHT fährt, prüfst Du 'nur', ob Jemand auf den Taster drückt- wenn Nein, war's Das auch schon.
Wenn JA, prüfst Du, ob wir 'oben' stehen -> Richtung 'runter', SONST (und auch, wenn wir unten stehen) Richtung 'hoch'.
Weiter merkst Du Dir die Startzeit und schaltest den Motor AN.
if (motor_ist_an){
//prüfe auf Ende der Laufzeit
if (millis()-startzeit>=laufzeit){
//MOTOR AUS
}
}else{
//hier ist der Motor aus, wir prüfen auf Taster
if (Taster betätigt){
if (Endlage OBEN betätigt){
RICHTUNG=RUNTER;
}else{
RICHTUNG=HOCH;
}
startzeit=millis();
//MOTOR AN
}
}
MfG
PS: Für den Arduino drückst Du EWIGKEITEN auf dem armen Taster rum - Du schreibst aber nicht, wo das Lösen erkannt wird oder der Taster ZWINGEND gelöst sein muß.
Auch in meinem Pseudo-Code ist das Lösen nicht enthalten - wenn Du den Taster 'festklebst' fährt das Gelump die nächsten 35 Jahre nonstop raus und runter - weil eben vor dem Auslösen der Taster nicht losgelassen werden musste.
Der Arduino sollte loop() im ms Takt durchlaufen (oder schneller) - alleine ein Augenzwinkern sind >20ms - und Knöpsche drügge kann der Mensch auch nicht viel flotter.
PPS: Du brauchst nur einen Endschalter - für die obere Endlage.
Sonst - wenn kein Endschalter betätigt ist - fährt der Motor nicht los.
Wie ist es zu verstehen, dass mehrfachtastungen eh für den Arsch sind?
Ich möchte einen Rolladen motor mit elektrischer Abschaltung hoch und Runterfahren lassen mehr nicht.
Das kann man nicht über einen Taster lösen?
daveone1990:
Das kann man nicht über einen Taster lösen?
Doch, kann man. Gemeint ist das anders. Wenn Du beispielsweise mit dem selben Taster den Rolladen auch anhalten wolltest, bräuchtest Du eine Entprellung, weil sonst das Prellen jede gestartete Bewegung sofort wieder anhalten würde.
Dein Ablaufplan aus #10 läßt sich gut mit einer Schrittkette (= endlicher Automat = finite state machine) realisieren. Ich mag die mit switch/case realisierten.
Taster entprellt aber ich komme nicht weiter
habe schon an switch case und weiteres gearbeitet und wieder alles verworfen.....
Also wenn ich den Taster entprelle und dann eine do while schleife mache um danach die laufzeit des motors zu steuern bleibt der Tasterwert für den Switch Case immer bei 1 hängen und um Serial ist alles nur noch seeehr langsam..
Da die MobaTools schonmal angesprochen wurden, hier eine Variante mit dem Timer der MobaTools ( Die MobaTools kannst Du über den Bibliotheksverwalter installieren ).
Als zusätzliche Funktion wurde eingebaut, wenn der Taster während der Laufzeit gedrückt wird, hält der Motor an. Beim nächsten Tastendruck läuft er dann wieder in die andere Richtung. Damit kann man dann auch manuell umsteuern. Die jeweiligen (Rest-)Laufzeiten werden berücksichtigt.
Versuch mal den Code zu verstehen. Ich habe auch versucht, die Variablennamen wirklich entsprechend der Bedeutung zu wählen. Das ersetzt manchen Kommentar
#include <MobaTools.h>
const byte ledPin = 13; // Pinnummer für die Led
const byte buttonPin = 8; // Pinnummer für rauf/runter-Taster
bool buttonGedrueckt; // in dieser Variable wird die Information
// abgespeichert ob der Taster gerade gedrückt wurde
// wird oder nicht
bool lastButtonState; // zur Flankenerkennung
const byte relaisHochPin = 9; // Relai 1 für Hoch
const byte relaisRunterPin = 10; // Reali 2 für Runter
bool aufwaerts = true; // Status = unten true, oben false
MoToTimer BlinkTimer, MotorTimer; // Zeiten für blinken und Motorlaufzeit
const long blinkZeit = 500;
const long laufZeit = 60000;
long restlaufzeit = 60000; // falls der Motor im Laufen angehalten wurde
void setup() {
pinMode(ledPin, OUTPUT); // definiere Pin 13 als Ausgang
pinMode(buttonPin, INPUT); // definiere Pin 8 als Eingang
pinMode(relaisHochPin, OUTPUT);
pinMode(relaisRunterPin, OUTPUT);
}
void loop() {
// Das Ereignis 'Taste wurde gerade gedrückt' erkennen
buttonGedrueckt = false;
if ( digitalRead(buttonPin) ) {
if ( !lastButtonState ) { // prüfe ob gerade Taster gedrückt wurde und
buttonGedrueckt = true;
lastButtonState = true; // vorher noch nicht gedrückt war
}
} else {
lastButtonState = false;
}
delay(20); // kurzes delay zum Entprellen
// Bearbeiten des Tasterdrückens --------------
if (buttonGedrueckt) {
// Taster wurde gedrückt
if ( MotorTimer.running() ) {
// Taster wurde während des Laufens erneut gedrueckt: anhalten
digitalWrite(relaisHochPin, LOW);
digitalWrite(relaisRunterPin, LOW);
restlaufzeit = laufZeit - MotorTimer.getTime(); // das ist die bisherige Laufzeit
MotorTimer.stop();
aufwaerts = !aufwaerts;
} else {
// Motor steht -> je nach Laufrichtung starten
MotorTimer.setTime( restlaufzeit );
if (aufwaerts) {
digitalWrite(relaisHochPin, HIGH);
digitalWrite(relaisRunterPin, LOW);
} else {
digitalWrite(relaisHochPin, LOW);
digitalWrite(relaisRunterPin, HIGH);
}
}
}
// Bearbeiten, wenn Motorzeit abgelaufen
if ( MotorTimer.expired() ) {
// Motorlaufzeit zu Ende. Stoppen und Laufrichtung umdrehen
aufwaerts = digitalRead( relaisRunterPin ); // wenn der Motor nach unten lief, steht er jetzt unten
digitalWrite(relaisHochPin, LOW); // Relais nix machen
digitalWrite(relaisRunterPin, LOW);
restlaufzeit = laufZeit;
}
// Blinken der LED. Die Led blinkt immer, während der Motor läuft
if ( MotorTimer.running() ) {
if ( !BlinkTimer.running() ) {
digitalWrite(ledPin, !digitalRead(ledPin ) );
BlinkTimer.setTime( blinkZeit );
}
} else {
// Wennd er Motortimer nicht läuft, Blinkt auch die Led nicht
BlinkTimer.stop();
digitalWrite(ledPin, LOW );
}
}
P.S. Um das zu testen, musste ich ein paar Einstellungen ändern. Ich hoffe ich habe alles wieder so zurückgesetzt, dass es für deine HW passt.