Go Down

Topic: Wenn Taster für X Sekunden gedrückt, dann ... (Read 480 times) previous topic - next topic

AtomicIX

Hallo,
ich habe gerade mein erstes kleines Projekt, komme da aber irgendwie nicht weiter.

Wenn ich TasterA drücke, soll AusgangA HIGH sein, wenn ich ih wieder los lasse, LOW. Wenn ich aber TasterA für mehr als 5 Sek gedrückt habe, soll Ausgang so lange HIGH sein, bis TasterB gedrückt wird.


hier mal die IF Anweisung in der loop.

Code: [Select]

 if (GrundTasteWert == HIGH && GrundLinksWert == LOW && currentMillis - previousMillis >= interval)
 {
 
       
       digitalWrite(8,HIGH);
     
 }
 else{
       digitalWrite(8,LOW);
   
 }




aber jetzt läuft das script halt nur alle 5 Sekunden, das will ich ja nicht.

HotSystems

Damit wir deine Fehler erkennen können, solltest du den kompletten Sketch posten.
Fragmente helfen da nicht.
I2C = weniger ist mehr: weniger Kabel, mehr Probleme. 8)

ardubu

du mußt previousMillis in der Funktion auch aktualisieren
Code: [Select]

 if (GrundTasteWert == HIGH && GrundLinksWert == LOW && currentMillis - previousMillis >= interval)
 {
       
       previousMillis = millis();
       digitalWrite(8,HIGH);
     
 }
 else{
       digitalWrite(8,LOW);
   
 }


michael_x

Quote
jetzt läuft das script halt nur alle 5 Sekunden
falsch

Da previousmillis nie gesetzt wird, gibt es keinen Grund, warum das zweite && nicht dauernd erfüllt sein sollte. ( Oder nie )
Ansonsten [mit ardubus Tip] wäre das && der Grund, warum der sketch was anderes macht als du dir wohl vorstellst.


Deine "Aufgabenstellung" ist auch unklar:
Was soll passieren, wenn B dauernd gedrückt ist ?
- LED geht gar nicht erst an.
- LED geht sofort aus beim Loslassen von A, egal wie lange A gedrückt war.
- Erst B loslassen und neu drücken löscht die LED.
- Egal

Whandall

Taste A steuert die LED, wenn länger als 5 Sekunden gedrückt bleibt die LED an.
Das Betätigen des Tasters B löscht die LED wieder.

Code: [Select]
#include <Bounce2.h>

const byte pinTasteA = 9;
const byte pinTasteB = 8;

Bounce TasteA, TasteB;

bool ledState;
unsigned long gedrueckt;;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  TasteA.attach(pinTasteA, INPUT_PULLUP);
  TasteB.attach(pinTasteB, INPUT_PULLUP);
}

void loop() {
  if (ledState) {
    if (TasteB.update() && TasteB.fell()) {
      ledState = false;
    }
    if (TasteA.update() && TasteA.rose()) {
      if (millis() - gedrueckt < 5000) {
        ledState = false;
      }
    }
  } else {
    if (TasteA.update() && TasteA.fell()) {
      ledState = true;
      gedrueckt = millis();
    }
  }
  digitalWrite(LED_BUILTIN, ledState);
}
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

AtomicIX

Danke schon mal.
Ich habe jetzt Probiert den Vorschlag von "Whandall" umzusetzen auf mein Programm. 
Aber ich glaube das ganze ist bisschen unausgereift was ich mir da überlegt habe.
Es ist ja nicht nur eine LED sondern ein Tackt der generiert wird. Ich wollte erst keine Romane schreiben .
Also noch mal von vorn.

Ich bekomme einen Impuls von Außen (Fotoapparat )
Dann soll nach einer Verzögerung ( über Poti einstellbar ) an einen Schrittmotor geschickt werden.
Wenn Position Rechts erreicht ist, soll es stoppen.
Wenn ich die Grudnsstellung drücke, soll an die Grundposition gefahren werden ( Links)
Kurzer druck auf den Grundstellungstaster kurzer Schritt.
Langer Druck ( 5 Sek. ) Schrittmotor läuft bis Ende (Links)



