Ah Sorry, Schalter_1 und Schalter_2 schalten sich gegenseitig. Das ganze wird ueber einen 4 Kanal 433Mhz Empfaenger geregelt.
Aha, Scheibchen für Scheibchen kommt langsam die Salami zum Vorschein....
Bitte nicht das Thema zerreißen!
Multipostings (Threads zum selben Thema) sind hier nicht erlaubt.
.
Streu noch Salz in meine Wunden und das war ja auch alles ganz anders geplant!!!! ![]()
Das verstehe ich noch...
Das verstehe ich nicht.
Wenn der Servo schon auf Position 0 steht, kann er nicht mehr Richtung 0 laufen.
Falls ich die Pause nicht abwarten will. Ich schalte um, Servo geht Pos_0.
Also keine lineare Schrittkette, sondern ein endlicher Automat mit Verzweigungen....
Auch wenn es dir noch nicht klar ist...
Ich glaube du möchtest endliche Automaten bauen.
Das kann sein. Hoert sich auf jeden Fall nicht falsch an. Die Frage ist nur: Sehr schwierig??
Ach, nicht wirklich....
Eigentlich ist es nur Logik/Logisch.
Also ich hab mal drüber geschaut und mir was zusammengerieben.
So und nu sag mal, was hier passiert - oder auch nicht.
compiliert fehlerfrei und ohne Warnungen ![]()
// basiert auf: https://forum.arduino.cc/t/zaehlen-von-millis-stoppen-nach-erreichen-eines-wertes/907481/19?u=my_xy_projekt
#include <Servo.h>
const byte BUTTON_Tester = 2;
const byte LED_1 = 3;
const byte LED_2 = 4;
const byte LED_3 = 5;
const byte LED_4 = 6;
bool buttonState = 0;
const byte KANAL_1 = A0;
const byte KANAL_2 = A1;
const byte KANAL_3 = A2;
const byte KANAL_4 = A3;
bool kanalState_1 = 0;
bool kanalState_2 = 0;
bool kanalState_3 = 0;
bool kanalState_4 = 0;
Servo MyServo;
unsigned int winkel = 0;
const byte SCHALTER = 8;
int schalterState = 0;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long pause = 6000;
unsigned long stateMillis = 0;
unsigned int pausen_wert = 6000;
int x = 0;
int y = 0;
bool merker=false;
void setup()
{
Serial.begin(115200);
pinMode(BUTTON_Tester, INPUT_PULLUP);
pinMode(LED_1, OUTPUT);
pinMode(LED_2, OUTPUT);
pinMode(LED_3, OUTPUT);
pinMode(LED_4, OUTPUT);
pinMode(KANAL_1, INPUT_PULLUP);
pinMode(KANAL_2, INPUT_PULLUP);
pinMode(KANAL_3, INPUT_PULLUP);
pinMode(KANAL_4, INPUT_PULLUP);
pinMode(SCHALTER, OUTPUT);
MyServo.attach(7);
}
int schalten (int soll, int ist, int Pause)
{
MyServo.attach(7);
if (soll > ist)
{
for (; ist <= soll; ist++)
{
MyServo.write(ist);
delay(Pause);
}
}
if (soll < ist)
{
for (; ist >= soll; ist--)
{
MyServo.write(ist);
delay(Pause);
}
}
MyServo.detach();
return soll;
}
void loop()
{
buttonState = digitalRead(BUTTON_Tester);
kanalState_1 = digitalRead(KANAL_1);
kanalState_2 = digitalRead(KANAL_2);
kanalState_3 = digitalRead(KANAL_3);
kanalState_4 = digitalRead(KANAL_4);
// Kanal 1 ist Gruen
if (kanalState_1 == HIGH)
{
digitalWrite(LED_1, HIGH);
digitalWrite(SCHALTER, HIGH);
winkel = schalten(170, winkel, 70);
}
// Kanal 2 ist Grau
if (kanalState_2 == HIGH)
{
digitalWrite(LED_2, HIGH);
winkel = schalten(170, winkel, 70);
stateMillis = currentMillis;
Serial.print("stateMillis:");
Serial.println(stateMillis);
// pause steht auf 6000
merker = true;
}
if (!kanalState_1 && !kanalState_2)
{
digitalWrite(LED_2, LOW);
Serial.println("else Zweig");
winkel = schalten(0, winkel, 70);
}
if (millis() - stateMillis > pause && merker)
{
Serial.println("If Bedingung erfuellt.");
winkel = schalten(0, winkel, 70);
merker=false;
x = 1;
}
if (kanalState_3 == HIGH)
{
digitalWrite(LED_3, HIGH);
}
else
{
digitalWrite(LED_3, LOW);
}
if (kanalState_4 == HIGH)
{
digitalWrite(LED_4, HIGH);
}
else
{
digitalWrite(LED_4, LOW);
}
if (buttonState == LOW)
{
digitalWrite(LED_1, HIGH);
digitalWrite(LED_2, HIGH);
digitalWrite(LED_3, HIGH);
digitalWrite(LED_4, HIGH);
}
else
{
digitalWrite(LED_1, LOW);
digitalWrite(LED_2, LOW);
digitalWrite(LED_3, LOW);
digitalWrite(LED_4, LOW);
}
}
[edit] da war ein doppeltes codepaste drin[/edit]
Also laeuft im Dauerlauf hin und her und auch ohne Pause.
Bei
if (!kanalState_1 && !kanalState_2)
steigt er aber aus. Also sobald ich auf Kanal 3 oder 4 gehe. Dazu hiabe ich mir auch schon gedanken gemacht. Meine Idee laesst die Winkel nur innerhalb der jeweiligen Schalter Positionen arbeiten, aber das nur am Rande. Poste das nachher mal.
Aber wie gesagt, Schalter 2: nur hin und her ohne Pause.
Versuch mal die Codezeilen einzusetzen ab
// Kanal 2 ist grau
bis
if (kanalState_3
// Kanal 2 ist Grau
if (kanalState_2 == HIGH)
{
digitalWrite(LED_2, HIGH);
winkel = schalten(170, winkel, 70);
stateMillis = currentMillis;
Serial.print("stateMillis:");
Serial.println(stateMillis);
// pause steht auf 6000
merker = true;
}
if (!kanalState_1 && !kanalState_2)
{
digitalWrite(LED_2, LOW);
Serial.println("else Zweig");
winkel = schalten(0, winkel, 70);
merker = false;
}
if (millis() - stateMillis > pause && merker)
{
Serial.println("If Bedingung erfuellt.");
winkel = schalten(0, winkel, 70);
merker = false;
x = 1;
}
if (kanalState_3 == HIGH)
Ich bau mir mal was auf dem SerMon - dauert vielleicht nen Moment.
So mein Lieber, hier ist doch ein Denkfehler drin!
Wenn Schalter2 AN geht, geht der Servo in Pos1.
Es wird sich die Zeit gemerkt.
Nach Ablauf der Pause geht der in Pos 0
Im nächsten Umlauf ist Schalter2 noch immer AN
Was passiert?
Also brauchst Du einen zusätzlichen Merker, der gesetzt wird, wenn Schalter2 AN geht und gelöscht wird, wenn Schalter1 UND Schalter2 AUS sind.
Ausgewertet wird der Merker dann hier:
if (kanalState_2 == HIGH)
daraus wird:
if ((kanalState_2 == HIGH) && einschaltSperre == false))
Es wird...
Ich weis ihr seid schon viel weiter. Ich will nur nochmal darauf eingehen, warum der Code in Post #19 nicht funktioniert hat.
Du setzt curentmillis = millis(). Dann setzt du statemillis = curentmillis. Sie sind also gleich. Danach vergleichst du curentmillis - statemillis > 6000. Dieser Vergleich kann nie wahr werden. Denn curentmillis - statemillis ist immer = 0 und somit wird der Code in dem If-Block nie ausgeführt.
Unkommentiert und ohne Erklärung.
#include <Servo.h>
const byte BUTTON_Tester = 2;
const byte LED_1 = 3;
const byte LED_2 = 4;
const byte LED_3 = 5;
const byte LED_4 = 6;
bool buttonState = 0;
const byte KANAL_1 = A0;
const byte KANAL_2 = A1;
const byte KANAL_3 = A2;
const byte KANAL_4 = A3;
bool kanalState_1 = 0;
bool kanalState_2 = 0;
bool kanalState_3 = 0;
bool kanalState_4 = 0;
Servo MyServo;
unsigned int winkel = 0;
const byte SCHALTER = 8;
int schalterState = 0;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long pause = 6000;
unsigned long stateMillis = 0;
unsigned int pausen_wert = 6000;
int x = 0;
int y = 0;
bool millisMerker = false;
bool kanalSperre = false;
void setup()
{
Serial.begin(115200);
Serial.println(F("Start..."));
pinMode(BUTTON_Tester, INPUT_PULLUP);
pinMode(LED_1, OUTPUT);
pinMode(LED_2, OUTPUT);
pinMode(LED_3, OUTPUT);
pinMode(LED_4, OUTPUT);
pinMode(KANAL_1, INPUT_PULLUP);
pinMode(KANAL_2, INPUT_PULLUP);
pinMode(KANAL_3, INPUT_PULLUP);
pinMode(KANAL_4, INPUT_PULLUP);
pinMode(SCHALTER, OUTPUT);
MyServo.attach(7);
}
unsigned int schalten (unsigned int soll, unsigned int ist, unsigned int Pause)
{
static unsigned long lastmillis = 0;
if (millis() - lastmillis >= pause)
{
MyServo.attach(7);
Serial.print(F("Servo "));
if (soll > ist)
{
Serial.print("+");
ist++;
}
else if (soll < ist)
{
ist--;
Serial.print("-");
}
MyServo.write(ist);
Serial.println();
}
MyServo.detach();
return soll;
}
void loop()
{
kanalState_1 = digitalRead(KANAL_1);
kanalState_2 = digitalRead(KANAL_2);
// Kanal 1 ist Gruen
if (kanalState_1)
{
Serial.println(F("kanal1 high"));
/*
digitalWrite(LED_1, HIGH);
digitalWrite(SCHALTER, HIGH);
winkel = schalten(170, winkel, 70);
*/
}
// Kanal 2 ist Grau
if (kanalState_2)
{
if (!kanalSperre)
{
/*
digitalWrite(LED_2, HIGH);
winkel = schalten(170, winkel, 70);
*/
Serial.println(F("kanal2 high"));
kanalSperre = true;
if (!millisMerker);
{
stateMillis = millis();
Serial.print("stateMillis:");
Serial.println(stateMillis);
millisMerker = true;
}
}
}
if (!kanalState_1)
{
if (!kanalState_2)
{
/*
digitalWrite(LED_2, LOW);
winkel = schalten(0, winkel, 70);
*/
millisMerker = false;
kanalSperre = false;
Serial.println(F("alle kanaele low"));
}
else if (!millisMerker)
{
/*
digitalWrite(LED_2, LOW);
winkel = schalten(0, winkel, 70);
*/
Serial.println(F("nach millis-Ablauf alle kanaele low"));
}
}
if (millisMerker)
{
if (millis() - stateMillis > pause)
{
// winkel = schalten(0, winkel, 70);
Serial.println(F("millis() low"));
millisMerker = false;
}
}
}
Wenn der geht, muss daraus ein logisch verständliches gebaut werden.
Alter!! Also ich teste das jetzt gleich mal, aber begreifen naja....
Aber natuerlich meinen allerliebsten Dank!!
Also der Serielle Monitor reagiert ganz geschmeidig, und natuerlich heissen Dank das du mir das Servo Skript angepasst hast. Macht aber leider keinen Mucks. Lass mich das Alte ausprobieren und dann berichte ich.
@Plumps , das stimmt so wie du es sagst. Ist aber schon mein dritter oder vierter Versuch. Hast du Lust deine Variante mit einzubringen? Das wuerde mir sehr helfen. Ich weiss nur noch das in einer anderen Konstellation die Werte von currentmillis und statemillis immer vor ein ander hergelaufen sind. Irgendwie konnte ich statemillis nie festsetzen, zaehlte immer mit hoch. Aber ich komme da bestimmt noch mal im Detail spaeter drauf zurueck.
Tuts
Aber ich bin damit nicht gluecklich, also doch, ein wenig, es lebt, es leeeeebt!!! Aber die Struktur ist echt schwer zu durchblicken.
Du darfst deinem statemillis nur den Wert von curentmillis geben, wenn der "Timer" neu gestartet werden soll. Jedesmal wenn du statemillis gleich curentmillis setzt müssen wieder die eingestellten Millisekunden vergehen (bei deinem Beispiel 6000 Millissekunden).
Also am besten den Wert von curentmillis erst dann statemillis übergeben, wenn der Vergleich curentmillis - statemillis > 6000 wahr ist, in dem dazu folgenden if-Block. Dadurch wird bei erreichen der Differenz von über 6000, statemillis wieder gleich curentmillis gesetzt. Jetzt würde es wieder 6000 Millisekunden dauern, bis der Vergleich wieder wahr ist.
Um Struktur in Daten(und Code) zu bringen, gibt es das Schlüsselwort struct.
Zudem kann man durchaus auch Strukturen in Arrays stopfen, was alle mal besser ist, als Variablen durchzunummerieren.