Brauche Hilfe bei Code

Hallo,

erstmal tut es mir leid, wenn das zu einfach für euch ist, aber ich komm einfach nicht auf die Lösung.
Ich habe einen Taster, bei dessen Betätigung der Variable 'K1interval' ein Wert ungleich 0 zugewiesen wird. Hat sie eben diesen Wert ungleich null, wird Relais K1 eingeschalten und nach der Zeit in ms, die 'K1interval' zugewiesen wird wieder ausgeschalten (einmal - kein Blinken). Probiert habe ich es folgendermaßen:

if(Taster == LOW) K1interval = 500;

// An- und wieder Ausschalten von K1
if(K1interval != 0 && (millis() - TasterStart > 2000)) {
  digitalWrite(K1, LOW);
  TasterStart = millis();
  K1Start = millis();
}
if(millis() - K1Start >= K1interval)  {
  digitalWrite(K1, HIGH);
}

Das eigentliche Problem ist, dass ich den Taster unterschiedlich lange betätigen können will (genauer gesagt mindestens 2000 ms), ohne dass das die Schaltung des Relais beeinflusst.
Könnt ihr mir vllt meinen Code erstmal wenn möglich korrigieren, bevor ihr mir einen komplett anderen gebt?
Bin für jede Hilfe dankbar!
Gruß
Paul

Techniker89:
Könnt ihr mir vllt meinen Code erstmal wenn möglich korrigieren, bevor ihr mir einen komplett anderen gebt?

Eventuell.
Wenn Du zuerst mal DEN GESAMTEN CODE POSTEST, den Dir jemand verbessern soll!

int K1 = 23;
unsigned long K1Start;
unsigned int K1interval;
unsigned long TasterStart;

int Taster = 33;

void setup() {
pinMode(K1, OUTPUT);
pinMode(Taster, INPUT_PULLUP);
}

void loop() {
Tasterval  = digitalRead(Taster);

if(Tasterval == LOW) K1interval = 500;
if(K1interval != 0 && (millis() - TasterStart > 2000)) {
  digitalWrite(K1, LOW);
  TasterStart = millis();
  K1Start = millis();
}
if(millis() - K1Start >= K1interval)  {
  digitalWrite(K1, HIGH);
}
}

Die Idee ist ganz gut, und läßt sich leicht zum Laufen bringen. Wie der Name TasterStart schon sagt, soll das der Zeitpunkt sein, zu dem der Taster gedrückt wurde. Fehlt nur, daß die Variable auch richtig gesetzt wird. So wie Du es bislang machst, steht eine andere Zeit drin.

Die Abfrage von Klinterval ist auch etwas unpassend, wenn Klinterval nicht irgendwann zurückgesetzt wird.

Ich habe mal ein paar Änderungen vorgenommen.
Code kompiliert fehlerfrei, ansonsten ungetestet:

#define ON LOW
#define OFF HIGH
byte relayState=OFF;
const byte K1 = 23;
const byte Taster = 33;
unsigned long startZeit;
const unsigned int k1ingelDauer=2000;


void setup() {
  digitalWrite(K1,relayState);
pinMode(K1, OUTPUT);
pinMode(Taster, INPUT_PULLUP);
}

void loop() 
{
  static byte alterTasterStatus;
  byte tasterStatus  = digitalRead(Taster);
  if (tasterStatus!=alterTasterStatus && tasterStatus==LOW) // hat sich auf LOW geändert
  {
   relayState=ON;
   startZeit=millis();
  }
  alterTasterStatus=tasterStatus;
  if (millis()-startZeit>=klingelDauer)relayState=OFF;
digitalWrite(K1,relayState);
}

Probier's mal aus, ob der Code das macht, was Du möchtest!

Edit/Nachtrag: Fehlt noch eine Zeile zum Ausschalten, trage ich gleich nach!

Zweiter Nachtrag: Eine Zeile zum Ausschalten nach Zeitablauf habe ich in der loop() Funktion nachgetragen.

Hallo jurs,

vielen Dank für deine Hilfe! Dein Code läuft bei mir. Allerdings funktioniert er nicht so, wie ich es mir gedacht habe. Vllt habe ich mich einfach ein bisschen schlecht ausgedrückt. Wenn der Taster gedrückt wird, soll das Relais für eine Zeit x ein- und wieder ausgeschaltet werden - egal ob ich den Taster kurz drücke oder lange gedrückt halte. Wird er erneut gedrückt, soll dasselbe geschehen.
In deinem Code fängt die Zeit x erst an zu laufen, wenn der Taster wieder losgelassen wird und nicht wenn er gedrückt wird.