Code: [Select]



#include <Bounce2.h>


int PotiPin=1; //Analog
int valAnalog=0; //Analog
int PotiZeit5=0; //Analog
int PotiZeit10=0; //Analog
int PotiZeit=0;

int Fakt5=11; // Zeitfaktor 5
//int Fakt10=12; // Zeitfaktor 10
int Fakt5Wert=0; // Zeitfaktor Merker

int BlitzTackt=9; // Blitzeingabe
int BlitzWert=0; // Blitzeingabe Wert

const byte GrundstellungTaste=12; //Grunsstellung Taste
// int GrundTasteWert=0;  // Grundstellung Taste

const byte GrundstellungLinks=4; //Grunsstellung Links
// int GrundLinksWert=0;  // Grundstellung Links

int GrundstellungRechts=3; //Grunsstellung Rechts
int GrundRechtsWert=0;  // Grundstellung Rechts

int Richtung=5; //Grunsstellung Rechts
int RichtungWert=0;  // Grundstellung Rechts

int SchrittTackt=8; // Impuls für Schrittmotor
int TaktWert=8;



bool ledState;
unsigned long gedrueckt;;


void setup()
{
  Bounce GrundstellungTaste, GrundstellungLinks;
  Serial.begin(9600);  // -> Nur TEST
  pinMode(SchrittTackt, OUTPUT);
  pinMode(Richtung, OUTPUT);
  pinMode(BlitzTackt, INPUT);
  GrundstellungTaste.attach(12, INPUT_PULLUP);
  GrundstellungLinks.attach(4, INPUT_PULLUP);
 
}
void loop()
{
  valAnalog = analogRead(PotiPin); // Potizeit auslesen
   BlitzWert=digitalRead(BlitzTackt);
   GrundRechtsWert=digitalRead(GrundstellungRechts);
 //  GrundLinksWert=digitalRead(GrundstellungLinks);
 //  GrundTasteWert=digitalRead(GrundstellungTaste);
   Fakt5Wert=digitalRead(Fakt5);
 

  if (ledState) {
    if (GrundstellungLinks.update() && GrundstellungLinks.fell()) {
      digitalWrite(Richtung, LOW);
      digitalWrite(8,HIGH);
      delay(2);
      digitalWrite(8,LOW);
      delay(2);
    }
    if (GrundstellungTaste.update() && GrundstellungTaste.rose()) {
      if (millis() - gedrueckt < 5000) {
      digitalWrite(Richtung, LOW);
      digitalWrite(8,HIGH);
      delay(2);
      digitalWrite(8,LOW);
      delay(2);
      }
    }
  } else {
    if (GrundstellungTaste.update() && GrundstellungTaste.fell()) {
       digitalWrite(8,LOW);
       digitalWrite(Richtung, HIGH);
      gedrueckt = millis();
    }
  }
 
}

   

 
  if (Fakt5Wert == HIGH && GrundRechtsWert == LOW)
{
  PotiZeit = (valAnalog * 5);  // Potizeit umrechnen *5
}
else
{
  PotiZeit = (valAnalog * 10);  // Potizeit umrechnen *10
}

 if (BlitzWert == HIGH && GrundRechtsWert == LOW)
 
{

 
  delay(PotiZeit);
  digitalWrite(SchrittTackt, HIGH);
  delay(250);  // Impulsdauer
  Serial.print("  Wert: ");  // -> Nur TEST
  Serial.print(PotiZeit);  // -> Nur TEST
 
}
else
{
digitalWrite(SchrittTackt, LOW);   // Ausgabe abschalten
}


}


Whandall

#6
May 15, 2017, 06:10 pm Last Edit: May 15, 2017, 06:22 pm by Whandall
Du hast eine '}' zuviel.

Ansonsten ersetze alle delay() durch äquivalenten nicht-blockierenden Kode.
Edit: Bei den kurzen delay(2) ist eine Implementation mit micros() sowieso genauer.

