Hallo zusammen,
ich stehe vor folgendem Problem:
Ich habe im Loop meines Sketches eine Unterfunktion uf, die unter bestimmten Umständen ausgeführt werden soll (in einem if-Statement festgelegt: wenn(Bedingung)-->führe uf aus). Innerhalb dieser Unterfunktion deklariere ich eine Variable x mit static uint32_t x = millis();
Hierbei wird NUR beim ERSTEN Durchlauf der Unterfunktion für x der aktuelle milli-Wert eingesetzt und der Wert BLEIBT und ändert sich nicht in einem erneuten Ablaufen der Unterfunktion.
Jetzt zu meiner Frage: Wie kann ich dafür sorgen, dass, nachdem eine Zeit lang die oben genannte Bedingung nicht erfüllt wird, also die Unterfunktion nicht ausgeführt wird, in der Unterfunktion die Variable x wieder beim ERSTEN Durchgang einen NEUEN Wert erhält?
Viele Grüße und auf hoffentlich viele zielführende Antworten
Noah
if (blablabla) { x=irgendwas; }
nachdem eine Zeit lang
Was ist "eine Zeit lang" ?
Wenn die Funktion das selbst rauskriegen soll (weil x lokal static ist), muss sie nicht nur den Anfangswert, sondern auch den des letzten Aufrufs (in einer weiteren static Variable) wissen.
( Wieso auch ? Was ist der Sinn von x )
Ich fürchte, du willst etwas Einfaches kompliziert machen ...
Maker1212:
Innerhalb dieser Unterfunktion deklariere ich eine Variable x mit
static uint32_t x = millis();
Hierbei wird NUR beim ERSTEN Durchlauf der Unterfunktion für x der aktuelle milli-Wert eingesetzt und der Wert BLEIBT und ändert sich nicht in einem erneuten Ablaufen der Unterfunktion.
Wie kann ich dafür sorgen, dass, nachdem eine Zeit lang die oben genannte Bedingung nicht erfüllt wird, also die Unterfunktion nicht ausgeführt wird, in der Unterfunktion die Variable x wieder beim ERSTEN Durchgang einen NEUEN Wert erhält?
suchst Du sowas?
static u_int32_t x = 0;
ruecksetzzeit = 10000; // 10 sekunden
if (millis() - x > ruecksetzzeit){x=0;}
if (x=0) {x=millis();}
Alternativ kannst Du auch via
void uf(bool ruecksetz)
{ if (ruecksetz) x=millis();}
x neu setzen, wenn Du im Hauptprogramm die Prüfung machst und HIGH an die uf übergibst.
Hier der Sketch etwas gekürzt, da das meiste irrelevant ist:
//jetzt kommt manuelles Zeug:
const int potiPin = A0; //Ablesepin für Poti
const int ledPin = 5; //PWM Signal für LED-Leiste (Mitte von Transistor)
int buttonPushCounter = 0; //für An/Aus
int buttonState = 0; //für An/Aus
int lastButtonState = 0; //für An/Aus
int potiWert = 0; //für Poti
int smoothWert = 0; //zum Abrunden vom abgelesenen Wert
int pwm = 0; //für Poti
//jetzt kommt auto Zeug:
int dimmer = 0;
bool hochdimmen = false;
int eingestellteStunde = 0;
int eingestellteMinute = 0;
int endeMinute = eingestellteMinute+9;
//jetzt kommt die Stuerung:
int stoppen = 0;
int stopstatus = 0;
int stopvariable = 0; //zum manuellen Ausschalten von AUTO (wenn == 1 --> kein AUTO)
//jetzt kommt der Touch Sensor:
#include <CapacitiveSensor.h>
CapacitiveSensor capSensor = CapacitiveSensor(6, 7);
int threshold = 400;
void setup() {
Serial.begin(9600); //nicht notwendig
pinMode(ledPin, OUTPUT); // ledPin als OUTPUT
void loop() {
TouchSensor();
if(hour() == eingestellteStunde && minute() >= eingestellteMinute && minute() <= endeMinute && stopvariable == 0){
stoppen = buttonState;
if(stoppen == LOW){
stopstatus = 0;
}
if(stoppen == HIGH){
stopstatus = 1;
}
if(stopstatus == 1){
stopvariable = 1;
led_manuell();
}
if(stopstatus == 0){
hochdimmen = true;
led_auto();
}
}
else{
led_manuell();
}
if(hour() == eingestellteStunde && minute() == eingestellteMinute+12){ //hier dann Uhrzeit in der Nacht eingeben!!!
stopvariable = 0;
}
if(eingestellteStunde == 0 && eingestellteMinute == 0){
stopvariable = 1; //sorgt dafür, dass ich sagen kann "LED soll GAR NICHT angehen"
}
else{
stopvariable = 0;
}
delay(200);
}
void led_manuell(){
if (buttonState != lastButtonState) {
if (buttonState == HIGH) {
buttonPushCounter++;
}
delay(50);
}
lastButtonState = buttonState;
if (buttonPushCounter % 2 == 0) {
// digitalWrite(ledPin, HIGH);
potiWert = analogRead(potiPin); //ließt von Poti Wert zwischen 0 und 1023 ab
smoothWert = 0.7*smoothWert+0.3*analogRead(potiPin);
pwm = map(smoothWert, 0, 1023, 5 , 255); //je nachdem, wie groß abgelesener Wert ist, wird PWM Signal länger oder kürzer
analogWrite(ledPin, pwm); //LEDs werden nach Bedarf gedimmt (manuell)
} else {
digitalWrite(ledPin, LOW); //sonst kein PWM Signal
}
}
void led_auto(){
if (hochdimmen == true) {
static uint32_t previousMillis = millis();
if (millis() - previousMillis < 2000) {
dimmer = 1;
analogWrite(ledPin, dimmer);
}
if (millis() - previousMillis > 2000 && millis() - previousMillis < 83000) {
static uint32_t dimmMillis = millis();
if (millis() - dimmMillis > 1825 && dimmer < 40) {
dimmer++;
analogWrite(ledPin, dimmer);
Serial.print(dimmer);
dimmMillis = millis();
}
}
if (millis() - previousMillis > 83000 && millis() - previousMillis < 300000) {
static uint32_t dimmMillis = millis();
if (millis() - dimmMillis > 1000 && dimmer < 255) {
dimmer++;
analogWrite(ledPin, dimmer);
Serial.print(dimmer);
dimmMillis = millis();
}
}
if (millis() - previousMillis > 480000) {
analogWrite(ledPin, 255); //dieser Wert muss auf den Endwert von dimmer gesetzt werden
}
}
hochdimmen = false;
}
void TouchSensor(){
long sensorValue = capSensor.capacitiveSensor(30);
//Serial.println(sensorValue);
if(sensorValue > threshold){
buttonState = HIGH; // hier HIGH und unten LOW, wenn Lampe nach Reset AN sein soll
//Serial.println(buttonState);
}
else{
buttonState = LOW;
//Serial.println(buttonState);
}
}
Es geht vor allem um die Funktion led_auto und natürlich die loop Schleife...
Wenn ich z. B. eingestellteStunde = 13 und eingestellteMinute = 10 soll um diese Uhrzeit (durch ein DCF77 Empfänger erhalten) led_auto durchgeführt werden. Gehen wir davon aus, dass der Arduino bis dahin 2 Stunden mit Strom versorgt wurde, ist demnach previousMillis = 3600s21000=7200000. Wenn dann die Bedingungen, um led_auto durchzuführen nicht mehr zutreffen, möchte ich, dass die Variable dann um beispielsweise 15:10 (eingestellteStunde = 15 und eingestellteMinute = 10) nicht mehr 7200000 ist, sondern für einen NEUEN Wert (in dem Fall 14400000, da 4 Stunden Laufzeit des Arduino) "aufnahmefähig" ist. (Da ich die Variable als static uint32_t deklariert habe, ist sie ja, nachdem sie einmal einen Wert erhalten hat, nicht mehr "aufnahmefähig" für einen NEUEN/SPÄTEREN Wert...
Hoffe es ist nun verständlicher...
Maker1212:
(Da ich die Variable als static uint32_t deklariert habe, ist sie ja, nachdem sie einmal einen Wert erhalten hat, nicht mehr "aufnahmefähig" für einen NEUEN/SPÄTEREN Wert...
Du verwechselst offensichtlich 'const' und 'static'. Ein static Variable in einer Funktion bedeutet nur, dass diese Variable beim erneuten Aufruf der Funktion immer noch den letzten aktuellen Wert enthält. Das heißt nicht, dass Du sie in der Funktion nicht ändern könntest. Das ist jederzeit möglich - allerdings nur innerhalb der Funktion in der sie definiert wurde.
Maker1212:
Hier der Sketch etwas gekürzt, da das meiste irrelevant ist:
zuviel gekürzt.
Es fehlt nach dem Setup die schliessende Klammer und die Uhr ist vollkommen raus...
Aber egal.
static uint32_t previousMillis = millis();
if (millis() - previousMillis < 2000) {
Die Bedingung ist IMMER erfüllt.
... damit wird das nie ausgeführt
if (millis() - previousMillis > 2000 && millis() - previousMillis < 83000) {
static uint32_t dimmMillis = millis();
und damit das hier:
if (millis() - previousMillis > 83000 && millis() - previousMillis < 300000) {
static uint32_t dimmMillis = millis();
nie abgearbeitet.
Da ich die Variable als static uint32_t deklariert habe, ist sie ja, nachdem sie einmal einen Wert erhalten hat, nicht mehr "aufnahmefähig" für einen NEUEN/SPÄTEREN Wert...
Hoffe es ist nun verständlicher...
Nein, Microbahner hat Dir Deinen Denkfehler schon gezeigt und ich habe Dir oben was vorgegeben, das kannst Du nutzen.
Allerdings musst Du Deine Zuweisungen unbedingt verändern, denn sonst werden bestimmte Zustände nicht erreicht.
Gib doch mal unabhängig vom Code bekannt, was Du eigentlich machen willst.
@my_xy_projekt "Die Bedingung ist IMMER erfüllt." Ich würde sagen sie ist 2s erfüllt.
Gruß Thorsten
my_xy_projekt:
zuviel gekürzt.
Es fehlt nach dem Setup die schliessende Klammer und die Uhr ist vollkommen raus...
Aber egal.
static uint32_t previousMillis = millis();
if (millis() - previousMillis < 2000) {
Die Bedingung ist IMMER erfüllt.
... damit wird das nie ausgeführt
if (millis() - previousMillis > 2000 && millis() - previousMillis < 83000) {
static uint32_t dimmMillis = millis();
und damit das hier:
if (millis() - previousMillis > 83000 && millis() - previousMillis < 300000) {
static uint32_t dimmMillis = millis();
nie abgearbeitet.
Nein, Microbahner hat Dir Deinen Denkfehler schon gezeigt und ich habe Dir oben was vorgegeben, das kannst Du nutzen.
Allerdings musst Du Deine Zuweisungen unbedingt verändern, denn sonst werden bestimmte Zustände nicht erreicht.
Gib doch mal unabhängig vom Code bekannt, was Du eigentlich machen willst.
Ich kann dir aber zu 100% sagen, dass die zwei if-Funktionen abgearbeitet werden und, dass previousMillis nur 1x einen Wert bekommt. Habe mir den Sketch nochmal genauer diesbezüglich angeschaut, aber kann dir trotzdem nicht ganz erklären, warum previousMillis nicht die ganze Zeit "upgedated" wird... Vielleicht findet es ja jemand raus
Ich glaube ich habe jetzt für mich eine Lösung gefunden...
Was ich machen will: Um eine best. Uhrzeit: LED dimmt hoch (Uhrzeit wird per IR eingegeben). Das Hochdimmen kann manuell unterbrochen werden und die LED lässt sich generell manuell steuern.
if (millis() - previousMillis > 83000 && millis() - previousMillis < 300000) {
static uint32_t dimmMillis;
dimmMillis = millis();
Propier mal so. Du deklarierst und initialisierst gleichzeitig, die Initialisierung wird aber nur einmal durgeführt.
Deswegen in 2 Anweisungen