Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Comparator help please -tach/shift light project

Status
Not open for further replies.

mojozoom

Member
My old car uses a 1mA current driven tach movement and the stock circuit isn't compatible with the MSD ignition box I use, and the adapter they sell to make the tach work buzzes like the dickens.

So I worked up a tach circuit based on the current tach diagrams in the LM2907 datasheet that'll work off the nice 12V square wave tach output connection that MSD provides. To go along with that I'd like to include a 2 stage shift light that lights 2 separate leds at a 400 rpm interval, and when the second led lights I'd like the first to go off.

I've got that that all worked up using an LM358 as a comparator, but I'm stuck using two pots and I really don't need independent adjustment of the two shift light turn on points - making them fixed at 400 rpm apart would be fine and hopefully minimize components. I was trying to use a voltage divider to fix two reference voltages and compare those to the tach output voltage, but everything I try seems to either work backwards or pulls down the current that the LM2907 is sending to the tach movement.

Can someone with more experience in these topics please advise if they see a better way to do this? Here's the circuit - ignore diode D2 hanging in the breeze there as it's just like that for troubleshooting. It connects to the - input of U2 above it in order to turn off the first led when the second turns on.

Thanks!

tach2.JPG
tach1.JPG
 
Hi

Probably do this with a single LM339 chip.
How much output voltage at each of the first and second shift points?
What is full scale output?

eT
 
Ok, the range the 1mA tach movement is reporting is from 0-8000 rpm, and V3 corresponds linearly to RPM and ranges from 0-5.86V with my current set of component values. So V3 = 0.0007 X RPM.


I'd like to set a target RPM for the shift point, but to have one light to come on at 400 rpm before the target RPM as well. So if you want to use a 5500 rpm shift point, the lights would trigger at 5100 rpm and 5500 rpm, correlating to V3 voltages of 3.57V and 3.85V respectively. Since I'm looking for a constant 400 rpm difference between the lights regardless of the setpoint, then the difference in voltage between the two references needs to be a constant 0.28V.


Hopefully that all makes sense. I'd like to only have one light trigger at a time, so I suppose it'll either need a window comparator for the first LED or we need something sneaky like the diode setup.
 
I should clarify that I'm not 100% sure that the tach movement is 1mA for full sweep, but the original 1958 patent for this 1968 Faria tach (the patent number was actually stamped on it) was based on a 1mA movement. But the patent was also describing a 4000 rpm tach for a 6-cylinder, and I am working with an 8000 rpm tach for a V8. I don't think they'd use different movements though, just different components on the circuit board. On my ohmmeter it measures 725 ohms and that runs the tach up to about 1300 rpm.

Maybe what I'm trying to do would be easier using an LM2914 in dot mode. Maybe span it over 2.8 volts so each division would be 0.28 volts, and then just use the top two LEDs? Or maybe use it in bar and connect a bunch of the comparator outputs together to one led so anything over a certain point always lights the same led.
 
I should clarify that I'm not 100% sure that the tach movement is 1mA for full sweep, but the original 1958 patent for this 1968 Faria tach (the patent number was actually stamped on it) was based on a 1mA movement. But the patent was also describing a 4000 rpm tach for a 6-cylinder, and I am working with an 8000 rpm tach for a V8. I don't think they'd use different movements though, just different components on the circuit board. On my ohmmeter it measures 725 ohms and that runs the tach up to about 1300 rpm.

Maybe what I'm trying to do would be easier using an LM2914 in dot mode. Maybe span it over 2.8 volts so each division would be 0.28 volts, and then just use the top two LEDs? Or maybe use it in bar and connect a bunch of the comparator outputs together to one led so anything over a certain point always lights the same led.

Hi

An LM3914 might be doable. I was going to suggest an LM339 comparator chip. It has four comparators that could be easily used to create one or two window comparators.
That part it easy. But it also has to change its references according to the selected shift setpoint so the LEDs go on/off correctly.

How do you intend to set the target RPM? Using a rotary selector mabe?
You could also have both LEDS flash when the setpoint is selected, then light steady as each is reached. However, it does make the circuit a little more complicated.

Operation could be something like this, but its up to you:
1. LEDs dark. Make selection with button(if lighted selector LEDs) or rotary switch for static selection (like a silkscreen image with markings)
2. Press "go" button. Setpoint LEDs begin to Flash
3. As each setpoint is reached, each corresponding LED changes to steady lit.
4. To "restart" (loop back to step 2).
5. To "finish" Press reset button. All LEDs go dark.

eT
 
Yikes - that all sounds very complicated! It'd probably need an Arduino or similar micro for that too.