Du hast Endschalter und Taster zu überprüfen, da ist jedes noch so kleine delay() störend.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

AtomicIX

okay, die {  vorm else habe ich entfernt.
aber ich bekommen folgende Meldung.




Timer-Programm:60: error: request for member 'update' in 'GrundstellungLinks', which is of non-class type 'const byte {aka const unsigned char}'

     if (GrundstellungLinks.update() && GrundstellungLinks.fell()) {

                            ^

Timer-Programm:60: error: request for member 'fell' in 'GrundstellungLinks', which is of non-class type 'const byte {aka const unsigned char}'

     if (GrundstellungLinks.update() && GrundstellungLinks.fell()) {

                                                           ^

Timer-Programm:67: error: request for member 'update' in 'GrundstellungTaste', which is of non-class type 'const byte {aka const unsigned char}'

     if (GrundstellungTaste.update() && GrundstellungTaste.rose()) {

                            ^

Timer-Programm:67: error: request for member 'rose' in 'GrundstellungTaste', which is of non-class type 'const byte {aka const unsigned char}'

     if (GrundstellungTaste.update() && GrundstellungTaste.rose()) {

                                                           ^

Timer-Programm:77: error: request for member 'update' in 'GrundstellungTaste', which is of non-class type 'const byte {aka const unsigned char}'

     if (GrundstellungTaste.update() && GrundstellungTaste.fell()) {

                            ^

Timer-Programm:77: error: request for member 'fell' in 'GrundstellungTaste', which is of non-class type 'const byte {aka const unsigned char}'

     if (GrundstellungTaste.update() && GrundstellungTaste.fell()) {

                                                           ^

exit status 1
request for member 'update' in 'GrundstellungLinks', which is of non-class type 'const byte {aka const unsigned char}'


michael_x

  GrundstellungLinks  ist ein const byte, soll vermutlich die Pin-Nummer sein.

fell() ist eine Methode eines bounce Objekts.

Solche Objekte hast du als lokale Variable in setup()

Ich hoffe das gibt dir genug Hinweise ;)

AtomicIX

okay, nu bekomme ich schon mal keine Fehler, aber durch druck auf den Grundstellugstaster (12) bekomme ich einen Tackt, das ist auch richtig.
Durch Druck von min 5sek  auf den Taster passiert nichts.


Code: [Select]

#include <Bounce2.h>


int PotiPin=1; //Analog
int valAnalog=0; //Analog
int PotiZeit5=0; //Analog
int PotiZeit10=0; //Analog
int PotiZeit=0;

int Fakt5=11; // Zeitfaktor 5
//int Fakt10=12; // Zeitfaktor 10
int Fakt5Wert=0; // Zeitfaktor Merker

int BlitzTackt=9; // Blitzeingabe
int BlitzWert=0; // Blitzeingabe Wert

const byte GrundTastePin = 12; //Grunsstellung Taste
// int GrundTasteWert=0;  // Grundstellung Taste

const byte GrundLinksPin = 4; //Grunsstellung Links
// int GrundLinksWert=0;  // Grundstellung Links

int GrundstellungRechts=3; //Grunsstellung Rechts
int GrundRechtsWert=0;  // Grundstellung Rechts

int Richtung=5; //Grunsstellung Rechts
int RichtungWert=0;  // Grundstellung Rechts

int SchrittTackt=8; // Impuls für Schrittmotor
int TaktWert=8;


Bounce GrundTaste, GrundLinks;
bool ledState;
unsigned long gedrueckt;;


void setup()
{
 
  Serial.begin(9600);  // -> Nur TEST
  pinMode(SchrittTackt, OUTPUT);
  pinMode(Richtung, OUTPUT);
  pinMode(BlitzTackt, INPUT);
  GrundTaste.attach(GrundTastePin, INPUT_PULLUP);
  GrundLinks.attach(GrundLinksPin, INPUT_PULLUP);
 
}
void loop()
{
  valAnalog = analogRead(PotiPin); // Potizeit auslesen
   BlitzWert=digitalRead(BlitzTackt);
   GrundRechtsWert=digitalRead(GrundstellungRechts);
 //  GrundLinksWert=digitalRead(GrundstellungLinks);
 //  GrundTasteWert=digitalRead(GrundstellungTaste);
   Fakt5Wert=digitalRead(Fakt5);
 

  if (SchrittTackt) {
    if (GrundLinks.update() && GrundLinks.fell()) {
    digitalWrite(Richtung, HIGH);
    digitalWrite(8,LOW);
    }
    if (GrundTaste.update() && GrundTaste.rose()) {
      if (millis() - gedrueckt < 5000) {
      digitalWrite(Richtung, LOW);
      digitalWrite(8,HIGH);
      delay(2);
      digitalWrite(8,LOW);
      delay(2);
      }
    }
  else {
    if (GrundTaste.update() && GrundTaste.fell()) {
         digitalWrite(Richtung, LOW);
      digitalWrite(8,HIGH);
      delay(2);
      digitalWrite(8,LOW);
      delay(2);
      gedrueckt = millis();
    }
  }
 
}

   

 
  if (Fakt5Wert == HIGH && GrundRechtsWert == LOW)
{
  PotiZeit = (valAnalog * 5);  // Potizeit umrechnen *5
}
else
{
  PotiZeit = (valAnalog * 10);  // Potizeit umrechnen *10
}
 if (BlitzWert == HIGH && GrundRechtsWert == LOW)
{

 
  delay(PotiZeit);
  digitalWrite(SchrittTackt, HIGH);
  delay(250);  // Impulsdauer
  Serial.print("  Wert: ");  // -> Nur TEST
  Serial.print(PotiZeit);  // -> Nur TEST
 
}
else
{
digitalWrite(SchrittTackt, LOW);   // Ausgabe abschalten
}


}



Whandall

Wenn man keine vernünftigen Namen benutzt baut man sich Fallen wie

Code: [Select]
 if (SchrittTackt) {
Dir ist schon klar, dass fast alle Pin-Nummern true sind?
Und alle sind konstant, machen also in einem if relativ wenig Sinn...

Mit dem Einführen dieser Zeile hast du zusätzlich noch die Klammerstruktur geändert,
dass es nicht mehr geht.

Wie kommst du auf das dünne Brett, dass die von mir verwendete Variable ledState überflüssig sei?
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

AtomicIX

Gute Frage,
ich habe jetzt noch mal von vorn angefangen, ob es zu verstehen.
Habe jetzt eigentlich nur meinen Motor am Ausgang eingebaut.
Wenn ich jetzt das Programm übertrage, läuft der Motor gleich los und reagiert auf nichts


Code: [Select]

#include <Bounce2.h>

const byte pinTasteA = 3;
const byte pinTasteB = 4;

Bounce TasteA, TasteB;

bool ledState;
unsigned long gedrueckt;;

void setup() {
  pinMode(8, OUTPUT);
  TasteA.attach(pinTasteA, INPUT_PULLUP);
  TasteB.attach(pinTasteB, INPUT_PULLUP);
}

void loop() {
  if (ledState) {
    if (TasteB.update() && TasteB.fell()) {
      ledState = false;
    }
    if (TasteA.update() && TasteA.rose()) {
      if (millis() - gedrueckt < 5000) {
        ledState = false;
      }
    }
  } else {
    if (TasteA.update() && TasteA.fell()) {
      ledState = true;
      gedrueckt = millis();
    }
  }
 
      digitalWrite(8,HIGH);
      delay(2);
      digitalWrite(8,LOW);
      delay(2);
}

Whandall

#12
May 17, 2017, 05:34 pm Last Edit: May 17, 2017, 05:40 pm by Whandall
Das kann dich bei dem präsentierten Kode ja nicht wirklich wundern, oder?

Grundsätzlich:
 du solltest grundsätzlich alle Timings mit millis()/micros() machen, vergiss die Existenz von delay()!

Code: [Select]
#include <Bounce2.h>

const byte pinTasteA = 3;
const byte pinTasteB = 4;

Bounce TasteA, TasteB;

bool motorState;
unsigned long gedrueckt;;

void setup() {
  pinMode(8, OUTPUT);
  TasteA.attach(pinTasteA, INPUT_PULLUP);
  TasteB.attach(pinTasteB, INPUT_PULLUP);
}

void loop() {
  if (motorState) {
    if (TasteB.update() && TasteB.fell()) {
      motorState = false;
    }
    if (TasteA.update() && TasteA.rose()) {
      if (millis() - gedrueckt < 5000) {
        motorState = false;
      }
    }
  } else {
    if (TasteA.update() && TasteA.fell()) {
      motorState = true;
      gedrueckt = millis();
    }
  }
  static unsigned long lastPulse;
  if (motorState) {
    if (micros() - lastPulse >= 2000) {
      lastPulse += 2000;
      digitalWrite(8, !digitalRead(8));
    }
  }
}
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Whandall

Um die Phasen immer mit HIGH zu starten und alle Phasen so gleich lang wie möglich haben zu wollen,
ist noch etwas zusätlicher Kode nötig (und ein kleines Umsortieren).
Wenn man für alle Konstanten Namen vergibt, dokumentiert sich der Kode fast selbst.

Zum Testen habe ich eine blinkende Led hinzugefügt und die Tasten auf andere Pins gelegt.

Code: [Select]
#include <Bounce2.h>

const byte pinTasteA = 30;
const byte pinTasteB = 31;
const byte pinMotor = 8;
const byte pinMotorLed = 9;

const unsigned int MotorPulseLen = 2000;
const unsigned int LedPulseLen = 500;
const unsigned int langeGedrueckt = 5000;

Bounce TasteA, TasteB;

bool motorState;
unsigned long gedrueckt;;

void setup() {
  pinMode(pinMotor, OUTPUT);
  pinMode(pinMotorLed, OUTPUT);
  TasteA.attach(pinTasteA, INPUT_PULLUP);
  TasteB.attach(pinTasteB, INPUT_PULLUP);
}

void loop() {
  static unsigned long lastBlink;
  static unsigned long lastPulse;
  if (motorState) {
    if (TasteB.update() && TasteB.fell()) {
      motorState = false;
    } else if (TasteA.update() && TasteA.rose()) {
      if (millis() - gedrueckt < langeGedrueckt) {
        motorState = false;
      }
    }
    if (!motorState) {
      digitalWrite(pinMotor, LOW);
      digitalWrite(pinMotorLed, LOW);
    }
  } else {
    if (TasteA.update() && TasteA.fell()) {
      motorState = true;
      gedrueckt = millis();
      lastPulse = micros();
      lastBlink = millis();
      digitalWrite(pinMotor, HIGH);
      digitalWrite(pinMotorLed, HIGH);
    }
  }
  if (motorState) {
    if (micros() - lastPulse >= MotorPulseLen) {
      lastPulse += MotorPulseLen;
      digitalWrite(pinMotor, !digitalRead(pinMotor));
    }
    if (millis() - lastBlink >= LedPulseLen) {
      lastBlink += LedPulseLen;
      digitalWrite(pinMotorLed, !digitalRead(pinMotorLed));
    }
  }
}

Ich finde das funktioniert gut.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

AtomicIX

Das läuft nicht  :smiley-confuse:

Es tut nicht, das was ich gehofft habe. Jetzt bin ich ganz verwirrt.
TasteA  ist die Taste für die Grundstellung
TasteB ist der Endlagenschalter
Motor ist der Motortakt
MotorLED nur zusätzlich eine LED ( kann theoretisch auch vernachlässigt werden ?)

Wenn ich jetzt meine pins anpasse, passiert erst mal nicht.
Wenn ich jetzt die TasteA drücke läuft der Motor los, wenn ich los lasse, läuft der Motor weiter.
Wenn ich die TasteA gedrückt halte, stoppt der Motor, wenn ich wieder los lasse, läuft er weiter.
TasteB macht gar nichts

Go Up