Bar Graph LED tachometer, Help needed.

Okay so I found the Bar Graph LED breakout kit on sparkfun(https://www.sparkfun.com/products/10936) and I was wanting to use it as a tachometer for a racecar my college makes for Formula SAE. I know the ECU outputs a tachometer signal that you define to a degree, you tell how many pulses per rpm that the signal sends out, which I set to 1 pulse per rpm. The issue is the signal sent out, it is a square wave with a duty cycle of 30% for the wave at battery voltage(can vary usually at 14.3v - 14.4v if the battery is charged by the stater when the engine is running), while 100% duty cycle is wave plus space before next wave. This is how it was described in the manual, I emailed the company and was sent a small sketch of what they were meaning.

Is there a way to reduce the voltage to a usable voltage for an UNO? Would a voltage regulator work? or would it create issues with the wave? Also I would like for each LED to represent a range of rpm(since not all ten on each bar is usable, I would have 24 steps if I count correctly, seeing as the last 4 on each bar are coupled) of about 438rpm per LED(10,500 rpm redline divided by 24 LED’s). Now when it gets to about 10,000 rpm I would like the LED’s that are currently on to start flashing to alert the driver that they need to shift. I have seen a small snippet of code to allow the LED’s to blink but I am not sure if it will work for my purpose, anyways here it is:

for (int i = 0; i <= 8; i++) {
    digitalWrite(latchPin, LOW); 
    shiftOut(dataPin, clockPin,  255); 
    digitalWrite(latchPin, HIGH);
    delay(150);
    digitalWrite(latchPin, LOW); 
    shiftOut(dataPin, clockPin,  0); 
    digitalWrite(latchPin, HIGH);
    delay(150);
  }

^^^^^put into the code format, Thanks to Mee_n_Mac, I hadn’t realized that the code button was for that.

Not sure if there is a way to just make all flash while at or above that rpm, or lower the voltage of the signal so that an arduino can use it without frying. Thank you for any help given!

Is there a way to reduce the voltage to a usable voltage for an UNO?

What you want is a level shifter.

A simple way to reduce that voltage is with a resistor and zener diode. The question is how much current can you draw from the tachometer pin w/o screwing it up. If the answer is at least a few mA then the zener circuit should work.

http://www.electronics-radio.com/articl … ircuit.gif

Chose a 4.0 - 5.1V zener. Set the resistor so that with the highest voltage, no more than perhaps 5 mA is flowing (~2k resistor).

Read more here;

http://www.evilmadscientist.com/2012/ba … er-diodes/

As for this;

The issue is the signal sent out, it is a square wave with a duty cycle of 30% for the wave at battery voltage(can vary usually at 14.3v - 14.4v if the battery is charged by the stater when the engine is running), while 100% duty cycle is wave plus space before next wave.

Huh ?

http://en.wikipedia.org/wiki/Duty_cycle

For anything less than 100% DC, measure with …

http://arduino.cc/en/Reference/pulseIn

As for flashing … too bad the design of that board did not bring out the enable signal. Simply pulsing that line would have turned all the LEDs off or allowed whatever was programmed into them to be on. So you have 2 options; use the clear line to erase all the data sent to the LEDs and so turn them off and then write the data when you want the LEDs to be on, thereby accomplishing a flash. Or use just software and write “all off” values to the LEDs (that might be all 0’s or all 1’s, I haven’t checked), wait some time and then write on values to the LEDs that are supposed to be on, thereby getting a flash. Your snippet sends all off (?or on?) followed by all on (?or off?) commands with 150 msec between them, thus getting a flash … if all you had were 8 LEDs connected to a shift register. So it’s basically doing the 2’nd option.

http://arduino.cc/en/Reference/shiftOut

http://arduino.cc/en/Tutorial/ShiftOut

ps - code tags

(click on to open)

codlink:

Is there a way to reduce the voltage to a usable voltage for an UNO?

What you want is a level shifter.

Well the only problem I have with that is finding one, most that I can find are for lower voltage, max 5v. Do you know where I can get one that converts from 14.4v - 12v down to a steady 5v, or at least steady enough for a MEGA to understand and use the input data, up to 200hz(higher than it should be but that is max if something went way wrong).

Would a voltage regulator work? Or would it interfere with the hertz of the input? From what I can tell, isn’t a level shifter just a voltage regulator that has a very low drop-out voltage?

^^^^written before Mee_n_Mac posted, hit submit right after apparently :stuck_out_tongue: (Mee_n_Mac you are AWESOME, you have helped me so much in the past couple days, Thank you so much!!!)

Huh ?

http://en.wikipedia.org/wiki/Duty_cycle

For anything less than 100% DC, measure with …

http://arduino.cc/en/Reference/pulseIn

That is what the manual for the ECU said…I didn’t understand it that is why the guy from the company sent that sketch to me, I think they meant period rather than duty cycle, because 30% is the duty cycle, 100% is the period. But don’t shot the messenger, I had no say in writing that manual.

For the pulseIn() command, how would I tell the rpm? I understand that it gives the time of the pulse of on, but how do I know what rpm that is? Would I need to contact the ECU company or is there a way I can find that out?

For that diode method, if I were to need a higher amperage to draw to run to the pin on the arduino how would I do so? Should the arduino even pull that much amperage in the first place seeing as it is just looking at the data. And I am assuming that this data would go into a Digital input, if I am not mistaken? (Will update more in the morning, if I make no sense, it took me over 40 minutes to just write this because I kept forgetting what I was trying to say…sleep is calling my name)

BlindAssassin111:
For the pulseIn() command, how would I tell the rpm? I understand that it gives the time of the pulse of on, but how do I know what rpm that is? Would I need to contact the ECU company or is there a way I can find that out?

I can guess that 1 of 2 things happen to that drawing as the RPM changes.
  1. The period remains the same but the DC changes and goes from some low % to some high % as the RPMs increase. This would be useful in driving an old analog tach gauge and so I can envision it being what happens even today. It’s called PWM. In this case you’d measure the “on” pulsewidth using the Pulse_In function. The width measured should be proportional to the RPM.

http://arduino.cc/en/Tutorial/PWM

  1. The DC remains the same but the frequency/period of the signal changes. In this case you’d measure the “off” time of the signal, as it would get shorter w/higher RPMs. Again you could map pulsewidth (PW) into RPMs.

In any case you can measure what happens by doing both, reving the engine and deciding which is correct. Or get an oscilloscope and look at the signal as you rev the engine. FWIW I’m 99% certain some forum someplace has the answer to what really happens.

BlindAssassin111:
For that diode method, if I were to need a higher amperage to draw to run to the pin on the arduino how would I do so? Should the arduino even pull that much amperage in the first place seeing as it is just looking at the data. And I am assuming that this data would go into a Digital input, if I am not mistaken? (Will update more in the morning, if I make no sense, it took me over 40 minutes to just write this because I kept forgetting what I was trying to say…sleep is calling my name)

Yes, the zener is tied to a digital input which will "see" a ~5v pulse instead of a 12-15v one. The DC will remain unchanged. The input pin is a much higher resistance than the resistor shown and so can (for practical purposes be neglected), that is the input draws very little current. You do need a couple of mA to flow through the zener though, to keep it reverse biased (read the EMS link). If the ECU tach pin can't supply even a few mA then there are other buffering, level shifting circuits to be used ... the zener was just the simplest.
  1. The DC remains the same but the frequency/period of the signal changes. In this case you’d measure the “off” time of the signal, as it would get shorter w/higher RPMs. Again you could map pulsewidth (PW) into RPMs.

In any case you can measure what happens by doing both, revving the engine and deciding which is correct. Or get an oscilloscope and look at the signal as you rev the engine. FWIW I’m 99% certain some forum someplace has the answer to what really happens.

This is what really happens, it just increases the frequency, constant 30% DC, as rpm’s increase. I found a 5v zener on mouser(http://www.mouser.com/ProductDetail/NXP … 6Qmlu3c%3d) but I can’t seem to figure out the reverse current needed to function. I did see that there is a zener on sparkfun(https://www.sparkfun.com/products/10301) but I can’t tell if that would be better or not. Any ideas which would be a better choice in my case? I am assuming the tach. signal can supply atleast 20mA, because I have seen some guages that draw that much and I have seen some draw 8mA and in the manual it says “can power original or aftermarket tachometers”, so I assume that it can vary to about 20mA.

Now you say

The input pin is a much higher resistance than the resistor shown and so can (for practical purposes be neglected), that is the input draws very little current.

but What are you meaning by this? That I don’t need to use a resistor before the zener diode? or that the pin has a negligible resistance for what I am doing? From what I understand the resistor is just there to induce a current to make the zener flow in reverse, and the resistance is just a value that can induce it, there is no required min or max?

Typically a few mA is right. If you look at the datasheet you’ll see they spec the zener voltage (and other things) w/a current of 5 mA. So that’s a good value to aim for. (Hmmmm, that number looks familiar … :mrgreen: )

http://www.mouser.com/ds/2/302/NZX_SER-42904.pdf

As for the zener circuit, a more complete description would include the input resistance of the Arduino IO pin and would look like;

To look at the above circuit means some current would flow into Rarduino instead of the Zener, and in fact, that’s what happens. But because Rarduino is such a high value and the Zener current doesn’t need to be that exact, you can neglect the small tiny itty bitty current that flows into the Arduino (in this instance) and model the circuit as shown before.

So if V1 (tach output) can be 15v and Vz = 5v and the voltage across the resistor (R) is 10v. If you want 5 mA then R = 2000 ohms. Lower voltages reduce the current but so long as it’s 2 mA or so, the Zener will be happy.

As the frequency of the pulses increase the time between them decreases. There are multiple ways to measure that interval. I mentioned one. There are others. Your choice. The (real) Arduino forum is full of answers to questions you never even imagined. :mrgreen:

http://forum.arduino.cc/index.php?topic=64219.15

Mee_n_Mac:
Typically a few mA is right. If you look at the datasheet you’ll see they spec the zener voltage (and other things) w/a current of 5 mA. So that’s a good value to aim for. (Hmmmm, that number looks familiar … :mrgreen: )

http://www.mouser.com/ds/2/302/NZX_SER-42904.pdf

As for the zener circuit, a more complete description would include the input resistance of the Arduino IO pin and would look like;
[attachment=0]zener-circuit.gif[/attachment]
To look at the above circuit means some current would flow into Rarduino instead of the Zener, and in fact, that’s what happens. But because Rarduino is such a high value and the Zener current doesn’t need to be that exact, you can neglect the small tiny itty bitty current that flows into the Arduino (in this instance) and model the circuit as shown before.

So if V1 (tach output) can be 15v and Vz = 5v and the voltage across the resistor (R) is 10v. If you want 5 mA then R = 2000 ohms. Lower voltages reduce the current but so long as it’s 2 mA or so, the Zener will be happy.

As the frequency of the pulses increase the time between them decreases. There are multiple ways to measure that interval. I mentioned one. There are others. Your choice. The (real) Arduino forum is full of answers to questions you never even imagined. :mrgreen:

http://forum.arduino.cc/index.php?topic=64219.15

Would this code work perfectly? Only thing I would need to add is the code for the bar graph LED’s correct? Also is Serial.println() similar to System.out.println() in java, where the Serial is the output and the command follows?

Code:

// Frequency counter sketch, for measuring frequencies low enough to execute an interrupt for each cycle
// Connect the frequency source to the INT0 pin (digital pin 2 on an Arduino Uno)

volatile unsigned long firstPulseTime;
volatile unsigned long lastPulseTime;
volatile unsigned long numPulses;

void isr()
{
  unsigned long now = micros();
  if (numPulses == 1)
  {
    firstPulseTime = now;
  }
  else
  {
    lastPulseTime = now;
  }
  ++numPulses;
}

void setup()
{
  Serial.begin(19200);    // this is here so that we can print the result
  pinMode(3, OUTPUT);     // put a PWM signal on pin 3, then we can connect pin 3 to pin 2 to test the counter
  analogWrite(3, 128);
}

// Measure the frequency over the specified sample time in milliseconds, returning the frequency in Hz
float readFrequency(unsigned int sampleTime)
{
  numPulses = 0;                      // prime the system to start a new reading
  attachInterrupt(0, isr, RISING);    // enable the interrupt
  delay(sampleTime);
  detachInterrupt(0);
  return (numPulses < 3) ? 0 : (1000000.0 * (float)(numPulses - 2))/(float)(lastPulseTime - firstPulseTime);
}

void loop()
{
  float freq = readFrequency(1000);
  Serial.println(freq);
  delay(1000);
}

Also just realized I said I was going to use a MEGA for this project, when in fact this project gets an UNO, while the other one gets a MEGA.

It looks like that code should work. What it’s doing is counting the pulses as they come in and then, once very second, computing the RPM based on the count. You might need to change a divisor but the basic concept is good.

I have worked the code a little bit but I was wondering if there would be a better solution for making the LED’s flash when above a certain frequency/rpm?

// Connect the frequency source to the INT0 pin (digital pin 2 on an Arduino Uno)
#include <SFEbarGraph.h>
#include <SPI.h>

SFEbarGraph BarGraph;

volatile unsigned long firstPulseTime;
volatile unsigned long lastPulseTime;
volatile unsigned long numPulses;

void isr()
{
  unsigned long now = micros();
  if (numPulses == 1)
  {
    firstPulseTime = now;
  }
  else
  {
    lastPulseTime = now;
  }
  ++numPulses;
}

void setup()
{
  BarGraph.begin(1, 2);// begin(number of bar graph kits, pin connected to)
}

// Measure the frequency over the specified sample time in milliseconds, returning the frequency in Hz
float readFrequency(unsigned int sampleTime)
{
  numPulses = 0;                      // prime the system to start a new reading
  attachInterrupt(0, isr, RISING);    // enable the interrupt
  delay(sampleTime);
  detachInterrupt(0);
  return ( numPulses < 3) ? 0 : ( 1000000.0 * (float)(numPulses - 2) ) / (float)( lastPulseTime - firstPulseTime );
}

void loop()
{
  float freq = readFrequency(140);
  
  unsigned char LED;
  //unsigned char LEDs;
  unsigned char numLEDs;
  
  if (freq >= 160)
  {
      for ( int iter = 0; iter < 5; iter++ )
      {
          BarGraph.barGraph(30, 0);
          delay(75);
          BarGraph.barGraph(0, 0);
      }
  }
  
  else
  {      
      numLEDs = round(freq / 6.111);
      
      BarGraph.barGraph(numLEDs, 0);
      /*for ( LEDs = 0; LEDs < numLEDs; LEDs++ ) // Not sure if this method is better, will have to test if the BarGraph.barGraph( numLEDs, 0 ) works or not.
      {
          BarGraph.paint(LED, HIGH);
      }
      BarGraph.send();*/
  }
}

So far what I am doing is just an if statement to see if the tach. signal is equal to or above a set frequency, and if so it will flash all LED’s 5 times. But something I am not sure about is how to make it more effective, meaning how would I make it flash while above and not stop until back below? I don’t understand the isr() method at all, I know it has something to do with the interrupt for the frequency calculation but does it operate how I would think, as in does it actually use an interrupt if there is a signal coming in that is different? If so would there be a way to make an interrupt for the flashing?

BlindAssassin111:
I don’t understand the isr() method at all, I know it has something to do with the interrupt for the frequency calculation but does it operate how I would think, as in does it actually use an interrupt if there is a signal coming in that is different? If so would there be a way to make an interrupt for the flashing?

The Interrupt Service Routine runs whenever the IO pin associated w/interrupt 0 detects a rising edge, aka a pulse from the tachometer. This line in the code sets that up while the isr() code is what runs.

attachInterrupt(0, isr, RISING); // enable the interrupt

The isr() function records the “time” of the 1’st pulse and the last pulse by using the micros() function. It also counts the number of times it has been run, = to the number of pulses. Then the loop() code uses those numbers to compute the RPM about once per second.

http://arduino.cc/en/Reference/Micros

As to better blinking … I’m not sure what the best way is. Surely you could use/set another hardware timer and have that trigger an interrupt and a different ISR. That ISR could turn the LEDs alternately off and on. But there may be an easier way (see links below). What would you consider to be a good “blink” ? How long should the LEDs be off ? on ?? Do you find that updating the RPM calculation, and thus the LEDs, once per second to be adequate ? Figure out what makes a good visual display and then “we” can code for that.

http://playground.arduino.cc/Code/SimpleTimer

http://playground.arduino.cc/Code/Timer

http://playground.arduino.cc/Code/Timer1

FWIW - I’m not sure that this is correct given the number of pulses is incremented only after the “first pulse” if statement in the isr().

numPulses = 0;

Perhaps the isr() code should be ???

void isr()
{
  unsigned long now = micros();
  ++numPulses;         //moved this to top of code
  if (numPulses == 1)
  {
    firstPulseTime = now;
  }
  else
  {
    lastPulseTime = now;
  }
}

Then again I’m unsure why it’s 2 (pulses subtracted) in this calculation.

(1000000.0 * (float)(numPulses - 2))/(float)(lastPulseTime - firstPulseTime)

How many pulses does the tach output in 1 revolution ?

I don’t know how long I want them to be on or off, what would be a noticeable, fast flash, would 35 ms be fast enough? I have already modified the amount of time it will take per “cycle” of the frequency converter, I changed it to happen every 140 ms, can be increased if need be, and that is more than enough to get 2 pulses at the lowest rpm I would like to read, about 900 rpm. I will look into those links, Thank you again for all of your help :D.

The Tachometer will output 1 pulse per revolution of the crankshaft. so number of pulses = rpm and the frequency = rpm/60. Easy conversions I used in the code. I have no idea why the original coder for the frequency part subtracted 2 from the numPulses in that line of code, or why it is set to 0 at first.

BlindAssassin111:
I changed it to happen every 140 ms, can be increased if need be, and that is more than enough to get 2 pulses at the lowest rpm I would like to read, about 900 rpm. I will look into those links, Thank you again for all of your help :D.

The Tachometer will output 1 pulse per revolution of the crankshaft. so number of pulses = rpm and the frequency = rpm/60. Easy conversions I used in the code. I have no idea why the original coder for the frequency part subtracted 2 from the numPulses in that line of code, or why it is set to 0 at first.

Yup, I was looking at the code you posted and then realized that you had only 20 ms of measurement time (ie - when the ISR was running) and that's too short. Even 140 msec seems too short to get good measurements. However increasing the time in the *readFrequency()* function means, [u]as it's presently written[/u], that the code isn't doing anything else and so the bargraph is left at it's last setting during that time... no blinking allowed. So I will show you a better way to time and schedule certain events that will allow that measurement time to be whatever whatever is needed (250 ms, 500 ms, 1 sec ???) for accuracy and appearance and will also allow the main *loop()* to run fast ... thusly making the blinking simple.

What you need to do is come up with some test code that allows you to play with the blinking, LEDs time off and LEDs time on, and then by experimenting with the values see what looks good. You might as well simulate the tach reving up and down, as quickly as it might happen in real life, and see what min and max times between bargraph updates looks good. That will play into determining what a good measurement time is, perhaps a tradeoff between looks and accuracy.

As far as the prior code goes … it might have been that posters tach output a pulse per sparkplug firing and so a 6 cylinder fires 3 per revolution and so you got 3 pulses/rev and … I dunno. All I do know is that the readFrequency() function outputs a true frequency which, when multiplied by 60, is turned into RPM. You have 30 LEDs in your bargraph ? What’s the max RPM you care to display ? The top/last LED coming on at (say) 9000 RPM would mean 300 RPM/LED. 12,000 RPM would mean 400/LED. What do you have, an F1 car ? :mrgreen:

There are 2 ways you could improve the code and make the flashing you want happen easily. Both mean getting rid of the delay() in the readFrequency() function and thereby allowing the loop() to run.

First you could use millis() function to schedule when to run the frequency calculation. Let’s say on the 1’st running of the loop() code, it enabled to ISR to run. Then the code called the millis() function and “memorized the time” (store the millis() result in a variable). Then on every subsequent running of the loop code an if() statement asked “is it X msecs later that the memorized time ?” If it’s not then the if() code doesn’t run and the loop() just continues to … well … loop. When the if() question is true then the ISR is disabled and the results from it, number of pulses and timing of first and last are obtained via the new readFrequency() function. The frequency and RPM are computed and then the bargraph updated. Lastly reset the ISR variables to start counting, enable the ISR and “memorize the time” again. As a result the frequency and RPM are computed and bargraph updated every X msec, give or take. Since the rest of the loop() code, when not doing the above, is next to nothing in length, it runs in less that 100 usec (my guess). So the timing of when the updates happen should be good to almost a msec. Now I want you to go and revisit the “SimpleTimer” link I posted above. It basically does, and hides, the above. You may find it easier to code using that library.

So now that the loop() runs very fast, except for the 1 time every X msecs, you can also use the same timing concept to test if the last computed RPM is >= some threshold and if so, then blink the LEDs. You can schedule that in the same manner as the above. When the LEDs are on, schedule a “blink update” some BlinkOn_msecs in the future. When that happens, turns the LEDs off and schedule the next “blink update” some BlinkOff_msecs in the future. Keep track of the LEDs being on or off via a boolean variable, LEDs_On. Toggle it true and false with the blink update code. There’s your blinking !

The ISR code would be the changed version I suggested before.

void isr()
{
  unsigned long now = micros();
  ++numPulses;
  if (numPulses == 1)
  {
    firstPulseTime = now;
  }
  else
  {
    lastPulseTime = now;
  }
}

The readFrequency() function changes. Since it’s now scheduled to run there’s no delay and no “sample time” argument. Moreover I’ve updated it to be what I think is correct for calculations and returning RPM instead of frequency.

float readFrequency()
{
  detachInterrupt(0);
  //Need at least 2 pulses, a first and a last to define 1 period of a revolution
  //The difference in pulsetimes, last - first, is some integer number of periods
  //The number of periods is the number of pulses - 1
  //The frequency is the number of periods divided by the time
  //Multiply by 1000000 to convert usecs to sec and by 60 to get RPM 
  //Return a 0 if the ISR hasn't seen 2 pulses, = 1 complete period
  return ( numPulses < 2) ? 0 : ( 60.0 * 1000000.0 * (float)(numPulses - 1) ) / (float)( lastPulseTime - firstPulseTime );
}

Be sure to zero out the numPulses and do the attachInterrupt(0, isr, RISING); after calling the above function.

I’ll let you digest that for now. The 2’nd method is slightly different in that instead of updating the RPM and bargraph every X msec, you could have it happen every 2’nd, 3’rd, 4’th or even 10’th pulse from the tach. The update time would now vary, updating slowly at low RPMs and more rapidly at high RPMs. Perhaps the blinking would now be every other update and so the blink rate would vary as well. This might have a more pleasing (or at least interesting) effect, I don’t know.

FWIW : a shorthand for an if-else statement is

condition ? value_if_true : value_if_false

Ok, I know I havent been on here recently, I was out of the country doing a study abroad program. Now that I am back, and given some time to think a little bit of what was said, I am still at a loss…

  1. Going back to the zener diode, you mention that I would need a 2k ohm resistor to have 10V across it, but the diode is a 5v, and seeing as max voltage is 14.4V, that would mean no break down if that much is lost over the resistor. Wouldn’t using a slightly smaller resistor be better? because if the diode breaks down at 5 then you need less than 2k resistance to get above that…or should I be using a 3v zener? I am thoroughly confused…

  2. in regards to the blinking, can you reword your statement? I am not understanding what you are trying to tell me…I have someone who is a CompSci major who is going to be helping me code, in order to get that correct, but he hasn’t had much experience with arduino, just like me, and he has no idea currently on how to get it to blink correctly. If possible could you write a small bit of code to explain what you were getting at? This may spark some ideas and help us realize what you had in mind.

Keep in mind that I am doing all of the coding given the fact I don’t have any hardware currently in front of me, I don’t have the money to buy it and the first thing the team is going to buy is an engine for the car, so that is the first priority and then possibly they will spend the $20 for the bar graph breakout kit. I am just trying to stay ahead of the game and get as much as possible done before I have to start the semester and become busy, which is only 3 weeks away.

Ok so last night as I was going to sleep I thought of a possible solution but I have no idea if it would be possible to do, but here it is:

1)when the rpm counter is called, at the end of that method it will check to see if it is above 9900 rpm and if so it will enable a blinking method that somehow can run in the background while the rpm calculator does its thing. If it isn’t above it will just disable the blinking method.

float readFrequency(unsigned int sampleTime)
{
  numPulses = 0;                      // prime the system to start a new reading
  attachInterrupt(0, isr, RISING);    // enable the interrupt
  delay(sampleTime);
  detachInterrupt(0);
  return ( numPulses < 2) ? 0 : ( 60 * 1000000.0 * (float)(numPulses - 1) ) / (float)( lastPulseTime - firstPulseTime );

  if the return is above 9900rpm
       then enable blink
  else
       then disable blink

or would a while be able to work?
}
  1. now to figure out if that would be possible and if indeed it is, how would I make a method that makes all LED’s blink?

I know that by doing

BarGraph.barGraph(30, 0);
          delay(35);
          BarGraph.barGraph(0, 0);

that makes all LED’s go on, delay 35ms, and then turn all off.

I read through the link about the SimpleTimer, and that might be able to be used to allow this to run if I am not mistaken, which I most likely am…

If anyone sees a way to possible implement this I would really appreciate it if you could show how to make it work!!!

BlindAssassin111:
1)when the rpm counter is called, at the end of that method it will check to see if it is above 9900 rpm and if so it will enable a blinking method that somehow can run in the background while the rpm calculator does its thing.

Exactly !

BlindAssassin111:
I read through the link about the SimpleTimer, and that might be able to be used to allow this to run if I am not mistaken…

You are not mistaken. I'll have to go over this thread but I think you can use the SimpleTimer library to create 2 timers. When enabled per the above, one timer goes off at 1/2 the total blink period, ie - your 35 msec. All the LEDs are turned on until the timer goes off again, in 35 (or whatever) msec. Then the LEDs revert back to the correct RPM. This process repeats until the RPMs drop below some threshold and the blinking, and it's timer, are disabled.

The other timer would control how often the RPMs are computed and the LEDs updated w/that new RPM.

No need for delay() in your code.

BlindAssassin111:

  1. Going back to the zener diode, you mention that I would need a 2k ohm resistor to have 10V across it, but the diode is a 5v, and seeing as max voltage is 14.4V, that would mean no break down if that much is lost over the resistor. Wouldn’t using a slightly smaller resistor be better? because if the diode breaks down at 5 then you need less than 2k resistance to get above that…or should I be using a 3v zener? I am thoroughly confused…
The 15v I mentioned was a theoretical highest battery voltage. I've seen cars and boats get to 15.2v when the alternator is at full output. In any case use the highest voltage you think it would ever be. Calculate the resistor needed to make 5mA flow through the Zener at that "high" voltage. Repeat the calculation using the lowest expected voltage (? 12v ?) and 2mA. Choose a resistor whose value is somewhere between the 2 calculated. That way you'll always have 2+ mA flowing through the zener but never too many mA. The exact value isn't critical.

