Forum: Mikrocontroller und Digitale Elektronik Zeitabläufe mit µC (xMega)


von David .. (david1)


Lesenswert?

Hallo,

ich habe vor, bzw. bin gerade an der Umsetzung des folgenden Projekts:
Ich hab ein Board mit nem xMega16D4 auf dem soll folgendes geschehen, 
nach einem bestimmten Zeitplan sollen Dinge ausgeführt werden.

Das folgende (schreib das zur Vereinfachung nur mit LED an/aus)
Led1 an
  10s warten
Led1 aus
Led2 an
  15s warten
Led2 aus

Das mit wait zu machen is mal eine ganz schlechte Idee, also Timer.

Das hab ich mir so vorgestellt, den Timer so einstellen dass ein Tick 
alle 10ms stattfindet, dann wird immer eine Variable (ich nenn sie mal 
A) hochgezählt mit dem Takt.

Dann im Programm iwie an der Led1 an z.B. den aktuellen Wert von A 
merken, den 10s addieren und das in ne Zwischenvariable B speichern, und 
dann später überprüfen wann A = B ist und dann Led1 aus schalten.


Jeder der etwas Ahnung hat wird jetzt wahrscheinlich die Hände überm 
Kopf zusammen schlagen ... Ich übrigens auch, aber ich komm im Moment 
grad auf nix besseres (Betriebsblind? ...)

Daher die Frage, wie macht man sowas ordentlich?
Steh da grad etwas aufm Schlauch.

EDIT: ganz vergessen, eigentlich muss man es ja nicht Wissen, geht ja 
nur ums Prinzip wie man das umsetzt, aber für die dies interessiert, ich 
arbeit in C.

David

: Bearbeitet durch User
von Andreas B. (bitverdreher)


Lesenswert?

Hi,
Das mit der Variable A im Timer ist schon richtig. Die zählst Du hoch.
Im Hauptprogramm tust Du nichts anderes als diese Variable auszuwerten.
(sinnvollerweise mit einem case Konstrukt)
Hier vergleichst Du die Variable mit den gewünschten Zeiten Deiner 
Ereignisse.
In Deinem Fall also:

case A
A=0:
Led1 an

#  10s warten
A=1000: #10ms x 1000
Led1 aus
Led2 an

#  15s warten
A=2500: #25ms x 1000 (ab A=1000 15s)
Led2 aus

endcase

Und wenn der Zyklus beendet ist, setzt Du A in Deinem Hauptprogramm 
wieder auf 0.

Das ist nichts anderes als eine Statemaschine.


Gruß
Andreas

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

David .. schrieb:

> Das hab ich mir so vorgestellt, den Timer so einstellen dass ein Tick
> alle 10ms stattfindet, dann wird immer eine Variable (ich nenn sie mal
> A) hochgezählt mit dem Takt.
>
> Dann im Programm iwie an der Led1 an z.B. den aktuellen Wert von A
> merken, den 10s addieren und das in ne Zwischenvariable B speichern, und
> dann später überprüfen wann A = B ist und dann Led1 aus schalten.

Das kann man im Prinzip genau so machen, wie du das vorschlägst.

Ich machs ganz gerne anders rum.
Ich hab keinen Zähler der hochzäht, sondern pro LED einen Zähler der 
runterzählt. Quasi ein Countdown für jede LED, wie lange sie noch 
brennen soll.
In der Hauptschleife wird der Countdownzähler auf einen Wert gesetzt, 
der der gewünschten Zeitdauer der Brenndauer entspricht (unter 
Berücksichtigung der ISR-Aufrufzeiten) und die LED eingeschaltet. In der 
ISR wird der Zähler sukzessive wieder runter gezählt und wenn 0 erreicht 
ist, wird in der ISR die LED abgeschaltet (oder sonst irgendeine Aktion 
ausgelöst).

Variationen davon sind natürlich möglich. Worauf es mir ankommt ist, 
dass ich das Gefühl habe, dass Countdown-Steuerungen auf dieser Ebene 
oftmals ein bischen einfacher sind, als eine Uhr die hochzählt.

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

Karl Heinz schrieb:
> Worauf es mir ankommt ist,
> dass ich das Gefühl habe, dass Countdown-Steuerungen auf dieser Ebene
> oftmals ein bischen einfacher sind, als eine Uhr die hochzählt.

Vor allen Dingen muss man bei Änderungen von Zeiten nur an einer Stelle, 
nämlich dort wo der Countdown-Wert gesetzt wird, etwas ändern und nicht 
überall alle Schaltzeitpunkte umrechnen.

von runtastic (Gast)


Lesenswert?

Vor kurzem gab's hier mal so eine Art Cronjob für uC...

von runtastic (Gast)


Lesenswert?

Beitrag "Crontab Library für avr"

Keine Ahnung ob es was taugt, habs mir noch nicht angesehen.

von Florian G. (stromflo)


Lesenswert?

Guten Tag,

hier gibt es auch noch einen schönen Ansatz solche Zeitsteuerungen zu 
erschlagen.

Beitrag "Wartezeiten effektiv (Scheduler)"

Damit sollte sich sowas gut realisieren lassen. Man muss nur im Code die 
Timerkonfiguration auf ATxmega trimmen...

Vielleicht hilft das ja schon mal weiter.

Gruß Flo

von David .. (david1)


Lesenswert?

Wow, vielen Dank für die Antworten, werde ich mir gleich ansehen.

Inzwischen hab ich aber auch schon eine Lösung:

ISR(RTC_OVF_vect)
{
  timerTime++;
}

und ein Zeitablauf sieht dann so aus:
      switch (timerTime)
      {
        case 0:
          //led1 an
        break;

        case 200:
          //led1 aus
          //led2 an
          //sound#2 starten
        break;

        case 800:
          //led2 aus
          //sound stoppen
          timerTime = 0;
        break;
      }

Ziemlich simpel und für mich derzeit schonmal ausreichend :)

von chris (Gast)


Lesenswert?

du musst dabei halt sicherstellen, dass der switch-case oft genug 
aufgerufen wird, dass du nicht einen Timertick verpasst. Sonst könnte es 
passieren, dass z.B. timerTime > 800 wird und dann dauert es je nach 
Datentyp ein bisschen, bis die überläuft und wieder bei 0 anfängt ;)

von David .. (david1)


Lesenswert?

Sehr guter Punkt.

den RTC hab ich so eingestellt das es alle 10ms ein Tick gibt, das 
dürfte bei 32MHz der CPU wohl locker reichen.
Und da ich nichts delays mache sondern nur LEDs, Servos und nen externes 
Soundmodul (WTV020 von eBay aus China falls jemand sowas zufällig sucht) 
hab ich da auch kein Problem damit, zumindest derzeit nicht.


Hab bisher noch keine Probleme fest gestellt.
Ansonsten kann man die XMegas wohl auch noch übertakten :P

von Falk B. (falk)


Lesenswert?

Siehe Multitasking.

von Karl H. (kbuchegg)


Lesenswert?

David .. schrieb:

> Hab bisher noch keine Probleme fest gestellt.
> Ansonsten kann man die XMegas wohl auch noch übertakten :P

Übertakten brauchst du nicht.
Du brauchst nur so programmieren (wenn du mal in die Situation kommst), 
dass du defensiv arbeitest. Also nicht darauf bestehen, dass eine 
bestimmte Zahl exakt rauskommen muss, sondern berücksichtigen, dass du 
eventuell auch mal einen Tick verpassen kannst. Mit den geschilderten 
Techniken ist das ja auch kein Problem.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.