Better way to arrange timed and continous events?

For now, I came to working code below.
Pros:

  • no delay()
  • all event frequencies are associated in relatively close places (crontab[] for frequencies and lastops[] to keep track of them)
    Cons:
  • handlers are scattered in timeHandler() and disconnected from events. Actually, there's no events, only side function to control different arrays
  • no built-in function to report actual array length
  • overall code is hard to understand and very hard to embed, because initiations and functions placed in different parts of document
  • biggest one: if a handler starts child process, it has to be embedded in same crontab[], linearizing tree, and this breaks my brain.
#define MIN 8
double crontab[] = {
  1000000/5, //playing note...
  1000000/1, //shifting frequency each 1 sec
};
double lastops[sizeof(crontab)/4];

void setup() {
  Serial.begin(9600);
}

void loop() {
  timer();
}

void timer(){
  for(int i=0 ; i < sizeof(crontab)/4; i++){
    if(micros() - lastops[i] > crontab[i]){
      lastops[i] = micros();
      timeHandler(i);
    }
  }
}

void timeHandler(int i){
  switch(i) {
    case 0:
      handler0();
    break;
    case 1:
      handler1();
    break;
    } 
}

void handler0(){
  Serial.println("flip...");
}

void handler1(){
 crontab[0] -= crontab[0]/20;
 if(crontab[0] < MIN){crontab[0] = MIN;}
 Serial.println("freq shifted");
}

And here is how I imagine it could be - simple and readable:

void setup() {
  Serial.begin(9600);
  crontab = { //multihash
	note {
		interval : 1000000 / 5
		handler : function (){
			Serial.println("flip...");
		}
	}
	shifter {
		interval : 1000000 / 5
		handler : function (){
			crontab[0] -= crontab[0]/20;
			MIN = 8;
			if(crontab[0] < MIN){crontab[0] = MIN;}
			Serial.println("freq shifted");
		}
	}
  }
}

void loop() {
  timer();
}

void timer(){
  for(i in crontab){ //or for(i = 0; i < crontab.LENGTH(); i++)
      if(micros() - crontab.i.last > crontab.i.interval){ //last is not defined, and it's OK!
      crontab.i.interval = micros();
      crontab.i.handler();
    }
  }
}

Will this help?

Likely, no. Your class adds very good replacement for delay representation, but events are still have to be handled inside sketch.

biggest one: if a handler starts child process, it has to be embedded in same crontab[], linearizing tree, and this breaks my brain.

Well, luckily for you, the Arduino can only run one process, so this will never happen.

father_gorry:

[quote author=Nick Gammon link=topic=72690.msg545038#msg545038 date=1316341993]
Will this help?
Gammon Forum : Electronics : Microprocessors : Elapsed time class

Likely, no. Your class adds very good replacement for delay representation, but events are still have to be handled inside sketch.

[/quote]

I'm not sure I understand your response. Where else would the events be handled rather than inside the sketch?

You could make a table of the timer objects, test each one inside loop, and do one when its time is up. Isn't that the essence of timed events?

Sorry. I meant that this way and approach somehow results in one-level list of timer variables, and in order to make understandable clear multi-leveled code, I have to hide that list or table as far as possible.
In other words, one must program, thinking of "each-200us-timed events" instead of "that things happen again in 200us".

Anyway, both mine and yours ways failed to me, because I needed exact timing (to play tone with stepper motor). The real intervals were noised: 230, 250, 269, 203 us etc.

father_gorry:
Anyway, both mine and yours ways failed to me, because I needed exact timing (to play tone with stepper motor). The real intervals were noised: 230, 250, 269, 203 us etc.

if you need exact timing, you're going to have to use one of the hardware timers as opposed to a software implementation.

father_gorry:
... in order to make understandable clear multi-leveled code, I have to hide that list or table as far as possible.
... I needed exact timing (to play tone with stepper motor).

Understandable clear code, and exact timings may be mutually exclusive.

Small, fast, readable, you get to choose any two only. :wink: