-
-
Notifications
You must be signed in to change notification settings - Fork 56
Description
Dear Michael,
Is it better to have multiple timers with one task apiece, or one timer with multiple tasks? I ask because I can't reliably set multiple tasks and cancel them individually. The code below fires phasers and photon torpedoes on a model starship. I want to "randomly" alternate firing phasers and torpedoes with each press of a button, for a total of four weapons fire: one phaser, three torpedoes (port and starboard); one torpedo, one phaser, two torpedoes; etc.
I'm using the LedFlasher library from Nick Gammon to fire the phasers, but I use your timer to tell it when to stop. (I've also tried disabling LedFlasher.) I also use your timer to repetitively increase the intensity of the torpedo effect, and again to ramp down the effect. I've tried it with one timer and assigning a task without obtaining an identifier, and just doing a blanket cancel when I want to end the task. And I've also created multiple tasks and using systemTimer.cancel(phasTask) and systemTimer.cancel(torpTask).
Whatever method I try, it only seems to work for two calls to the randomFire function. After that, the fireTorpedo function or firePhaser functions act unreliably. The randomFire function, for instance, just keeps firing torpedoes endlessly.
I've also tried instantiating the timer with Timer<2> systemTimer, but that causes a different problem — the phaser fires endlessly.
I'd appreciate any suggestions. Tomorrow I'll try creating multiple timers with one task apiece. Ultimately I have four tasks for this sketch, to control spotlights, thrusters, phasers and torpedoes. But for now, I'd just be happy to handle two tasks.
Thanks,
Jennifer Petkus
`#include <arduino-timer.h>
#include <LedFlasher.h>
const int CS_PIN = 10;
// Audio out = pin 9, declared in setup
const int WEAP_BTN = 8;
const int TORP1_PIN = 6;
const int TORP2_PIN = 5;
const int PHAS_PIN = 4;
auto systemTimer = timer_create_default();
/* Next value is a very loose approximation of the time
for a torpedo launch burst. Torpedo brightness increases
until it reaches threshold value, goes to 255, and then fades */
const int TORP_DUR = 1500/255;
const int TORP_THRESH = 64; // when torp launcher switches to full bright
int torpInt = 0; // current brightness of torp launcher
int torpCnt = 0; // port or starboard launcher
int fireCnt = 0; // how many times weapons fired
int fireLmt = 4; // max number weapons fire
bool weapFlag = 0; // prevents overlapping fire
bool warpFlag = 0; // prevents overlapping impulse/warp triggers
bool phasFlag = 0;
const int PHAS_LOW = 250;
const int PHAS_HIGH = 1500;
LedFlasher phasers(PHAS_PIN, 50, 100); // phaser flicker effect
void setup() {
pinMode(TORP1_PIN, OUTPUT);
pinMode(TORP2_PIN, OUTPUT);
pinMode(WEAP_BTN, INPUT);
phasers.begin();
}
void loop() {
systemTimer.tick();
if (digitalRead(WEAP_BTN) == HIGH && !weapFlag) { // prevents overlapping fire and firing in spacedock
weapFlag = 1;
randomFire();
}
if (phasFlag) {
digitalWrite(PHAS_PIN, HIGH);
phasers.update();
}
}
void randomFire() {
if (fireCnt < fireLmt) {
if (random(0,2) == 1) {
phasFlag = 1;
firePhaser("fire");
} else {
systemTimer.every(TORP_DUR, fireTorpedo, "ramp");
}
fireCnt++;
} else {
fireCnt = 0;
weapFlag = 0;
}
}
void fireTorpedo(const char *which) {
if (which == "ramp") { // slowly lights LED until …
if (torpInt > TORP_THRESH) { // … flash after threshold
systemTimer.cancel();
torpInt = 255;
systemTimer.every(TORP_DUR/2, fireTorpedo, "fade");
} else {
torpInt++;
}
} else if (which == "fade") {
if (torpInt <= 0) {
if (torpCnt == 0) {
systemTimer.cancel();
systemTimer.every(TORP_DUR, fireTorpedo, "ramp");
torpCnt++;
torpInt = 0;
} else if (torpCnt == 1) {
torpCnt = 0;
randomFire();
}
} else {
torpInt--;
}
}
int cur_pin = 0;
if (torpCnt == 0) { // switches between port / stbd launcher
cur_pin = TORP1_PIN;
} else if (torpCnt == 1) {
cur_pin = TORP2_PIN;
}
analogWrite(cur_pin, torpInt);
}
void firePhaser(const char *which) {
if (which == "fire") {
systemTimer.in(500, firePhaser, "stop");
} else if (which == "stop") {
systemTimer.cancel();
digitalWrite(PHAS_PIN, LOW);
phasFlag = 0;
randomFire();
}
}`