Unabhängiger Timer gesucht

OP Persönliche Seite #3351416
Lesenswert?

Hallo,

ich möchte gerne eine Nachlaufsteuerung von 1-60 Sekunden für eine LED 
einbauen, und zwar hier:

...
//      Größer als.....
      if ((o == (1) && u == (1)))
      {
          if (temp_val.i/100 > t || humid_val.i/100 > h)
        {
         DDRD |= (1 << DDD0); // Setzen
        }
        else
        {
         DDRD &= ~(1 << DDD0); // Rücksetzen <--- hier soll eine 
Nachlaufsteuerung rein
        }
      }
...

Allerdings soll die Nachlaufsteuerung nicht den ganzen Programmablauf 
blockieren, während sie aktiv ist.
Ich habe Timer getestet, allerdings stoppte während der Timer lief das 
ganze Programm.

Ich habe echt keine Idee mehr, wie ich das realisieren kann und wende 
mich deshalb an Euch.

Danke im Vorraus.

Gruss Stefan
Angehängte Dateien:
Gast #3351426
Lesenswert?

Stefan B. schrieb:

> Allerdings soll die Nachlaufsteuerung nicht den ganzen Programmablauf
> blockieren, während sie aktiv ist.
> Ich habe Timer getestet, allerdings stoppte während der Timer lief das
> ganze Programm.

Dann hast du was falsch gemacht.

> Ich habe echt keine Idee mehr, wie ich das realisieren kann

Lerne programmieren.
Gast #3351448
Lesenswert?

so ganz blicke ich durch deinen Code geraden nicht durch.

Prizipiell würde ich folgendemaßen vorgehen:
Benutze einen Timer, der in regelmäßigen Abständen aufgerufen wird und 
eine Variable (initialisiert mit 0) hochzählt. Sobalt die Variable einen 
bestimten Wert überschreitet, wird die LED abgeschaltet und es wird 
nicht mehr weitergezählt.

Ich hoffe das hilft dir weiter!
Gast #3351475
Lesenswert?

Brech das ganze runter in eigenständig funktionierende Teile, die mal 
dann auch einzeln testen kann.
Lass die PeDa "Lib" in eigenem File, das zeigt wo du sie her hast und du 
Must sie nicht immer durchblättern.
Includiere NUR .h Files. Spart Compiler/Linker-Gemeckere.
Lese PeDa's Thread in der Codesammlung zum Thema [[Wartezeiten effektiv 
(Scheduler)]]
(irgendwie bin ich zu blöd für's verlinken!?)
OP Persönliche Seite #3351594
Lesenswert?

Erstmal danke für die Antworten.

Zur Info, da mit der main.c niemand was anfangen kann. Das wird ein 
Thermo-/Hygrometer mit einer einstellbaren Alarmgrenze für größer oder 
kleiner Feuchtigkeit und ebenso die Temperatur und einem 
MinMax-Speicher. Funktioniert ja auch soweit. Siehe Bilder. Die Led wird 
irgendwann mal ein Lüfter o.Ä.

Ich möchte gerne, dass die Led eine Nachlaufzeit hat, denn wenn die 
Temperatur zwischen der einstellbaren Grenze schwankt, wird sie 
dementsprechend auf high und dann wieder auf low geschalten, zu deutsch 
blink sie dann....das würde ich gerne vemeiden wollen und deswegen der 
Gedanke mit der Nachlaufzeit.

Ich habe wahrscheinlich einen Denkfehler gemacht. Ich werde das nochmal 
mit einem Timer probieren und falls ich nichtmehr weiter komme, mich 
nochmal hier melden.

Gruss Stefan
Angehängte Dateien:
#3352041
Lesenswert?

Noch ein Tip
1
         if (temp_val.i/100 > t || humid_val.i/100 > h)
2
        {
3
         DDRD |= (1 << DDD0); // Setzen
4
        }
5
        else
6
        {
7
         DDRD &= ~(1 << DDD0); // Rücksetzen
8
        }

du willst da ganz sicher nicht an den DDR Registers rumpfriemeln.
Mit DDRx stellst du ganz am Programmanfang den Portpin auf Ausgang und 
dann benutzt du das PORTx Register um den Pin auf 0 oder 1 zu schalten.
1
         if (temp_val.i/100 > t || humid_val.i/100 > h)
2
        {
3
           PORTD |= (1 << PD0); // Setzen
4
        }
5
        else
6
        {
7
           PORTD &= ~(1 << PD0); // Rücksetzen
8
        }



Für den Fall, dass du tatsächlich mal irgendwo einen Nachlauf brauchst. 
Du hast bereits einen Timer im System. Das ist gut so, denn über den 
führt der Weg. Dein Timer 'tickt' mit 10ms (d.h. in diesen Intervallen 
wird die ISR aufgerufen)
1
volatile uint16_t shutdownTime;
2

3
...
4

5
ISR( ... )
6
{
7

8
   ....
9

10
   if( shutdownTime > 0 )
11
   {
12
     shutdownTime--;
13
     if( shutdownTime == 0 )
14
       PORTD &= ~( 1 << PD0 );
15
   }
16
}

alle 10ms wird also die noch verbleibende Restzeit geprüft, ob sie noch 
größer 0 ist. Wenn ja, wird die Restzeit verringert und wenn dann 0 
rauskommt, dann wird abgeschaltet.
Bleibt nur noch das einschalten. Das passiert aufgrund irgendwelcher 
Bedingungen zb in main
1
int main()
2
{
3
  DDRD |= ( 1 << PD0 );    // Pin auf Ausgang
4
  
5
  ....
6

7
  while( 1 )
8
  {
9

10
    if( irgendwas ganz wichtiges ist passiert )
11
    {
12
      cli();    // Interrupts disablen, damit gefahrlos auf shutdownTime
13
                // zugegriffen werden kann. Ist ja ein 16 Bit Wert
14

15
      shutdownTime = 500;    // 5 Sekunden * 10 Millisekunden macht einen
16
                             // Wert von 500
17
      PORTD |= ( 1 << PD0 ); // ... und einschalten
18

19
      sei();    // Gefahr vorüber, Interrupts sind wieder erlaubt
20
    }
21
    ....
22
  }
23

24
}

in main wird eingeschaltet und die abzulaufende Zeit eingestellt. Wird 
immer wieder zugewiesen, dann fängt die Zeit auch immer wieder neu zu 
laufen an. Wird irgendwann die Zuweisung nicht mehr gemacht, dann wird 
in der Timer-ISR die 'Zeitvariable' sukzessive bei jedem Aufruf ein 
wenig runtergezählt, bis dann irgendwann 0 erreicht wird und der Ausgang 
in der ISR abgeschaltet wird. Voila: ein Nachlauf ist entstanden - 5 
Sekunden nachdem die Bedingung 'irgendwas wichtiges' nicht mehr 
zutrifft, schaltet der Ausgang ab.
OP Persönliche Seite #3356332
Lesenswert?

Hi @all,

ich habe es hinbekommen mit der Hysterese. Allerdings die 
"Programmwurscht" ist immernoch vorhanden. Sobald ich da was 
durcheinander bringe, funktioniert meine Umrechnerei von +Graden zu 
-Graden nichtmehr. Irgendwie blicke ich, wenn es so weiter geht, selbst 
nichtmehr durch ;-)

