You are correct. The original electronics could be used to drive the motor. The part of the original electronics that drive the are pretty simple. The controller on that board just sends out a long enough pulse to a transistor to drive the motor at ~7.6V (the playstation controller plug has a dedicated 7.6V line for driving rumble motors). However, the pulse length sent out is not very well optimized for the design (the motor spins too long which results in a weird 1 and a half recoils per pulse) and is not adjustable. How well the recoil works is very sensitive to the pulse duration since you are essentially trying to spin a DC motor around exactly once. I also had to cut off part of the board in order to fit the aimtrak board properly, so I am not sure if the board still works.
Your 555 timer circuit definitely looks like it would work (I assume you would add a transistor or h-bridge to drive the motor). The upside is that you don't have to program a micro controller to do it. The downside is that the recoil is only adjustable when you have the case open (or if you put something to adjust the pot from the outside), whereas the micro controller method lets you adjust the recoil length from the aimtrak software. The cost difference for the circuits is pretty minimal. An ATTiny85 is trivially more expensive than a 555, and requires less total components. Using a L293d as an motor driver, the cost is about 5-6 bucks (with 4 bucks being the L293d). Personally, I think the gun is a pain to take apart and I had the parts on hand, so I opted for using a microprocessor. Overall, the more choices, the better.
Here is the code for the uC for anyone who wants it. It can be loaded to an ATTINY85 through the arduino IDE with the "arduino-tiny" add-on.
/*
P99RecoilLAPW (L293d Attiny PulseWidth)
This program receives a 5v pulse on the int pin on the uC and activates the motor pin on a L293d to spin
the recoil motor on a P99 light gun for a fixed amount of time. This version uses an ATTiny85 instead of
an arduino. Also, this version measures the width of the pulse coming in and adds that to a static wait
time so that the motor run time can be adjusted slightly adjusted directly through the Aimtrak software
(adjustment time should be between 1 - 40 ms. Even with 8MHz processor speed, the smallest pulse duration
of 1ms should be captured by the uC). Works fine with an ATTiny running at 8MHz.
Pinout (ATTiny85)
_____
(N/C) PB5 -|1 8|- VCC (5v)
(N/C) PB3 -|2 7|- PB2 (Aimtrak recoil signal input)
(P99 Recoil Enable Switch) PB4 -|3 6|- PB1 (L293d enable pin)
GND -|4___5|- PB0 (L293d input 2)
This code is in the public domain.
Foodbag
July 6, 2013
*/
#define in2Pin 0 // Drives the motor driver
#define recoilPin 2 // Reads recoil pin from Aimtrak
#define recoilPinInt 0 // Pin 2 Interrupt
#define recoilEnbSwitch 4 // Reads the enable recoil switch
#define enablePin 1 // Sets the enable pin on the L293d
unsigned long staticWaitTime = 130000; // How long the static wait time for the firing is (in microseconds)
unsigned long maximumMotorTime = 230000; // Disable motor after this long
volatile boolean readyToFire = true;
volatile boolean fireMotor = false;
volatile boolean lastEdgeRising = false; // Seems to help with to falling edges doubling motor run time
volatile unsigned long firingTime = 0; // When the rising signal from the Aimtrak Recoil pin is captured
volatile unsigned long recoilSigLen = 0; // How long the pulse is from the Aimtrak Recoil pin
void setup()
{
pinMode(enablePin, OUTPUT); // Sets the driver enable pin to output
digitalWrite(enablePin, LOW); // Sets the driver enable pin low to start (it gets enabled with one loop of program)
pinMode(in2Pin, OUTPUT); // Sets the driver pin 2 to output
digitalWrite(in2Pin, HIGH); // Sets the driver pin 2 to 5v (which is the motor break)
pinMode(recoilEnbSwitch, INPUT); // Sets the recoil enable switch pin to input
digitalWrite(recoilEnbSwitch, HIGH); // Sets the internal interrupt for the recoil enable pin
pinMode(recoilPin, INPUT); // Sets the recoil sensor pin to an input (we need to read the pin the interrupt
attachInterrupt(recoilPinInt, captureFiringSignal, CHANGE); // Sets up the interrupt for the recoil pin
}
void captureFiringSignal()
{
if (readyToFire == true)
{
if (digitalRead(recoilPin) == HIGH) // If this is the rising edge of the pulse, record pulse start time and let the motor be fired
{
firingTime = micros();
fireMotor = true;
lastEdgeRising = true;
}
else if (lastEdgeRising == true) // If this is the first falling edge, calculate pulse width. Otherwise ignore
{
recoilSigLen = (micros() - firingTime);
readyToFire = false;
fireMotor = true;
lastEdgeRising = false;
}
}
}
void loop()
{
if(fireMotor == true)
{
digitalWrite(in2Pin, LOW); // Start motor
unsigned long firingStart = micros();
while (micros() - firingStart <= staticWaitTime + recoilSigLen && micros() - firingStart <= maximumMotorTime) {} //Wait for motor to spin long enough
digitalWrite(in2Pin, HIGH); // Stop motor
fireMotor = false; // Don't let motor run till next pulse received
readyToFire = true; // Look for new pulse
}
else if (digitalRead(recoilEnbSwitch) == LOW) // If switch is turned to recoil, enable L293d to spin motor (ie enable recoil)
{
digitalWrite(enablePin, HIGH);
}
else // Otherwise, disable L293d so motor can't spin (ie disable recoil)
{
digitalWrite(enablePin, LOW);
}
}
I've attached the schematic for my circuit.