I have a 12V pulse square signal coming from an RPM sensor. I would like to translate it into 5V pulses since I will need to use it as input in an Arduino. What do you guys think is the easiest way? Can a comparator be used?
- voltage divider (I would suggest 10k/5k, for a 4V swing. This allows for a high margin up to 15V from the sensor.)
- resistor and zener diode
- drive an n-channel MOSFET gate, pull up the output to 5V
- use that same MOSFET as a down-shift level translator
- use an optoisolator
The method you choose depends on how much electrical noise your environment has. If it’s a car or motorcycle engine, this might be a lot.
There are combo solutions such as using a voltage divider and a zener and a transistor or FET to condition the signal. That said, the optoisolator is the most robust solution as it breaks up any potential current loop between the sensor and your Arduino. It’s also more expensive, but much less than the cost of your fried board.
There's an additional benefit to using an optoisolator: by referring the diode input to the sensor ground, it will reject common-mode noise that might find its way onto the sensor wires.
More here: Detect car +12V using Arduino
And a Littelfuse appnote about automotive noise
MORE: Here's a simulation of common-mode noise with the optoisolator (try it here). I added a Zener to protect the opto LED, it's optional.
You don't need a comparator. Since you're making the voltage smaller there is no need to use an amplfier or comparator.
What I would use is one of these:
Note how the resistor divider circuit on the left doesn't output 5 V exactly (if the 12 V is 12 V then the output will be 4.8 V) but that doesn't matter. An Arduino running on 5 V will consider a voltage below 2.5 V a zero and a voltage above 2.5 V a one.
To make a more precise 5.0 V from 12.0 V you'd need a 14 k (instead of 15 k as I suggest) resistor. A 14 k resistor migth be hard to find, 15 k ohm is more common.
The same is true for the circuit on the right, a 5 V zener diode could be harder to find than a 4.8 V zener. But again, that will work perfectly fine.
There is an analog comparator on the ATmega328p chip, however there is no way of adding hysteresis, unfortunately.
A bulletproof way would be to take the 12V input, apply some signal conditioning, and then connect it to a comparator (eg. LM393) with some hysteresis or a Schmitt trigger gate (rather less predictable hysteresis but a bit simpler).
On the other hand, maybe a simple voltage divider would work for you. Might be reliable.
If you want to go the comparator route, something like this:
The blue trace represents the input 0/12V with some noise superimposed (a sine wave just for illustrative purposes). The red trace is the input divided down and filtered by C1/R3/R5.
R1/R2/R6 set the threshold at 2.5V nominal with about 450mV of hysteresis (so the thresholds are about 2.73V (rising) and 2.28V (falling).
R7 is a pullup which is required because the LM393 is open-collector.
This is only a few pennies worth of components and is pretty much bulletproof so it would be good for a volume product where failures are not to be tolerated.