PDA

View Full Version : How do others develop without delay()



taskman
07-31-2013, 06:20 AM
I never call delay() in my code and I was just wondering if what I do is normal or best practice even or if there is a better way of doing it

Here is an example


void Weapon::doFlashMuzzle(TeamEnum team) {
if (shooting || busyFlashingMuzzleLight) {
unsigned long currentMillis = millis();
if(currentMillis - flashMuzzleLightPreviousMillis > flashMuzzleLightTime) {
#ifdef DEBUG
Serial.println(F("Flash muzzle"));
#endif
flashMuzzleLightPreviousMillis = currentMillis;

switch (flashMuzzleLightProgramCounter) {
case 10:
setMuzzleLedColour(team);
flashMuzzleLightProgramCounter = flashMuzzleLightProgramCounter + 10;
break;
case 20:
busyFlashingMuzzleLight = false;
setMuzzleLedColour(NONE);
flashMuzzleLightProgramCounter = 10;
flashMuzzleLightPreviousMillis = 0;
break;
}
}
}
}


flashMuzzleLightTime = 150;
This code will only execute every 150 ms+
In the first step I set the team colour LED. After another 150 ms or so I will switch off the team colour LED again and then it just starts over again

So the way I develop all my functionality that might need a wait is to kind of have a mini program running. Is this the best way to not use delay()?


Here is another example where the code will keep on trying to do something until it works. I only developed this today and haven't tested it yet. Also didn't build in endless looping checking yet


void Commons::stopSound() {
if (busyStopping) {
switch(stopSoundProgramCounter) {
case 10:
stopSoundModule1();
stopSoundProgramCounter = stopSoundProgramCounter + 10;
break;
case 20:
byte soundModule1Busy = digitalRead(SOUND_MODULE1_BUSY);
//always go back to the first position in the stop sound mini program
stopSoundProgramCounter = 10;

//if the module isn't busy anymore after sending a stop then mark the flag to show not busy stopping anymore
if (!soundModule1Busy) {
busyStopping = false;
}

break;
}
}
}

Constantin
07-31-2013, 11:17 AM
I too try to limit delays to the minimum possible. My approach is to use flags - let's say an interrupt has fired - and the flag gets queried in the main program loop relatively often, so you get the best of both worlds, a program loop that is relatively fast, delay-free, yet responsive to changes.

Your example might be a good candidate for the programmable interval timer or PIT. Search for the discussions in this forum on how to use it. IIRC, it can be used to execute code at specific intervals.

Epyon
08-01-2013, 10:46 PM
I use hardware timer interrupts. These interrupts start and stop functions, so it functions a little bit like a fixed process scheduler.
When timing is essential, interrupts are the way to go :) .