Простейшая дзынькалка. Команды запуска и останова таймера надо поместить в любое удобное меню.

Интерфейс текстовый - надо написать длительность периода в секундах, выделить и выбрать пункт "Запустить таймер".
Можно и коммандером:^Q"SternTimer2.Start(5)"

## Код:
```
MODULE SternTimer2;

   IMPORT Dialog, Log := StdLog, Strings, Services, TextControllers, TextModels;

   TYPE
      Action = POINTER TO RECORD (Services.Action)
         period: INTEGER
      END;

   VAR
      a: Action;

   PROCEDURE (a: Action) Do;
   BEGIN
      Dialog.Beep;
      Services.DoLater(a, Services.Ticks()+a.period*Services.resolution);
   END Do;

   PROCEDURE Start (period: INTEGER);
   BEGIN
      ASSERT(period # 0, 20);
      Services.RemoveAction(a);
      NEW(a); a.period := period;
      Services.DoLater(a, Services.Ticks()+period*Services.resolution);
   END Start;

   PROCEDURE ReadPeriod*;
      VAR c: TextControllers.Controller; r: TextModels.Reader; period, res, i, beg, end: INTEGER; ch: CHAR; s: ARRAY 50 OF CHAR;
   BEGIN
      c := TextControllers.Focus();
      IF c # NIL THEN
         c.GetSelection(beg, end);
         IF end > beg THEN
            r := c.text.NewReader(NIL); r.SetPos(beg); s := ''; i := 0;
            r.ReadChar(ch);
            WHILE (r.Pos() <= end) & ~r.eot DO
               s[i] := ch; INC(i);
               r.ReadChar(ch);
            END;
            s[i] := 0X;
            IF s # '' THEN
               Strings.StringToInt(s, period, res);
               IF res = 0 THEN Start(period) END
            END
         END
      END;
   END ReadPeriod;

   PROCEDURE Stop*;
   BEGIN
      Services.RemoveAction(a); a := NIL
   END Stop;

   PROCEDURE StopGuard* (VAR par: Dialog.Par);
   BEGIN
      par.disabled := a = NIL
   END StopGuard;

END SternTimer2.

Меню

   "Запустить таймер"   ""   "SternTimer2.ReadPeriod"   "TextCmds.SelectionGuard"
   "Остановить таймер"   ""   "SternTimer2.Stop"   "SternTimer2.StopGuard"
```