For these old cars there's usually very little action going on at the dashboard, so if anything does light up or flash it's usually very very bad. So that's why I was thinking of just a simple shift light to start, and not an F1 bar graph style with an led every 200 rpm or something like that. But it is really nice to have a warning that you're approaching the redline, so two lights it is. The 400 rpm difference is something I chose just based on gut feel, so a little more wouldn't hurt anything and I expect I'll have to tweak that number once it's running on the car.

My plan to set the rpm for the shift light was to use a switch to divide the setpoint in half in some way, so for a setpoint of 6000 rpm I could flip the switch to "SET" and run the rpm up to 3000, then adjust a pot until the high side light turned on. I suppose that could be done by doubling the input signal voltage, cutting the LM3914 span in half at R(hi), or maybe even switching to different LED outputs for the setting process if that made sense with how this worked. Setting the shift point at the full 6000 rpm on my car would probably have my neighbors calling the cops on me for excessive noise.

Right now my biggest hiccup is that my simulation iterates endlessly when I have both the LM2917 and LM3914 in play. It's like I can use one or the other, but not both. I saw your posts on the tach for the V12 Jag from a while back and plan to grab some of those details for this too.
 
Well here's where I'm at with it now. It seems to work as expected, but I still need to iron out the setpoint mechanism. What seems to make sense to me would be to take the 7.3V that is set by the LM2917 zener and reduce that as needed to establish the setpoint voltage of the LM3914. Currently I would need exactly half of the 7.3V for a full scale 8000 rpm setpoint, and I'd like to use a pot to adjust that voltage down lower for lower setpoints.

But then the trick is how to cut that voltage in half again so the light comes on at half the normal rpm so you can adjust the setpoint. So I need to divide the divider??

tach3.JPG
 
Ok, after fiddling with the LM2917-14 for an eternity I pulled out an Arduino and had something working in short order. So now it become Arduino questions for everyone!

I have two separate Arduino circuits, one is a simulator to provide 12V pulses with 20% duty cycle, and it steps through the frequency range in 2000 RPM increments.

The other is the tach circuit, which reads the frequency of the pulses and provides a PWM signal to the tach gauge movement. The shift lights will come later.

Here's what I need help with though. The tach doesn't seem to respond perfectly linearly to the signal I'm giving it, though it's very very close. At 800 rpm it reads about 700, at 2000 it reads about 1900, at 4000 it reads 4100, etc. Close enough I suppose for 1968. But I'd like to come up with some way to calibrate it at each 1000 rpm interval and build a correction curve that could be applied to the PWM signal going out.

Ultimately I'd like the simulator to be part of the tach circuit and have the calibration be done via bluetooth and an Android app. For now I just need to come up with a way to implement the correction curve to get the PWM output to drive the meter to the exact value that it should. I'm guessing I'd have to store data in the EPROM after calibration is done so those values can be used again and again.

Thanks!
 
You should be able to get the tacho to be accurate and not need a correction curve. How are you reading the rpm?

Mike.
 
id roll back a few steps... how was the original tacho connected to the engine? via the coil negative wire? It may run off the MSD output but may require a pull up resistor to 12v (usually 1k works) otherwise you can also use an inductive kicker circuit and run it from the MSD output. then just concentrate on the shift lights as a seperate device
 
Currently the "rpm" comes from an Arduino. It's creating a 0-12V square wave with 20% duty cycle, duplicating the output of the tach wire on an MSD.

I currently have MSD's inductive kicker adapter to run the tach from the MSD tach output (the 0-12V square wave), but it's been making a sizzling sound for the past 18 years and I'm tired of listening to it. It's extremely common for them to make noise, and $70. Since I've been wanting a shift light integrated into the stock dash somewhere I figured I could do both at the same time. The shift lights are really easy to do as there's lots of examples out there to draw from.

Getting the tach to be dead on accurate and quiet would be really nice though.

 
I suppose I could try to drive the tach with a current source instead of using PWM, but the PWM was easy and seems to come very close to the correct result.
 
I'm busy now but could have a go later at writing an interrupt driven tach that should be accurate. Which Arduino are you using and what pin is the signal on?

Mike.
 
Sounds interesting!

I'm using an Uno right now and read frequency on pin 8 as I'm using using the FreqMeasure library. I figured I'd eventually move this to a Nano in order to fit it inside the tach housing.
 
On the Uno you can only attach interrupts to pins 2 and 3.

Here's an untested sketch which should send the RPM to the serial monitor. Don't have access to a board at the moment.

