MV Speedometer

A speedometer specially designed for coilgun projectiles! To determine the speed of coilgun projectiles while experimenting, I usually counted the frames of my high speed camera while filming the projectile.

Now using 2 optical sensors and a micro controller I can calculate the velocity and kinetic energy of the projectile and read it directly on the display. A large improvement!

The Principe is pretty simple: 2 optical sensors secured on a known distance, measure the time difference that the optical sensors are interrupted and you can calculate the speed. This device is ideal for experimenting with different coilgun coils and projectile positions etc. I ordered my projectiles online (steel rod), which all have the exact same diameter, length and weight (6.0x93.0mm, 12,64 grams). By pre programming the weight of the projectile in the micro controller and using the measured speed, the forward kinetic energy can be determined. The microcontroller I used is the ATMEGA16.

The time is measured to the microsecond (for speeds around 330km/h the time difference is about 1000 microseconds), so the speeds are pretty accurately measurable. Even my air pistol  (91m/s, 330km/h) posed no problem. Ofcource the kinetic energy calculation is wrong because of the different projectile weight, but the speed is accurate.

Because the projectile has to go between each optical sensor, they had to be separated so a 8mm tube would fit between them. Because of this the original infrared LEDs weren't strong enough and I had to replace them with stronger LEDs of the same wavelength (950nm 15 degrees angle).

Download the schematic and eagle board layout

Download the AVR studio project

Download the datasheets of the IR-LED, optical sensor and LCD

The C-code:

// Speedometer V1.0 software, designed by Daniel Eindhoven, www.megavolts.nl //
// Program used for measuring coil gun projectiles speeds and kinetic energy
// Linker options -Wl,-u,vfprintf
// Libraries libprintf_flt.a and libm.a
// Clock frequency 8.0MHz


#include avr/io.h
#include stdio.h
#include avr/interrupt.h
#include stdint.h
#include string.h
#include avr/pgmspace.h
#include util/delay.h   
#include "lcd.h"

char buffer1[17];
char buffer[17];
uint32_t teller=0;
float joule=0;
float metersec=0;
float kmhour=0;
float usec=0;

void lcd_start(void) // Function lcd init               
{
    int y=2000;
    lcd_init();
    lcd_cursor(false, false);     // Cursor off
    lcd_cls();
    while(y>0)
    {
        lcd_home();
        lcd_puts_P(PSTR("Speedometer V1.0"));
        lcd_goto(1,0);
        lcd_puts_P(PSTR("At Your Service!"));
        y--;
    }
    lcd_cls();
        lcd_home();
        lcd_puts_P(PSTR("  Scanning for  "));
        lcd_goto(1,0);
        lcd_puts_P(PSTR("  projectile... "));
}
void input_init(void){
    DDRC=0x00;        // Port C used as input
}

// Program starts here //

 int main() {
    input_init();
    lcd_start();

    while(1)
    {  
    while ((PINC&0x01)==0x01){     // First detector, waits till the first lightbeam is interrupted (poll)
    }
    while ((PINC&0x02)==0x02){     // Second detector, waits till the second lightbeam is interrupted (poll)
        teller +=7;                           // Increase counter with the number of clock cycles used for one poll
        }                                        // (This number is experimentally determined, and can change each time the program is compiled)
       
        usec = (teller/8.0);                              
// Microseconds = number of poll clock cycles divided by 8 (8MHz is the clock frequency)
        metersec = (0.09*8000000.0)/(teller);  
// Meters per second = (distance between sensors (0.009 meter) * clock frequency) / number of poll clockcycles

        kmhour = 3.6 * metersec;                      
// kM/H = 3.6 * meter per second
        joule = 0.5 * 0.01264 * metersec * metersec;   
// Kinetic energy in the projectile = 0.5 * weight of the projectile (0.01264 kg) * meter per second^2

        lcd_home();
        snprintf_P(buffer, sizeof buffer, PSTR("%4.2fm/s %4.1fkmh    "), metersec, kmhour);    // Put the calculated values on the display
        snprintf_P(buffer1, sizeof buffer1, PSTR("%4.2f J %5.1fus    "), joule, usec);        
        lcd_goto(0,0);
        lcd_puts(buffer);
        lcd_goto(1,0);
        lcd_puts(buffer1);
        teller = 0;
        _delay_ms(1000); // Wait for one second before starting all over

    }
    return 0;
}


Some pictures of the construction:

We have 4 guests and no members online