Das Ding ist auf keinen Fall perfekt (vom Programmierstil her), aber die 
Funktionen, die ich haben wollte, sind vorhanden. Vielleicht bette ich 
iwann noch ne Uhr mit Datum ein. Damit man immer schön sieht, wann es am 
kältesten draussen war.

Die Hysterese ist jetzt variabel wählbar und funzt perfekt.

Und ich habe wieder einiges an Erfahrung/Wissen dazugewonnen, wozu das 
Projekt letztendlich auch gedacht war.

Wenn es Sinn machen sollte, auch wenn niemand in der main.c durchsteigt, 
könnte ich mein "Projekt" in die Codesammlung stellen. Aber davor würde 
ich gerne paar Meinungen hören.
Angehängte Dateien:
#3356379
Lesenswert?

Karl Heinz Buchegger schrieb:
> while( 1 )
>   {
>
>     if( irgendwas ganz wichtiges ist passiert )
>     {
>       cli();    // Interrupts disablen, damit gefahrlos auf shutdownTime
>                 // zugegriffen werden kann. Ist ja ein 16 Bit Wert
>
>       shutdownTime = 500;    // 5 Sekunden * 10 Millisekunden macht
> einen
>                              // Wert von 500
>       PORTD |= ( 1 << PD0 ); // ... und einschalten
>
>       sei();    // Gefahr vorüber, Interrupts sind wieder erlaubt
>     }

Mittlerweile kann ich ja schon so ein bisschen, aber  KEINER  und 
auch kein Buch erklärt das so schön wie du, lieber Karl Heinz!
Gast #3356504
Lesenswert?

Besser wäre aber:
1
#include <util/atomic.h>
2
...
3
 while( 1 )
4
   {
5

6
   if( irgendwas ganz wichtiges ist passiert )
7

8
     ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
9
     {
10
       shutdownTime = 500;    // 5 Sekunden * 10 Millisekunden macht einen
11
                              // Wert von 500
12
       PORTD |= ( 1 << PD0 ); // ... und einschalten
13
     }
14

15
  }

Denn eigentlich will man das I-Flag im Zustand davor, der nicht "1" sein 
muß.
Oder man mag unerklärliche Fehler suchen ;-)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren