NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Motorcycle tachometer

June 09, 2014
by scootergarrett
scootergarrett's Avatar

Motorcycle tachometer

So I got the idea that I could make a digital tachometer for my motorcycle (1980 kawasaki 750), for various reasons (the current mechanical one leaks oil on my pants, feedback to the choke so it tracks a set rpm when it warms up instead of revving up to 3000rpm when I'm getting ready and pissing off my neighbors). Anyways with some help from someone who has taken the signal from the ignition points and conditioned it to a usable signal. I now have a prototype circuit Circuit diagram which I don't clam to fully understand yet, I mean a nand schmitt trigger who comes up with this stuff.

and the code that counts 3 spark cycles then dose math and prints the calculated RPM to the LCD

// for NerdKits with ATmega328 //

#include "/home/garrett/Libraries_Mine/Lib.h"

#define RoundRPM 50
#define SparkSum 3

volatile uint16_t TIME;
volatile uint8_t SparkCount;

int main()
{
    double Freq;

    lcd_init();
    FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
    lcd_clear_and_home();

    // Initialize pins //
    DDRC |= (1<<PC2);               // Make PC2 an output for testing
    PORTC  |= (1<<PC2);             // Start off

    // Set up PB1 for pin change interrupts //
    DDRB &= ~(1<<PB1);
 //   PORTB |= (1<<PB1);
    PCICR = (1<<PCIE0);
    PCMSK0 = (1<<PCINT1);

    /// Working on the timming part ///
    TCCR1B = (1<<CS11) | (1<<CS10);
//    TIMSK1 = (1<<OCIE1A);

    /// Clear timer and allow interrupts ///
    TCNT1 = 0;
    sei();

    SparkCount = 0;

    while(1)
    {

        if(TIME == 0)
        {
            delay_ms(100);
            continue;
        }

        lcd_line_one();
        fprintf_P(&lcd_stream, PSTR("%06i"), TIME);

        /// Convert TIME into RPM and round RPM
        Freq = (1843200.0 / TIME / 8.0 * SparkSum);

        Freq *= 60.0;

        Freq = floor(Freq / RoundRPM + 0.5) * RoundRPM;

        if(Freq < 12000)
        {
            lcd_line_two();
            fprintf_P(&lcd_stream, PSTR("%05.0lf  RPM   "), Freq);
        }

        delay_ms(100);
    }

    return 0;
}

/// Pin change interupt ///
ISR(PCINT0_vect)
{
    if(  (PINB & (1<<PB1))   )
    {
        ++SparkCount;
    }

    if(  SparkSum == SparkCount   )
    {
        TIME = TCNT1;

        PORTC  ^= (1<<PC2);

        TCNT1 = 0;
        SparkCount = 0;
    }

    if( SparkCount >= SparkSum)
    {
        TIME = 0;
        SparkCount = 0;
    }

    return;
}

The code needs is still in prototype mode. I thought I would share where I'm now. I need to get a good case which is a ways off

Post a Reply

Please log in to post a reply.

Did you know that reading a double floating point variable with scanf requires "%lf" for "long float"? Learn more...