RPM based shift light

Hello,
I am having some trouble getting my shift light code working. I am able to get the shift light working using IF statements only, it will follow both up and down with a function generator, however all the LEDs are pulsing on and off, I suspect this is due to the timing of the loop re-checking the IF statements over and over again?

I found a similar project that was done several years and the code there uses FOR loops in addition to IF statements, I ran that code straight up and everything works great, however when I change the frequency ranges to work for my vehicle, I cannot get the lights to follow the freq output back down and also all the green LEDs come on at once instead of progressively.

[https://www.reddit.com/r/arduino/comments/515vsd/my_progressive_shift_light_because_racecar/[url/]

Below is my version of the working code from the above link, could someone review and tell me if they see anything obvious?

#include <Adafruit_NeoPixel.h>

#ifdef __AVR__
  #include <avr/power.h>
#endif

#define PIN            6  //LED Data Pin
#define NUMPIXELS      9  //number of leds connected
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int i;
int rpm;
float ighigh,iglow;
unsigned long igfreq, igcal1, igcal2;
int cnt;

void setup() {
  // put your setup code here, to run once:
  pixels.begin();  // This initializes the NeoPixel library.
  Serial.begin(115200);  // connect to the serial port

  Serial.println("Frequency Counter");  //this is just for debugging so we can see what freq the controller is reading
  
  rpm = igfreq * 30
}

void loop() {
  //loop code, runs every cycle
  //measure period of tach signal
  ighigh = pulseIn(5,HIGH);
  iglow = pulseIn(5,LOW);
  
  igcal1=1000/((ighigh/1000)+(iglow/1000));
  
  //do it again
  ighigh = pulseIn(5,HIGH);
  iglow = pulseIn(5,LOW);
  
  igcal2=1000/((ighigh/1000)+(iglow/1000));
  
  //to filter out some noise, we only consider our measurement valid if they are similar in value, we accept the average
  if((igcal1-igcal2)<8)igfreq = (igcal1+igcal2)/2;
  
  //displaying measured freq through serial for debugging 
  Serial.print(cnt++);
  Serial.print("  Freq: ");
  Serial.print(igfreq);
  Serial.print("  RPM:  ");
  Serial.println(rpm);
  delay(1);

  //Progressive lights from 7000-9000:  4 green lights, 2 yellow, & 3 red
  // @9100 all flashing red 
  if(rpm>=7000 && rpm<9100){
    for( i=0;(i<NUMPIXELS)&&(i<=((igfreq-100)/16));i++){
      if(i <4){
        pixels.setPixelColor(i, pixels.Color(0,80,0));  //Green 
        pixels.show();
      }
      if(rpm>8000){
        pixels.setPixelColor(4, pixels.Color(50,50,0));  //Yellow 
        pixels.show();
      }
      if(rpm>8250){
        pixels.setPixelColor(5, pixels.Color(50,50,0));  //Yellow
        pixels.show();
      }
      if(rpm>8500){
        pixels.setPixelColor(6, pixels.Color(100,0,0));  //Red
        pixels.show();
      }
      if(rpm>8750){
        pixels.setPixelColor(7, pixels.Color(100,0,0));  //Red
        pixels.show();
      } 
      if(rpm>9000){
        pixels.setPixelColor(8, pixels.Color(100,0,0));  //Red 
        pixels.show();
      } 	  
    }
    for(i;(i<NUMPIXELS);i++){
      pixels.setPixelColor(i, pixels.Color(0,0,0));  //Off
      pixels.show();
    }
  }
  else if(rpm>=9100){
    for( i=0;(i<NUMPIXELS);i++){
      pixels.setPixelColor(i, pixels.Color(100,0,0));  //Red
      pixels.show();
      }
      delay(20);
      for( i=0;(i<NUMPIXELS);i++){
      pixels.setPixelColor(i, pixels.Color(0,0,0));  //Off
      pixels.show();
      }
      delay(20);
  }
  else for(i=0;(i<NUMPIXELS);i++){
      pixels.setPixelColor(i, pixels.Color(0,0,0));  //Off
      pixels.show();
  }
}

](Reddit - Dive into anything)

when I change the frequency ranges to work for my vehicle ... all the green LEDs come on at once instead of progressively.

Did you adjust this line?

for( i=0;(i<NUMPIXELS)&&(i<=((igfreq-100)/16));i++){

What was the original frequency range the code was written for, what is the range for your vehicle, and what/how did you change the code.

Other general comments: too many pixel.show(). This will cause flickering. Ideally you only want one in loop().

Did you adjust this line?

for( i=0;(i<NUMPIXELS)&&(i<=((igfreq-100)/16));i++){

I did not, that is how it was in the base code. I hyperlinked the original, I made quiet a few changes. The original code was using a range of 100-216 hz, for my vehicle it needs to be 233-300 hz.

Other general comments: too many pixel.show(). This will cause flickering. Ideally you only want one in loop().

where would I put it pixel.show?

I might be wide of the mark here .. it may or may not help ..but ... I think I would work in the time units throughout and not convert into rpm - those division calculations must take a while ?
I’d also see if I could get rid of using floats too ( that may not be possible ).
“Case”
Might also be worth a look to set the switch points .

hammy:
I might be wide of the mark here .. it may or may not help ..but ... I think I would work in the time units throughout and not convert into rpm - those division calculations must take a while ?
I’d also see if I could get rid of using floats too ( that may not be possible ).
“Case”
Might also be worth a look to set the switch points .

I tired it both ways, no change in the outcome.

What do you mean by switch points?

Sorry not very clear ..
I meant use the “case” statement to determine which lights are turned on when certain rpm point us passed rather than’ “if” rpm is bigger than whatever’

Rufio1013:
I did not, that is how it was in the base code.

Let me be less subtle. You need to change that line.