Mike.
Edit, calculating ten times per second is probably not going to be very accurate as 3,600RPM is 6 pulses in 100mS. Probably better to change it to something like twice per second.
Code:
#define TACHO 3   //can only be 2 or 3 if a 328 based board.

volatile uint16_t  pulseCount=0;
uint32_t lastRead;
uint16_t timeToNext=100;    //read ten times per second
uint16_t rpm;

void setup() {
  Serial.begin(115200);
  pinMode(TACHO,INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(TACHO),interrupt,RISING);
}

void interrupt(){
  pulseCount++;
}

void loop() {
  if((millis()-lastRead)>timeToNext){
    lastRead=millis();
    cli();              //prevent interrupting following two lines
    rpm=pulseCount;     //get the pulse count
    pulseCount=0;
    sei();              //enable interrupts again
    rpm*=600;           //times 10 is RPSecond - so *600 is RPM
    Serial.println(rpm);
  }
}
Edit added volatile to pulseCount.
 
Last edited:
A lot of basic analog electronic tachos are little more than a moving coil meter with a monostable /charge pump type circuit to give an average voltage roughly proportional to frequency.

They are not really precise instruments and each will probably be a bit different.


You could theoretically implement a look-up table to give a corrected output, or just pick a few points and interpolate between those to give an approximate correction.
 
I've also heard that standard tachs were often incorrect by a bit, and looking around the net last night confirmed that. Maybe 100-200 rpm off here and there is pretty common, some Mustang guys even see 600 rpm off at really high rpm. I stumbled on to the "multiMap" function which I think may do exactly what I need though. It's erroring right now though.

I know absolutely nothing about interrupts at this point, so bear with me. Is there something that would make an interrupt based frequency measurement more accurate than others? The fellow that made the FreqMeasure library seemed to think it would be extremely accurate which is why I used it.

It would be good if I had a second set of eyes on my MSD simulator code too. For it I'm turning on a pin for a specified time and then off for 4X that time, to get 20% duty cycle and variable frequency. I expect though that just looping through the code will add a few usec to the off time, reducing the frequency by an increasing percentage as frequency increases.

Also I understand that there's some sort of rounding error that occurs in using integer math here. I remember another post where a fellow was using milliseconds and getting huge frequency deviations where remainders were being eliminated. He switched to microseconds and resolved most of it. At this point I've assumed that my frequency measurement method was 100% accurate, and adjusted the on time used for each rpm frequency provided by the simulator until it delivered the exact measured result I was looking for. But that only works if my frequency measurement is truly 100% accurate.
 
Your problem is that you don't know where your error is, in the generation or the measuring. Do you have a multimeter with a frequency function? Have you tried using the frequency out function for generation?

Mike.
 
I do, but I wasn't entirely trusting it. It reads frequency and duty cycle, but what was concerning me was that according to the multimeter my duty cycle was decreasing as I increased frequency. That really shouldn't be possible when my off time was simply 4 times the on time. And it eventually would get to a point where the DMM stopped showing increases in frequency, whereas the serial monitor showed that it truly did increase.

I suppose this is the kind of thing I should be able to verify with my old dino of a scope. I'm heading home from work now and will play with that this evening. And your code too.
 
I tried the above code on a board and used tone to produce a 60Hz signal on pin 8. Most of the time the reading was 3600RPM but occasionally it showed 4200. This was due to the count occasionally being 7 due to the tone function not being accurate. A way around this may be to average the value over a second.

Here is code with averaging over 1 second. If you connect pin 8 to pin 3 then it should act as both generator and tacho. The code is a little more difficult to understand so if you are unsure about part of it just ask.

Mike.
Code:
#define TACHO 3   //can only be 2 or 3 if a 328 based board.
#define READINGS 10

volatile uint16_t  pulseCount=0;
uint32_t lastRead;
uint16_t timeToNext=1000/READINGS;    //read ten times per second
uint16_t rpm;
uint8_t readings[READINGS];
uint16_t total;

void setup() {
  Serial.begin(115200);
  pinMode(TACHO,INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(TACHO),interrupt,RISING);
  tone(8,60);
}

void interrupt(){
  pulseCount++;
}

void loop(){
  if((millis()-lastRead)>timeToNext){
    lastRead=millis();
    cli();              //prevent interrupting following two lines
    rpm=pulseCount;     //get the pulse count
    pulseCount=0;
    sei();              //enable interrupts again
    total=rpm;
    for(uint8_t i=0;i<READINGS-1;i++){    //scroll the readings and sum them as we go
      total+=readings[i+1];
      readings[i]=readings[i+1];
    }
    readings[9]=rpm;
    Serial.println(total*60);
  }
}
 
Last edited:
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top