delay oder millis oder?

Thenewuser

Grünschnabel
hi, ich hab zwar schon gesucht aber leider nichts passendens gefunden.

Für mein arduino habe ich ein sketch geschriben der soweit alles mach was es soll.
In diesem Sketch habe ich eine "Funktion"

PHP:
void dimmenlinks() {
   if (statTFL_L==100&&statTFL_R==100&&digitalRead(Bl_L)==HIGH) {
            for (int fadeValue = 255 ; fadeValue >= 50; fadeValue -= 5) {
           analogWrite(TFL_L, fadeValue);delay(10);
           statTFL_L = 60;}     
}}
void aufhellenlinks() {
       if (statTFL_L==60&&statTFL_R==100&&digitalRead(Bl_L)==LOW) {
            for (int fadeValue = 50 ; fadeValue <= 255; fadeValue += 5) {
           analogWrite(TFL_L, fadeValue);delay(10);
           statTFL_L = 100;}   
}}

die funktion startet wenn die Variablen und der Eingang als Bedingung erfüllt sind.
PHP:
TFL_R=100&&TFL_L=100&&Eingang(Bl_L)==HIGH

jedoch liefert mein Eingangssignal (sofern aktiv)
PHP:
Eingang(Bl_L)
kein permanentes Signal sondern
"HIGH/LOW/HIGH/LOW" usw. jeweils o,5sec im wechsel

dadurch wird "aufhellenlinks" sofort durchlaufen und dann gleich wieder
"dimmenlinks"

Wenn ich das Eingangssignal tatsächlich wegnehme, ist ja
PHP:
digitalRead(Bl_L)==LOW

Wie kann ich prüfen ob "digitalRead(Bl_L)==LOW" schon 3sec. LOW ist (also tatsächlich kein signal anliegt)
und das in die Fuktion einbinden?

anders gesagt, bleibe im "statTFL_L = 60;" bis digitalRead(Bl_L)==LOW
(länger als 3sec.)


ich danke euch schon mal
 

cwriter

Erfahrenes Mitglied
Hi

Habe ich richtig verstanden, dass du erst bei einem "stabilen" Signal eine deiner Funktionen ausführen willst?
Dann wäre folgendes möglich:
C:
char curr_state = 123;
unsigned int chg_time = 0;

void loop()
{
    char tmp = digitalRead(Bl_L);
    if(tmp != curr_state) {
        curr_state = tmp;
        chg_time = millis();
    }
    else if(millis() - chg_time >= 3000) {
        if(curr_state == LOW) dimmen(...)
        else aufhellen(...);
    }
}
Kurz zur Funktionsweise: Loop wird bekanntermassen immer wieder ausgeführt. Wenn der aktuelle Status (curr_state) in jedem Durchlauf gleich dem Input ist, hat keine (beobachtete) Änderung stattgefunden. Falls der Durchgang, der mind. 3000ms = 3s nach dem Setzen des Zeitpunkts der letzten Änderung ausgeführt wird, erreicht wird (falls eine Änderung stattfindet, wird die Zeit ja zurückgesetzt), dann war der Input stabil und kann verwendet werden.

Alles klar?

/EDIT: Übrigens sind für Signaländerungen Interrupts (Edge detects) wesentlich besser geeignet als Polling, da dort Hardware verwendet werden kann, statt die ALU zu stressen.

Gruss
cwriter
 
Zuletzt bearbeitet:

Thenewuser

Grünschnabel
Cool danke,
bin absoluter beginner in der Programmierung und muss schauen das ich den Ansatz richtig deute und umsetzten kann. evtl kannst du ja noch mal helfen ;)

Noch ein paar backround infos zu meinem Sketch.
Ich arbeite mit mehreren Eingängen die (sofern aktiv) permanent 5V=HIGH liefern.

Mit diesen Eingangssignalen kann ich dann ohne probleme (wenn aktiv) meine LED bspw. auf 100% hoch dimmen (wenn wert HIGH)
und erst dann runter auf 0 dimmen wenn der jeweilige wert auf LOW fällt (Eingangssignal inaktiv)

(darauf beruht quasi der aktuelle stand)

Jetzt ist es so, dass mein Eingangssignal (sofern aktiv) digitalRead(Bl_L) KEIN permanentes Signal liefert. sondern ein gepulstes Signal. HIGH/LOW/HIGH/LOW etc. Frequenz von 1,5 Hz ± 0,5 Hz (90 HIGH pro Minute ± 30).

jetzt ist es ja so das mein Signal zwar aktiv ist aber technisch betrachtet HIGH/LOW/HIGH/LOW liefert.

so muss ich also prüfen ob mein Eingansignal logisch LOW ist. also permanent (mis 3 sec) low.

Ergo so denke ich, benötige ich eine prüfung (in der art)
if digitalRead(Bl_L) für mehr als 3sec.;
dann "setze eine variable die ich abfragen kann)


kan man das so bauen???
 

cwriter

Erfahrenes Mitglied
Mit diesen Eingangssignalen kann ich dann ohne probleme (wenn aktiv) meine LED bspw. auf 100% hoch dimmen (wenn wert HIGH)
Also geht es dir um PWM? Oder ist 0101 (LOW=0, HIGH=1) voll 1 und nur 0000 ist voll 0 (alles ist 1, ausser bei 0000, dann ist es 0)?
Gibt es einen Grund, weshalb du ein so niederfrequentes Signal benutzen willst?
Ergo so denke ich, benötige ich eine prüfung (in der art)
if digitalRead(Bl_L) für mehr als 3sec.;
dann "setze eine variable die ich abfragen kann)
Ja, mein Code oben macht das. Allerdings ist er auch auf die andere Seite so. Im Prinzip übernimmt es die Bereinigung des Contamination Delay der Digitaltechnik, also ist es nur LOW, wenn das Signal LOW bleibt, und nur HIGH, wenn das Signal HIGH bleibt.
Falls dir egal ist, wie HIGH das Signal tatsächlich ist (50%, 75%, ...?), dann kannst du den obigen Code so abändern, dass es immer HIGH ist, und nur in Ausnahmefällen LOW. (Einen if-Block und für HIGH die Zeitkondition wegnehmen).

Allerdings frage ich mich, ob ein 1.5Hz-Signal überhaupt Sinn macht. Um Dimmstufen zu definieren, müsstest du damit für 60 Stufen schon eine Minute lang warten. Und nur als HIGH-LOW ist PWM Overkill.
kan man das so bauen???
Ja, mein Code oben macht für LOW genau das. Allerdings muss für HIGH alles HIGH sein, aber durch tertium non datur ist das Signal ja genau dann HIGH, wenn es nicht LOW ist.

Gruss
cwriter
 

Thenewuser

Grünschnabel
ja mir geht es umd das PWM dimmen von leds. Allerdings sind die "Schalter" für dimmen auf 100% und wierder auf 0% meine Eingangssignale.

Allerdings frage ich mich, ob ein 1.5Hz-Signal überhaupt Sinn macht. Um Dimmstufen zu definieren, müsstest du damit für 60 Stufen schon eine Minute lang warten. Und nur als HIGH-LOW ist PWM Overkill.

Mein eingangssignal ist leider fest definiert 1.5Hz! Dieses will ich ja nicht als PWN Ausgangsignal verwenden.

ich werde das mal mit deinem Code testen ;) danke schon mal