MV Speedometer

Een snelheidsmeter speciaal voor coilgun projectielen! Om bij het experimenteren met coilgun opstellingen de snelheid van het projectiel te bepalen moest ik voorheen met een high speed camera de frames tellen.

Nu kan ik dmv 2 lichtsluizen en een microcontroller direct de snelheid en kinetische energie meten en in één oogopslag aflezen. Veel handiger dus!

Het principe is vrij simpel: 2 lichtsluizen op een bekende afstand van elkaar opgesteld, meet het tijdverschil dat de sluizen onderbroken worden en je kan de snelheid bepalen. Om snel en eenvoudig te kunnen experimenteren met verschillende coilgunopstellingen is dit apparaat ideaal. Voor deze opstelling gebruik ik 6x93mm projectielen van allemaal exact hetzelfde gewicht(12,64 gram), kant en klaar online besteld. Met het gewicht en de snelheid is de voorwaartse kinetische energie weer te berekenen. De gebruikte u-controller is overigens de ATMEGA16.

Er wordt op de microseconde nauwkeurig gemeten, hij kan dus zeer hoge snelheden meten. Onder andere mijn luchtdruk pistool (91m/s, 330km/h) was geen probleem, natuurlijk klopt dan de berekening voor de kinetische energie niet (wat maar 2.2J is) omdat het gewicht onbekend is. De snelheid is wel correct.

Omdat de lichtsluizen verder uit elkaar moeten staan zodat er een 6mm projectiel tussendoor past, waren de orginele IR leds niet sterk genoeg. Deze leds heb ik vervangen door sterkere leds met een kleinere spreidingshoek (15 graden 950nm).

Download hier het schema + eagle board layout

Download het AVR studeo project

Download de datasheets van de ir led, lichtsluis en LCD

De 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;
}


Verder nog wat foto's:

We hebben 6 gasten en geen leden online