Kannst du mir vllt nochmal helfen?

Gruß
Paul

Hallo,

wie lange soll das Relais denn eingeschalten und wie lange ausgeschalten sein?
Schaltest du wirklich mit Low ein und mit High aus?

Techniker89:
Hallo jurs,

vielen Dank für deine Hilfe! Dein Code läuft bei mir. Allerdings funktioniert er nicht so, wie ich es mir gedacht habe. Vllt habe ich mich einfach ein bisschen schlecht ausgedrückt. Wenn der Taster gedrückt wird, soll das Relais für eine Zeit x ein- und wieder ausgeschaltet werden - egal ob ich den Taster kurz drücke oder lange gedrückt halte.

Genau das macht mein Code - die Schaltdauer steht fest auf zwei Sekunden (2000 Millisekunden) im Sketch.

Der Schalter müßte ein "Schließer" sein und sie folgt angeschlossen werden:
Ein Pol an Arduino-GND und der andere an Arduino Pin33.
Die ZLeitungen zum Schalter ferrnhalten von netzspannungsführenden Leitungen!

Techniker89:
In deinem Code fängt die Zeit x erst an zu laufen, wenn der Taster wieder losgelassen wird und nicht wenn er gedrückt wird.

Dann ist der Schalter entweder falsch angeschlossen, oder es ist kein normaler "Schließer" (bi unbetätigtem Taster "offen", bei betätigtem Taster geschlossen", sondern möglicherweise ein "Öffner" mit umgekehrter Schaltlogik:

  • unbetätigter Schalter => geschlossener Schaltkontakt
  • betätigter Schalter => offener Schaltkontakt

Wenn das einzige Problem ist, dass Du einen Öffner anstelle eines Schließer-Schalters verwendest und mein Code daher beim Loslassen statt beim Drücken des Schalters schaltet, wäre die einzige Änderung, um das Schaltverhalten umzudrehen, eine Negation der digitalRead() Abfrage:

 byte tasterStatus  = !digitalRead(Taster);

Und wenn die Schaltung sowohl beim Drücken als auch beim Loslassen für zwei Sekunden schaltet, dann prellt der Schalter und Du fügst zum Entprellen vielleicht ein kleines delay(1); zusätzlich mit in die loop() Funktion ein.

Hallo jurs,

doch, der Schalter ist richtig angeschlossen und es ist auch ein normaler Schließer.
Ich kann mir das nicht erklären, werde aber morgen nochmal probieren.

Gruß
Paul

Hallo,

du musst nichts weiter machen als die Logik von define ändern. Vertausche LOW mit HIGH.

#define ON LOW
#define OFF HIGH

Moin moin,

ich verzweifel gerade an den Winkelfunktionen. Ich benötige den winkel alpha in Grad von der sin() funktion. Bekomme schon graue Haare. Könnte mir bittemal jemand auf die Sprünge helfen.

asin(255/5000)* 180/3.1415926535) Habe es so versucht, leider falsch

255/5000 ist immer 0. Wenn dann 5000.0

Außerdem hast du eine Klammer zu viel.

Und Pi gibt es als fertige Konstante. PI oder M_PI. Das schreibt man nicht so direkt in die Rechnung

Pussy:
Moin moin,

ich verzweifel gerade an den Winkelfunktionen. Ich benötige den winkel alpha in Grad von der sin() funktion. Bekomme schon graue Haare. Könnte mir bittemal jemand auf die Sprünge helfen.

asin(255/5000)* 180/3.1415926535) Habe es so versucht, leider falsch

255/5000 ist eine Integer-Rechnung und das Ergebnis ist null (Rest 255).

Ist es das, was Du da als Klammer-Zwischenrechnung machen möchtest?

Oder sollte in der ersten Klammerrechnung ein 'float' als Zwischenergebnis herauskommen, mit dem Du dann weiterrechnest?
Dann versuche
degrees(asin(255.0/5000))

255.0/5000 ist eine float'-Rechnung mit float-Ergebnis

Aber 255/5000) ist eine Integer-Rechnung mit ganzzahligen Integer-Ergebnis null.

Für die Umwandlung radians() und degrees() gibt es Makro-Funktionen.

jurs:
Für die Umwandlung radians() und degrees() gibt es Makro-Funktionen.

Dachte ich auch. Und die sind in Arduino.h

#define DEG_TO_RAD 0.017453292519943295769236907684886
#define RAD_TO_DEG 57.295779513082320876798154814105

#define radians(deg) ((deg)*DEG_TO_RAD)
#define degrees(rad) ((rad)*RAD_TO_DEG)