So long as the zener has 2 mA flowing through it, it’ll breakover and be at/near it’s rated voltage. The voltage across the resistor is then Vtach - Vzener and the current through the resistor as determined by Ohms law. Remember that these types of current/voltage calculations involving a diode are just a “good enough” approximation to the truth.

Mee_n_Mac:

BlindAssassin111:
1)when the rpm counter is called, at the end of that method it will check to see if it is above 9900 rpm and if so it will enable a blinking method that somehow can run in the background while the rpm calculator does its thing.

Exactly !

BlindAssassin111:
I read through the link about the SimpleTimer, and that might be able to be used to allow this to run if I am not mistaken…

You are not mistaken. I'll have to go over this thread but I think you can use the SimpleTimer library to create 2 timers. When enabled per the above, one timer goes off at 1/2 the total blink period, ie - your 35 msec. All the LEDs are turned on until the timer goes off again, in 35 (or whatever) msec. Then the LEDs revert back to the correct RPM. This process repeats until the RPMs drop below some threshold and the blinking, and it's timer, are disabled.

The other timer would control how often the RPMs are computed and the LEDs updated w/that new RPM.

No need for delay() in your code.

So, if I am understanding you correctly, I would need a timer that, when the rpm is above 9900, would turn on the LED’s for 35ms and then turn them off?

