Toy LED Gun

Hey Everyone,

I am working on my first Arduino project, a toy LED gun that is suppose to have a similar function as the Plasma Pistol in Halo. My current set up is hardware debounced button with a Tlc5940 chip running 4 LEDs, 2red, 1yellow, 1green. I consider the 4 LEDs to be the indicator LEDs, they show the 'charge' of the gun relative to how long the trigger is held (this is my current setup). When the trigger is released, before or after the full charge, the blast intensity out of the barrel will reflect the charge.

I don't have the barrel LEDs set up yet because I ran into some issues with getting the trigger to properly work. I originally thought I would use two interrupts, one on the rising edge (trigger pressed/held) and falling edge (trigger released). The problem occurred that I nesting interrupts is not default. Any way around this? How do I activate another set of code in the middle of the first interrupts code?

Thank you,
Paul

#include "Tlc5940.h"
unsigned long StartTime;
void setup()
{
  /* Call Tlc.init() to setup the tlc.
     You can optionally pass an initial PWM value (0 - 4095) for all channels.*/
  Tlc.init();
  attachInterrupt(0,pressed,CHANGE);
  Serial.begin(9600);
}



volatile int triggerPressed = 0 ;

void loop() {
  while(!triggerPressed) {
    Tlc.clear();
    Tlc.update();
  }
  
  //triggerPressed = 0;
  int ChargeTime[] = {500,1000,1500,2500};
  int StartTime;
   
   for (int Pin = 0; Pin <= 3; Pin++){
    StartTime = millis();
    long EndTime = StartTime + ChargeTime[Pin];
    long time = millis();
    
    while(time <= EndTime){
      if(!triggerPressed) break; 
      int Brightness = map(time-StartTime,0, ChargeTime[Pin], 0, 4095);
      Tlc.set(Pin,Brightness);
      Tlc.update();
      time = millis();
    }
    if(!triggerPressed){
      Serial.println("released");
      Tlc.clear();
      Tlc.update();
      break;
    } 
  }
  Tlc.clear();
  Tlc.update();
}

void pressed(){
  Serial.println("Im in the press function");
 triggerPressed = !triggerPressed;
 digitalWrite(12,triggerPressed); 
}

It is usual to make time variables unsigned long.
Why are you using interupts? Interupts are usually used where microsecond accuracy is needed. Human pushing of a button (trigger) is never that accurate. Look up 'state machine'.

wouldnt I run into the same problem with the state machines? can the code for the charging be changed to the firing code at any time during the charging code resulting in the charging code to stop?

What is the differences between a Finite State Machine and a State Machine? and will they allow rising and falling edge detection?

pwl4909:
wouldnt I run into the same problem with the state machines? can the code for the charging be changed to the firing code at any time during the charging code resulting in the charging code to stop?

 Case 1:If(trigger pulled) increase charge a little each time around loop()
else change state to 2  //trigger has been released
break
Case  2:Fire!
No charge left...change state to 3
break
Case 3:if (trigger pulled) change state to 1 //waits for trigger to be pulled again.
break

What is the differences between a Finite State Machine and a State Machine?

None, except one less word.

and will they allow rising and falling edge detection?

Yes, but why would you need that if you're not using interupts?

Yes, but why would you need that if you're not using interupts?

My thought process was case 1 rising edge (Trigger pushed/held)
Charging sequence

case 2 falling edge (Trigger released)
end charging sequence and relate charge to blast intensity and fire.

pwl4909:
wouldn't I run into the same problem with the state machines? can the code for the charging be changed to the firing code at any time during the charging code resulting in the charging code to stop?

That is precisely what proper coding - which is what state machines, or coding in that fashion - is for.

pwl4909:
will they allow rising and falling edge detection?

"Edge detection" is coding to determine when the state of your button - on each pass through the loop - is not the same as the last time through the loop. You do this by making a "memo" - using a variable - of what the button was previously, and looking to see when it has changed.

Hardware debouncing is - literally - a waste of time and money. You have a processor that executes literally millions of operations per second, compared to which the time it takes you to press - or release - the button is ridiculously long. It is tedious to perform debouncing in interrupt code but dead easy by "polling".