# Interfacing with an AC voltage generating anemometer

Hello!
I am trying to measure wind speed using this anemometer on my Arduino UNO. It integrates a stationary coil which generates an AC voltage with a frequency relative to the rotational speed of its shaft. My idea was to convert the AC signal to a square wave, whose frequency I would then measure using the FreqCount library by PaulStoffregen. I prepared a test setup, using a function generator set to 100Hz (to simulate the AC signal from the sensor) and a comparator circuit, as seen below:

I checked the circuit's output using an oscilloscope and it is indeed a clean square wave with the same frequency as the AC input signal, with a LOW voltage of 0V and a HIGH voltage of 3.3V. (3.3V should be sufficient for the UNO's logic levels, right?). Then I fed the square wave to the Arduino, ran the example code and obtained the readings on the serial monitor. They perfectly matched the AC frequency of the function generator.
The problem is when I replace the function generator with the actual anemometer. While the comparator circuit still works as expected, the Arduino obtains erratic values ranging from approx. 1600-1800Hz, whilst the anemometer shaft is completely still. Spinning the shaft manually seems to cause higher readings of over 2000Hz. Of course these values are extreme, considering that the anemometer isn't expected to rotate faster than 100Hz.
So far, I have tried adding a passive low pass filter (1KΩ resistor and 100nF capacitor) at the comparator's output, so to cut off high frequency oscillations.
Any ideas about what's causing these erratic measurements? If my approach doesn't seem viable, I am open to alternative solutions.
Any help is appreciated!

The AC signal of the anemometer is only 100mV at 60rpm. Set your function generator to reflect that voltage in it's output and you probably get the same behavior.

That R1 forms a voltage divider with R2 and R3, reducing the effective voltage change you see on the comparator's input. Remove R1, increase the value of R2 and R3. 100k-220k or so will do just great. That will give a great improvement.

Also note that C1 should be non-polarised! So that means ceramic, as film is not available in those values. If your largest ceramic is just 1µ or 2µ2 you may have to increase R2 and R3 even more, 470k-1M even. This to keep your RC constant nice and high, so the offset resistors don't decrease your signal much.