like this(sorry for crappy code, was just trying to get the main point across):

// Connect the frequency source to the INT0 pin (digital pin 2 on an Arduino Uno)
#include <SFEbarGraph.h>
#include <SPI.h>

SFEbarGraph BarGraph;
SimpleTimer blinkTimer;

volatile unsigned long firstPulseTime;
volatile unsigned long lastPulseTime;
volatile unsigned long numPulses;

void isr()
{
  unsigned long now = micros();
  if (numPulses == 1)
  {
    firstPulseTime = now;
  }
  else
  {
    lastPulseTime = now;
  }
  ++numPulses;
}

void setup()
{
  BarGraph.begin(1, 12);// begin(number of bar graph kits, the pin "LAT" is connected to)
}

// Measure the frequency over the specified sample time in milliseconds, returning the frequency in RPM
float readFrequency(unsigned int sampleTime)
{
  numPulses = 0;                      // prime the system to start a new reading
  attachInterrupt(0, isr, RISING);    // enable the interrupt
  delay(sampleTime);
  detachInterrupt(0);
  return ( numPulses < 2) ? 0 : ( 60 * 1000000.0 * (float)(numPulses - 1) ) / (float)( lastPulseTime - firstPulseTime );
}

void Blink()
{
  BarGraph.barGraph(30, 0);
}

