Three-Stage Coil Gun: Dan Pivonka and Michael Pugh
Three-Stage Coil Gun: Dan Pivonka and Michael Pugh
Abstract:
A coil gun is an electronic gun that fires a projectile by means of the magnetic field
generated when a large pulse of current is run through a coil. In this project, a projectile
was propelled by three separate coils that were precisely fired to maximize acceleration.
Sets of two DC capacitors in series drove the large pulses of current through coils
constructed from magnetic wire. Before both the second and the third coils, a pair of
laser diodes and photo sensors measured the velocity of the projectile, which was used to
compute the optimum firing time for the next coil. Two final sets of lasers and photo
sensors gauged the exit velocity, and this was shown on a seven-segment display. During
testing and demonstration, the gun successfully fired all three coils; however, due to
weak laser diodes, the system occasionally would incorrectly measure exit velocity and
not completely reset, preventing immediate, repeat firing.
The idea of electromagnetic guns has been around since roughly the 1900s, but
they have not been developed into many practical applications. They have been proposed
for applications such as delivering payloads into space; however this technology has not
yet been developed. There are two main types of electromagnetic guns: coil guns and rail
guns. Both have been shown to reach supersonic speeds, however this coil gun was not
designed to exceed velocities of a few meters per second due to safety concerns.
In this project, the team created control and velocity measurement circuitry for a
coil gun powered by DC capacitors and coils. The coil gun accelerates the projectile by
running a strong impulse of current through a coil of wire with many turns, creating a
powerful magnetic field that accelerates a metal projectile. To provide the impulse of
current, a large DC capacitor discharges very quickly through the coil of wire. In order to
optimize the acceleration of the object, the pulse of current should fire as the projectile
approaches the coil, but should last no longer than the time it takes for the object to reach
the center of the coil. To increase exit velocity, the team created three separate coils
along the barrel of the gun; however, each of these needs to be precisely activated. The
specific firing time is determined by a velocity measurement between two photo sensors.
A final velocity measurement is performed after the last coil fires, and the velocity is
displayed on a seven-segment display. The entire system has been set up to reset after
each shot and recharge the capacitors so that the time between shots is only constrained
by the capacitors’ charging time. A basic outline of the system is shown in the block
diagram in Figure 1.
The digital part of the project focuses on the control and firing circuitry for the
overall system. It starts by measuring the charge on the firing capacitors through a
voltage division circuit and the A/D converter on the PIC. Based on this measurement,
the PIC continuously provides a signal to the FPGA indicating whether the system is
ready. The FPGA then waits for the trigger signal from the user to fire the first coil. The
projectile fires through the barrel and sequentially blocks the first pair of laser diodes and
photo sensors. The FPGA receives the outputs from the photo sensors digitally and sends
an interrupt signal to the PIC as each photo sensor is blocked. The PIC starts a timer
when it receives the first interrupt from the FPGA and measures the timer on the second
interrupt, and it can then calculate the velocity of the projectile. From this velocity, the
PIC determines the exact time it needs to fire the next coil and generates an interrupt
when this time is reached. This interrupt sends a signal to the FPGA, and the FGPA then
fires the next coil in line. The fire signals from the PIC are amplified with operational
amplifiers to 15V, which is then applied to the gate of a power MOSFET to open the
channel and fire the coil.
17 V
-5-
-17 V
-17 V
Figure 3: Charging and Firing Circuitry Schematic
Digital
Output
Microcontroller Design
The PIC microcontroller has two primary functions in this design. The first is to
measure the charge of the capacitor banks and allow firing of the coils only when they are
completely charged. This is accomplished using the PIC’s built in A/D converter. As
The system has been designed with the simplest possible interrupt and fire signals
for the PIC, and much of this simplification is in the usage of the FPGA. On the FPGA,
the team employs two separate finite state machines (FSMs) that allow the photo sensor
The second FSM generates an interrupt signal for the PIC based on the inputs
from the photo sensors. The photo sensor inputs are represented by the bits photo[5:0].
The FSM remains in its initial state until both the first coil has fired and the first photo
sensor had been blocked. When both of these conditions are met, it moves into its next
state, which sends a digital interrupt to the PIC. The system then immediately moves into
its third state, in which the interrupt signal is set low. It remains in the third state until
the second photo sensor is blocked, and it then moves into a state in which the digital
interrupt is again set high. This process is repeated until the system has sent a digital
interrupt for each photo sensor. After all of the interrupts have occurred, the FSM returns
to its initial state and waits for both a trigger input from the user and for the first photo
sensor to again be blocked by the projectile. A state diagram is shown in Figure 8.
The coil gun successfully fired and there was significant improvement with each
successive stage. It was able to measure the charge on the capacitors, to take the trigger
input from the user, and to measure the velocity and precisely fire the second and third
stages. The projectile reached speeds of approximately 4m/s, which was near the
expectation. Despite many successful demonstrations, the system did experience a lack
of robustness due to the fairly dim laser diodes and problems with alignment in the photo
sensors. To remedy these problems, the team ran the laser diodes well above their rated
voltage, and with this change every part of the system did function properly most of the
time. However, the laser diodes could not be left on because of the danger of burning
them out, and turning the lasers on and off made continuous firing without reset difficult.
Special thanks to Ted Jiang for his work on the analog circuitry.
Parts List:
/* Global Variables*/
// (5 cm)Distance between set of sensors in meters/(1.6 e-5)
unsigned int sDist = 0xC35;
// (15 cm)Distance from 1st sensors to coil in meters/(1.6 e-5)
unsigned int cDist = 0x249F;
// (.01s)Time of pulse in 2nd coil in seconds/(1.6 e-6)
unsigned int pTime = 0x186A;
// Temp variable
unsigned int time;
// Counter for photo sensor interrupts
char counter = 6;
// Min value A/D converter will read when caps charged
unsigned int voltage = 0xBE00, a = 0x00;
/* Function Prototypes */
void main(void);
void isr(void);
#pragma code
void main(void)
{
TRISE = 0x00;
TRISA = 0xff;
TRISC = 0x00;
TRISD = 0x00;
PORTD = 0x00;
ADCON1 = 0x00;
ADCON0 = 0x8d;
SSPCON1 = 0x20; //enables serial port
SSPSTAT = 0xC0; //Data on rising edge
while(1)
{
// PORT E tells FPGA when capacitors are charging
// (1 = charging, 0 = system ready to fire)
PORTE = 0x01;
while (a < voltage)
{
counter = 0x06;
// Loop until counter reaches zero,
// indicating 6 photo sensor intrpts
while(counter > 0x00)
{
}
}
}
}
return;
}
endmodule
parameter s0 = 4'b1100;
parameter s1 = 4'b0001;
parameter s2 = 4'b0010;
parameter s3 = 4'b0011;
parameter s4 = 4'b0100;
parameter s5 = 4'b0101;
parameter s6 = 4'b0110;
parameter s7 = 4'b0111;
// State register
always @(posedge clk, posedge reset)
if (reset) state <= s0;
else state <= nextstate;
// Next state
always @( * )
if (state[0])
nextstate = state + 1;
else
case(state)
s0: if(p[0] & firing) nextstate = s1;
else nextstate = s0;
s2: if(p[1]) nextstate = s3;
else nextstate = s2;
s4: if(p[2]) nextstate = s5;
else nextstate = s4;
s6: if(p[3]) nextstate = s7;
else nextstate = s6;
s8: if(p[4]) nextstate = s9;
else nextstate = s8;
s10: if(p[5]) nextstate = s11;
else nextstate = s10;
default: nextstate = s0;
endcase
// Ouput logic
assign intrpt = state[0];
endmodule
// Firing Module
module fire(clk, reset, fire, ready, trigger, c);
input clk;
input reset;
input fire;
input ready;
input trigger;
output [2:0] c;
parameter s0 = 4'b0000;
parameter s1 = 4'b0001;
parameter s2 = 4'b0011;
parameter s3 = 4'b1011;
parameter s4 = 4'b0111;
parameter s5 = 4'b1111;
// State register
always @(posedge clk, posedge reset)
if (reset) state <= s0;
else state <= nextstate;
// Next state
always @( * )
case(state)
s0: if(~ready & trigger) nextstate = s1;
else nextstate = s0;
s1: if(fire) nextstate = s2;
else nextstate = s1;
s2: if(fire) nextstate = s2;
else nextstate = s3;
s3: if(fire) nextstate = s4;
else nextstate = s3;
s4: if(fire) nextstate = s4;
else nextstate = s5;
s5: if(fire) nextstate = s0;
else nextstate = s5;
default: nextstate = s0;
endcase
// Output logic
assign c = state[2:0];
endmodule
reg [16:0] m;
reg [3:0] display;
d1 = m[16];
d2 = ~m[16];
end
endmodule