need help with tach signal

I am working on a manual shift module in my car for track days. I first off stress this project will not be for daily or on road driving of any sort. with that said I got the bulk of the functionality worked out as far as the transmission control goes and I’m at the point where I want to add some idiot proof functionality and the possibility to send serial data to my carputer for display and audible warnings based on these and other operating conditions. My issue is that I can not get any varied pulse frequency to work correctly. The operating range is 15Hz at 450RPM (jut below idle) to 255Hz at 7650RPM (just above my rev limiter) although for simplicity I’m testing it at lower frequencies because they where easier for me to code in from a second controller. Since the pulse is triggered twice per rotation from my little 4 banger due to the ignition system it employs you just take the time between pulses in micros and multiply that by 60000000 to get the RPM value. I can’t use any delay function to calculate this as that would add too much input delay for the shift paddles (its all about responsiveness and input lag reduction). All of the information I found online regarding tachometer circuits and coding does not seem to work for me at all. My goal with this post is to just get the base code to be functional in turning on an led that is set to respond to a specific RPM value after the frequency to RPM calculation and keeping it on until it goes lower then the target RPM. I can expand on that and eliminate the led and apply that RPM value to preventing downshifts at too high of an RPM this negating engine damage if I’m stupid enough to make such a mistake. I’m not quite sure how to post code here so ill just attach a txt file if that’s okay. If there is a more acceptable way I can paste in code please let me know. I apologies if this was a little long winded and if the code is hard to understand. I honestly have no idea what I’m doing in regards to this and I have little experience with this sort of thing. Thank you all so very much for your time.

sketch_may14a.ino (2.91 KB)

Since the pulse is triggered twice per rotation from my little 4 banger due to the ignition system it employs you just take the time between pulses in micros and multiply that by 60000000 to get the RPM value.

I don't think so. I would vote for dividing 60000000 by the number of microseconds between the pulses. But the formula in the code seems to be correct except that you used a constant of 6e06 instead of 6e07 as you wrote above which means your RPM are to low by a factor of 10.

What exactly was your question?

preferably post your sketch using </> -code tags like this people that are on the forum on a tablet can also view what you post (if you run into the 9000 chars limit you can use 2 posts) i think the issue is in the variables you use

time = micros() - oldtime;
  rpm = (rev / time) * 6000000;

since you declare them as signed integers

float rev = 0;
int rpm;
int oldtime = 0;
int time = micros;

(time & oldtime) , then do a float division, now your rpm may end up being negative. i would declare

uint32_t rev = 0;
uint16_t rpm;
uint32_t oldtime = 0;
uint32_t time = micros;

and then do the multiplication first, and keep the whole thing in integer (or do you think it may overflow ? that would mean more than 715 rev-ticks) so

rpm=(rev*6000000UL)/time

most important seems to make sure the sign doesn’t change by accident.

I am afraid that did not read all of your post. I started out with good intentions but got lost somewhere along the way in the wall of words.

Consider splitting your description into paragraphs to make it easier to read

Thank you all so very much for your replies and I'm sorry I have not gotten back to you sooner. My issue I'm having is that the led I'm trying to trigger either doesn't turn on or blinks at the frequency of my delay instead of staying on constantly when above the target rpm value.

Yes pylon that would be off by a factor of 10. I was trying any little tweak I could think of to make it work prior to this post and I must have overlooked that when changing it back to the original code. Which is also why the trigger rpm was only 100.

Deva_Rishi I tried the changes you mentioned but I'm still not having any different results. I'm honestly not even sure if the code creating the PWM signal is sound.

const int button = 13;
const int pulse = 2;
int buttonState = 0;
//10 = 100 90-10
//12 = 83 75-8
//14 = 71 64-7
//16 = 63 57-6
//18 = 56 51-5
//20 = 50 45-5
int new1 = 0;
int old = 0;
int rpm = 0;

void setup() {
  pinMode (button, INPUT);
  pinMode (pulse, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  buttonState = digitalRead(button);
  //NEW1 SWITCHING WITH BUTTON PRESS AND RELEASE
  {
    if (buttonState)
    {
      new1 = 1;
    } else
    {
      new1 = 0;
    }
  }
  if (new1 > old)
  {
    if (rpm == 0)
    {
      rpm = 10;
    } else    if (rpm == 10)
    {
      rpm = 12;
    } else    if (rpm == 12)
    {
      rpm = 14;
    } else    if (rpm == 14)
    {
      rpm = 16;
    } else    if (rpm == 16)
    {
      rpm = 18;
    } else    if (rpm == 18)
    {
      rpm = 20;
    }
  }
  if (rpm == 10)
  {
    delay(90);
    digitalWrite (pulse, HIGH);
    delay(10);
    digitalWrite (pulse, LOW);
  } else   if (rpm == 12)
  {
    delay(75);
    digitalWrite (pulse, HIGH);
    delay(8);
    digitalWrite (pulse, LOW);
  } else   if (rpm == 14)
  {
    delay(64);
    digitalWrite (pulse, HIGH);
    delay(7);
    digitalWrite (pulse, LOW);
  } else   if (rpm == 16)
  {
    delay(57);
    digitalWrite (pulse, HIGH);
    delay(6);
    digitalWrite (pulse, LOW);
  } else   if (rpm == 18)
  {
    delay(51);
    digitalWrite (pulse, HIGH);
    delay(5);
    digitalWrite (pulse, LOW);
  } else   if (rpm == 20)
  {
    delay(45);
    digitalWrite (pulse, HIGH);
    delay(5);
    digitalWrite (pulse, LOW);
  }
  if (new1 != old)
  {
    old = new1;
  }
}

I'm pretty sure the numbers are and conversions are correct. This is what I'm using to send a pulse from one arduino to another to make sure my code is working correctly.

Looking over that last bit of code I noticed a bit of a mistake i made in the notes around the digital writes. I labled them as "xxRPM" when it should say Hz.