void loop()
{
  unsigned char LED;
  unsigned char numLEDs;
  
  float rpm = readFrequency(140);
  timerId = blinkTimer.setInterval(35, Blink);
  blinkTimer.disable(timerId);

  if rpm >=9900
  {
         blinkTimer.enable(timerId);
  }
 else
  {
         blinkTimer.disable(timerId);
         numLEDs = ceil(rpm / 366.6667);
         BarGraph.barGraph(numLEDs, 0);
  }
}

So if I understand as well as I hope I do, it should 1)calculate RPM given a 140ms window to see signals, 2)create a timer called blinkTimer that has a time of 35ms, 3)check to see if the rpm is above 9900, and if so enable the timer(which then turns on the LED’s for the whole 35ms period and if not disable the timer and just light up the correct number of LED’s. Would this work as I am expecting it to?

I need it to constantly be doing this process because the engine revs so fast that there is no time to just check rpm every Xms and blink every Yms. Would increasing the number of pulses per rpm from the ECU allow for a faster polling time? I can do 2, 3 or even 4 pulses if need be.

BlindAssassin111:
So if I understand as well as I hope I do, it should 1)calculate RPM given a 140ms window to see signals, 2)create a timer called blinkTimer that has a time of 35ms, 3)check to see if the rpm is above 9900, and if so enable the timer(which then turns on the LED’s for the whole 35ms period and if not disable the timer and just light up the correct number of LED’s. Would this work as I am expecting it to?

I think so. I'll have to look at the SimpleTimer functions to see how best to do it.

BlindAssassin111:
I need it to constantly be doing this process because the engine revs so fast that there is no time to just check rpm every Xms and blink every Yms. Would increasing the number of pulses per rpm from the ECU allow for a faster polling time? I can do 2, 3 or even 4 pulses if need be.

If the pulses are spaced evenly then yes, more is better and can shorten the "observation time" needed to measure the RPM. I'll look over your code above.