Part of the problem is of course the rather low frequencies and low voltages you get from that anemometer most of the time (low wind speeds), making this AC coupling harder to pull off. So an alternative approach could be to bias the anemometer coil itself: in the data sheet there's a mention of a J1 between two black wires, if you keep that open you would be able to bias the coil itself. Basically voltage divider on one input of the coil and the same voltage to your comparator; the other end of the coil to the other input of your comparator. The voltage produced by the spinning coil will simply be added to that bias. I just don't know how to keep a comparator stable with identical voltage on both pins (which happens when the anemometer doesn't spin at all), I can imagine there will be oscillations here!

The remaining problem is of course the 6V peak/peak that it can produce when going really fast meaning you go over voltage, that can be handled with clamping diodes.

Here is the circuit I use to interface a home made AC anemometer with an Arduino.

The anemometer coil (R4 and V1) outputs only 10 mV at low wind speeds, but the circuit still outputs a respectable squarish wave (0.6 to 4.4V). It works very well in practice.

Note that decoupling capacitors are not shown in the schematic, but are absolutely required.

Thank you all for your replies. I have tested your suggestions and here are my results:

wvmarle:
That R1 forms a voltage divider with R2 and R3, reducing the effective voltage change you see on the comparator's input. Remove R1, increase the value of R2 and R3. 100k-220k or so will do just great. That will give a great improvement.

Also note that C1 should be non-polarised! So that means ceramic, as film is not available in those values. If your largest ceramic is just 1µ or 2µ2 you may have to increase R2 and R3 even more, 470k-1M even. This to keep your RC constant nice and high, so the offset resistors don't decrease your signal much.

I replaced C1 (originally used a 10μF electrolytic) with a 1μF MKT and swapped R2 and R3 for two 100KΩ resistors. I initially tested the circuit with the function generator at a low amplitude and it seemed to work just as fine as the original configuration did. But as I increased the AC amplitude (>1Vp-p) the output signal started getting cropped, as seen in the attached picture 1. Same results obtained with two 470KΩ resistors in place of R2 and R3. I even tried R2=470KΩ and R3=1MΩ, but still the same issue occurs.

What's worth mentioning is that while the AC amplitude was low enough to prevent this "cropping", the Arduino test code (FreqCount library example) was successfully reading the correct frequency, regardless if the input was the function generator or the anemometer's coil.

wvmarle:
Part of the problem is of course the rather low frequencies and low voltages you get from that anemometer most of the time (low wind speeds), making this AC coupling harder to pull off. So an alternative approach could be to bias the anemometer coil itself: in the data sheet there's a mention of a J1 between two black wires, if you keep that open you would be able to bias the coil itself. Basically voltage divider on one input of the coil and the same voltage to your comparator; the other end of the coil to the other input of your comparator. The voltage produced by the spinning coil will simply be added to that bias.

You are apparently referring to the diagram on page 4 of the datasheet. Note that I only own the bare anemometer. It's only the generator coil and a entirely passive PCB with no components (see attachment). The coil wires (black and red) are attached on one side of the PCB. The other side of the PCB has three wires: red which is directly connected to coil's red, black connected to coil's black and green which is connected to PCB's copper pour. No jumpers whatsoever.
That said, I assume you are suggesting a design like the one posted by jremington:

jremington:
Here is the circuit I use to interface a home made AC anemometer with an Arduino.

The anemometer coil (R4 and V1) outputs only 10 mV at low wind speeds, but the circuit still outputs a respectable squarish wave (0.6 to 4.4V). It works very well in practice.

Note that decoupling capacitors are not shown in the schematic, but are absolutely required.

I wired this circuit on one of the four comparators of the LM339 I am using and added a 100nF cap in series with the coil. Result can be seen in attached picture 2.

In general, none of the above suggestions seemed to work better in my case. In the attached picture 3 you can see the output of the comparator, configured as in the original design I posted (C1 being 10μF electrolytic), which works well for an amplitude as low as 400mVp-p.

Sotber:
That said, I assume you are suggesting a design like the one posted by jremington:I wired this circuit on one of the four comparators of the LM339 I am using and added a 100nF cap in series with the coil. Result can be seen in attached picture 2.

He mentioned decoupling caps. Not AC coupling.

Wire up the circuit as per the schematic posted in #3, and add decoupling caps where they belong: between the Vcc and GND pin of the comparator itself.

Sorry, my bad. Attached the cap to the IC. See the gif for the result.

added a 100nF cap in series with the coil.

Remove this capacitor and replace with a direct connection. The input biasing is critical for proper operation. Note that R4 in the diagram is the DC resistance of the sense coil, not a separate resistor. The circuit I posted works as advertised and is sending wind speed measurements right now.

Add decoupling capacitors 100 nF and 10 uF directly across the Vcc and GND pins of the IC.

Since your sensor can output several volts at high wind velocities, it may be a good idea to add input protection diodes as follows:

jremington:
Remove this capacitor and replace with a direct connection. The input biasing is critical for proper operation.
Add decoupling capacitors 100 nF and 10 uF directly across the Vcc and GND pins of the IC.

Yes, I correctly placed the decoupling capacitor after wvmarle's post. Also, added an 10uF as you suggested.

jremington:
Note that R4 in the diagram is the DC resistance of the sense coil, not a separate resistor.

Yes, I didn't add any additional resistor there, though my anemometer's coil has a resistance of 1.3KΩ.

jremington:
Since your sensor can output several volts at high wind velocities, it may be a good idea to add input protection diodes as follows:

Nonetheless, the circuit doesn't seem to behave very stably. When completely inert, I measure I high frequency (~500KHz), ramp-like waveform on the output, as seen on the attached picture.

I tried attaching the feedback resistor to the non inverting input of the comparator and that totally wipe away the high frequency oscillations. When the anemometer is rotated, the output is indeed a square wave. It's not perceivable by the example code I am using though. I tried the FreqMeasure library as well (which is meant for lower frequency measurements), but still no luck. Values either jump around erratically (over 40KHz) or I don't get a reading at all. However, the noticeable improvement with this design is that the circuit is handling low signals much better now. Even a slight spin of the anemometer shaft produces a square wave output.

All in all, the required square wave is obtained one way or another. It appears now that the issue lies within the Arduino sketch.

That 500 kHz could be the result of the ripple of a switching power supply. This is a typical frequency for those things to work at. Try scoping your power supply, see what you get there.

The waveform looks like what you get from an open-drain output with a too weak pull-up resistor (you mentioned you use the LM339 comparator, which indeed has open-drain output). Lowering the value of your pull-up resistor will give a much nicer square wave here. Not relevant to your project, just an interesting little side experiment.

Another thing: did you connect the other inputs of the comparator to something or did you leave them unconnected? Inputs should never be left floating, that can give all kinds of unwanted side effects. Unused outputs may be left unconnected.

So when your anemometer is spinning, this 500 kHz disappears completely and you see the expected frequency?

What square wave do you get then, voltage wise?

wvmarle:
That 500 kHz could be the result of the ripple of a switching power supply. This is a typical frequency for those things to work at. Try scoping your power supply, see what you get there.

I get my voltage supply directly from the Arduino’s 5V and GND pins. I scoped the pins. Perfectly straight, 5V line on the oscilloscope. No oscillations whatsoever.

wvmarle:
The waveform looks like what you get from an open-drain output with a too weak pull-up resistor (you mentioned you use the LM339 comparator, which indeed has open-drain output). Lowering the value of your pull-up resistor will give a much nicer square wave here. Not relevant to your project, just an interesting little side experiment.

At jremington’s design there is no pull-up resistor, right? In any case, I added a 3.3KΩ between the comparator’s output and VCC rail.

wvmarle:
So when your anemometer is spinning, this 500 kHz disappears completely and you see the expected frequency?

What square wave do you get then, voltage wise?

Yes, when the anemometer is spinning there are no 500KHz oscillations. The voltage of the oscillations is about 0-4.5V.
The square wave is also from 0-4.5V.

Sotber:
At jremington's design there is no pull-up resistor, right?

The LT1012 as in that schematic is an OpAmp, producing a voltage between 0 and Vcc as output. For this application an OpAmp will work great in a role of comparator. It won't be able to follow high frequencies but that's not important.

You are using an LM339 comparator, and those things have an open drain output. MUCH cheaper and simpler to construct than the OpAmp's voltage output. It requires a pull-up resistor; maybe you had your pin set to INPUT_PULLUP?

Yes, when the anemometer is spinning there are no 500KHz oscillations. The voltage of the oscillations is about 0-4.5V.
The square wave is also from 0-4.5V.

Great.
So my theory is now (maybe completely off of course): somewhere nearby you have a switching power supply (in your computer is one, for starters) which causes a small disturbance, probably the wires of your anemometer act as antenna. That tiny ripple (maybe too small for your scope to see - just 1-2 mV could be enough) is then picked up by the comparator, which turns it into a voltage. Quite sure it's not random noise as it's too regular. You may also be able to see it if you connect your scope to the comparator input, at high sensitivity.
The moment your anemometer starts turning it produces a signal that is much greater, 50-100 mV or more, completely swamping out this ripple, and it disappears.

Possible solution: add more hysteresis to your circuit, as explained in this document. This is what R5 in the circuit is for, but it seems it's not enough for your case. Decreasing the value of R5 would increase the hysteresis, filtering out this small ripple. Beware to not add too much hysteresis as you won't be able to measure your signal any more.

That your frequency measuring fails is maybe still caused by this issue even when the anemometer is spinning: when the signal of the anemometer is very close to zero the 500 kHz ripple takes over again, and your comparator is producing lots of pulses around the zero crossing.

So first of all I'd suggest you to get rid of this high frequency noise. Good that you have a scope at hand, otherwise it'd be a nightmare to troubleshoot!

Thank you for the insight.
I believe we should first establish which circuit is the most appropriate one, because it feels like we are swinging between the two designs.
The original design I posted works pretty well, without picking up a high frequency noise. Problem is that it doesn’t handle low signals.
jremington’s suggestion does handle low signals, but picks up noise.

That being said, the following suggestion applies to the original circuit, which isn’t affected by noise.

wvmarle:
Possible solution: add more hysteresis to your circuit, as explained in this document. This is what R5 in the circuit is for, but it seems it’s not enough for your case. Decreasing the value of R5 would increase the hysteresis, filtering out this small ripple. Beware to not add too much hysteresis as you won’t be able to measure your signal any more.

wvmarle:
The LT1012 as in that schematic is an OpAmp, producing a voltage between 0 and Vcc as output. For this application an OpAmp will work great in a role of comparator. It won’t be able to follow high frequencies but that’s not important.

You are using an LM339 comparator, and those things have an open drain output. MUCH cheaper and simpler to construct than the OpAmp’s voltage output.

I am getting slightly conflicting messages here. So, you are in favor of an OpAmp design? Shall I ditch the LM339? Maybe go for a TLC271?

wvmarle:
It requires a pull-up resistor; maybe you had your pin set to INPUT_PULLUP?

Nope, haven’t touched the build-in example of the library. Here’s the code:

/* FreqMeasure - Example with serial output
* http://www.pjrc.com/teensy/td_libs_FreqMeasure.html
*
* This example code is in the public domain.
*/
#include <FreqMeasure.h>

void setup() {
Serial.begin(57600);
FreqMeasure.begin();
}

double sum=0;
int count=0;

void loop() {
if (FreqMeasure.available()) {
count = count + 1;
if (count > 30) {
float frequency = FreqMeasure.countToFrequency(sum / count);
Serial.println(frequency);
sum = 0;
count = 0;
}
}
}

Also checked the library .cpp file. Doesn’t seem there is a command to set the internal pullup.

wvmarle:
So first of all I’d suggest you to get rid of this high frequency noise.

Note that when I attached R5 of jremington’s design to the non-inverting input of the LM339, the oscillations disappeared.

I was always talking about jremington's circuit. That has some hysteresis built in already, but it may simply not be enough for your situation.

You may try to replace it with an OpAmp (most general purpose OpAmps will do - try with whatever you have in your parts box), see what happens. It may very well filter this noise out simply by being unable to follow.

Alright, I'll post back with my results

The LT1012 is a really nice op amp, perfect for this application.

jremington's suggestion does handle low signals, but picks up noise.

Not in my case. The sense circuitry is enclosed within the grounded metal case of the anemometer, far from any AC line devices.

I simply poll a digital port pin to read the output.

I believe you can simplify your circuit by significantly.

1. Connect the negative input of the LT1012 to ground

2. Feed the input signal through a 10k resistor to a pair of back to back 1N4148 diodes connected to ground

3. Connect the back to back diodes to LT1012 positive input.

I've not had experience specifically with the LT1012 but when used as a comparator, other amplifiers have worked with the inputs at ground and sometimes a little below.

John

I believe you can simplify your circuit by significantly.

You are welcome to try, and report back.

But check the LT1012 data sheet first.

So, I have tried all you suggestions so far and the results have been quite similar. Here are my observations:

• I wired up the circuit using an LT1013 OpAmp. I got high frequency oscillations with anemometer being inert. Their amplitude is ~3V. As an experiment, I added a 220nF cap across the coil. Oscillations disappeared, but I was reading a constant voltage of ~3V while the instrument wasn't spinning. Again, feeding the feedback to the non-inverting input (R5 between output and + of OpAmp) resolved all issues. Nice square wave output, good response to low signals.
• Using again the LT1013, I tried JohnRob's approach. Circuit works great without any modifications.
• I wrote a very basic code that keeps checking a digital pin and then measures the input signal's HIGH time.

My current setup seems to work adequately. Attached are the circuit and the code:

int pin = 8;
unsigned long previous;
unsigned long current;
unsigned long hightime;

void setup() {
Serial.begin(9600);
pinMode(pin, INPUT);
}

void loop() {