Arduino Ultrasonic Anemometer Part 5: Testing the digital board

In the last post I went through the analog board and showed what I had to do to get it working properly. Today I’ll do the same whith the digital board. Click here for an overview over this series of posts on the anemometer project: https://soldernerd.com/arduino-ultrasonic-anemometer/

_MG_1021
The corrected digital board

So I plugged in the board for the first time and everything looked fine. The power LED came on, both the +5V and -5V rails worked as expected. But not everything worked that well.

I’ve explained in a previous post how the Arduino can control the direction by means of two lines: Axis and Direction. Here’s the meaning of these signals (L=low, H=high):

Axis=L, Direction=L -> North to South

Axis=L, Direction=H -> South to North

Axis=H, Direction=L -> East to West

Axis=H, Direction=H -> West to East

The first thing these two signals do is to control 74HC139 address decoder. The 139’s enable signal is grounded so its outputs are always on. Depending on Axis and Direction the 139 turns exactly one of the signals North_EN, South_EN, East_EN and West_EN on. EN stands for enable. As the bar over the signal name indicates, these are active-low signals. So zero volts means on and 5V means off. Each of these enable signals is connected to an LED. The other side of the LEDs is connected (via a resistor of course) to +5V so the LED is on when the signal is on despite the fact that it is active low. This part also worked.

Then we have two 74HC368 hex inverters. If you look at the 368s data sheet you’ll notice that it consists of 6 inverting buffers. But there are only two enable signals. As with most enable signals, these too are active-low. One enable signal controls 4 of the inverting buffers while the other one controls only 2. For us, this doesn’t matter since we need a total of 4 groups (one for each transducer) of 2 buffers each (one for each transducer pin). So we’ll only use two buffers of each group no matter if there are four.

Each group is controlled by one of the enable signals coming from the 139. The North_EN signal enables the buffers of the group connected to the North transducers and so forth. So exactly one group of buffers is on at any given time. That’s the transducer that is transmitting. All 4 buffer groups are connected to the same PWM signal (named Signal on the schematic) coming from the Arduino. But since only one buffer group is on, only that transducer is actually sending. The other buffer outputs are off and their transducer pins can float freely. Notice how the PWM signal is connected to the input of only one of the buffers in each group. The output of that buffer ist then connected a transducer pin as well as to the input of a second buffer. So one pins of the transmitting transducer are always in opposite states. When the first one is high, the second one is low and vice versa. There were no surprises here, everything worked as expected.

AxisDirection
How Axis and Direction control the 74HC139

Here’s a little visualization of the 74HC139 in action. Note the glitches in the West_EN and East_EN signals. The Arduino can’t change both Axis and Direction perfectly simultaneously, there will always be at least one clock cycle in between the two commands. That’s why those glitches happen. But Axis and Direction are changed between measurements so nothing interesting is going on anyway. No need to worry about this here.

But then there is the task of selecting the right signal to listen to. And that’s where I’ve messed up just about everything. I guess I just wanted to build my first prototype as soon as possible and didn’t double-check everything as I should have. I probably also tried to be clever and use as few signals as possible and chose my inputs so that it simplifies the physical routing on the PCB. Anyway, I ended up with a design that doesn’t work. So if you want to build this circuit, look at the RevB board and schematics where I’ve corrected the mistakes.

As explained before, there are three 74HC4052 multiplexers to eliminate crosstalk. Like the 139, the 4052s are controlled by Axis and direction. But watch out: You need to select the transducer opposite from the one that is transmitting. So for example Axis=L and Direction=L means North to South. North_EN is low so the North buffer group is on and so North is transmitting. That means we have to chose the South transducer for receiving. Nothing complicated, really. But you have to concentrate and think carefully about which transducer has to connected to which of inputs. There are multiple solutions that work but many more that don’t.

My working solution is as follows: IC5 selects between North and East. So North is connected to input 1 while East is connected to input 3. When we want to listen to North, East is idle and vice versa. That’s why we get rid of crosstalk. The negative output of IC5 is grounded, the positive one is named NorthEast and routed to IC6. The second multiplexer, IC7 selects between South on input 0 and West on input 2. Again, the negative output is grounded and the positive output named SouthWest is connected to IC6. IC6 then only has the simple task of choosing between SouthWest and NorthEast. That’s why I only needed my Direction signal to control this multiplexer. The other address input can be left grounded.

I didn’t bother building another board so I’ve just used some pieces of wire to correct my mistakes. The corrected circuit is equivalent to what you see on the RevB schematic and works flawlessly.

This was definitely not my most interesting post so far. Lots of text and much in the way of photos or screenshots. Analog circuits are usually more fun to work with I find. Next time I’ll connect the Arduino to my two boards and show you how they perform. There will be some photos and screen shots again, promise.

Click here for the next post: https://soldernerd.com/2014/11/19/arduino-ultrasonic-anemometer-part-6-mechanical-design/

Arduino Ultrasonic Anemometer Part 4: Testing the analog board

In this post I will go through the testing of the analog circuit and what I had to do to make it work properly. Click here for an overview over this series of posts on the anemometer project: https://soldernerd.com/arduino-ultrasonic-anemometer/

20140930_223552
A first, basic test setup.

Ok, so the the analog board is finally ready and all the components have been soldered into place. Time to see if it works as expected. My test setup looked as follows: I’ve programmed an Arduino (a Mega as you can see in the background, I didn’t have a Uno at that time but it doesn’t matter for what I’m doing here) to output 15 pulses at 40kHz from one of its pins (followed by a break of a few milliseconds). That pin was connected to one of the pins of a transducer while the other transducer pin was grounded. A second transducer was placed accross from the first one in a 20cm distance. That’s the distance/size I’m planning to use in the final design as it keeps the wind meter nice and compact. One pin of that second transducer was grounded while the other one was connected to the amplifier input of the analog board. So there are only 2 transducers at this time. One constantly transmitting, the other constantly receiving. Software is also minimal. Keep it simple for now, we’re just trying out the analog circuit.

Amplifier

send_receive
Transmitted signal and amplifier in- and output.

Here we have the transmitted signal in red at the bottom left, together with the amplifier input (yellow), output of the first stage (green) and output of the second stage (purple). On the positive side, the received signal (amplifier input) is quite strong, around 350mV peak-to-peak. But the amplifier is barely working. At the output of the second stage we want a signal in the range of 5V pp but we get just a bit more than 700mV. We’re using a two-stage tuned amplifier and only double the signal amplitude. That’s hopeless.

As I’ve said in part 3, the root cause for this is my poor choice for the inductor/capacitor combination. 47uH or 330nF at 40kHz only give an impedance of 12 Ohms. Even with a decent Q-factor the impedance across the LC tank will never be high enough. I’d rather use something like 1mH / 15nF or 470uH / 33nF as as Carl did. But I didn’t have a inductor like that at hand so I had to change some other components to fix it.

First I changed the bypass capacitors (C5 and C10) from 100nF to 1uF. That makes the emitter ‘more grounded’ at signal frequencies (4 ohms instead of 40 ohms if you do the math). That did help but was not enough to save the show.

I then changed the emitter resistors (R8 and R13) from 330 ohms to only 47 ohms. The logic behind this is simple: The voltage across the LC tank is too small because the impedance is too low. Voltage is current times resistance (or impedance). I can’t change the impedance because I don’t have a suitable inductor so I have to increase the current. Changing the base resistors does just that.

Now I have plenty of gain at the price of a much-higher-than-planned quiescent current. Actually, gain was even a bit too high so I put in 15 ohms for R7 and R12 to slightly reducing the gain. Power consumption is not really a concern in this prototype so we’re fine for now. But if you’re going to build your own, use a big enough inductor in the first place and you won’t have to jerk up the current just to squeeze out enough gain.

amplifier_400us
Amplifier after fixing the gain

Amplifier input (yellow), output of the second stage(green) and output of the second stage (purple). Note the different scales of 200mV, 1V and 2V per division. As you can see, the gain’s fine now. We’re getting a bit more than 4 Volts of amplitude peak-to-peak which is just what we need.

amplifier_20us
Close-up of the amplifier signals

You can also see how much cleaner the output is compared to the input. The yellow signal has picked up quite a bit of noise gut the purple signal looks perfectly clean. That’s the benefit we get from the narrow bandwidth of the tuned amplifier. And that’s why you don’t want to just use an op-amp.

Envelope detector

Let’s turn to the envelope detector now. Fortunately this part worked right from the start but that doesn’t mean it can’t be improved. I’ve used a voltage divider of 1M and 47k (R14 and R15) to get a voltage of 2.2 Volts which just about compensates for the drop over the schottky diode D1. Maybe I’ll use an identical diode in my next design to get a voltage exactly one diode drop above ground.

lowpass_filter
Envelope before and after smoothing

Here we see the transmitted signal (red) together with the amplifier output (purple), the output of the diode / input of the low-pass filter (green) and the filter output (yellow). Note how the filter makes the stairs in the green signal disapear. That’s exactly its purpose.

I found the envelope to be a bit slow so I’ve changed the resistors R16 and R17 from 47k to 22k. Together with the 1nF caps (C15 and C16) that gives a -3db point of 7.2kHz. That makes the envelope quite a bit faster which means the rising edge will also be steeper. That makes it easier to precisely trigger on it, provided it is still smooth. Obviously you have to strike some balance here. Not sure if my values now are perfect but they definitely do work ok.

One problem I’ve encountered is that I get some nasty oscillations in the envelope if I turn up the gain too high (via the pot R1). Making the envelope faster has made it even worse. I’m not quite sure why that is. It’s my first time to work with a VCVS (voltage controlled voltage source) circuit such as this active filter. I might use two stages of simple op-amp buffers and RC filters in my next design. That means I’ll need an extra op amp but anyway. For now, I just have to be modest with the gain setting and everything is fine.

envelope_detect_500us
Envelope detector in action

This screenshot shows the envelope detector in action: Transmitted signal (red), amplifier output (purple), envelope (yellow) and output of the envelope detector (green). Note that this screenshot was taken before the changed cutoff frequency of the filter. The yellow curve is very smooth but doesn’t track the purple amplifier output very well. That’s why I thought it was a bit slow.

envelope_detect_100us
Close-up of the envelope detector triggering on the rising edge of the envelope

The green signal is the output of the comparator which is also the output of our envelope detector. It will be connected to the Arduino where it will trigger an interrupt and serve as a coarse measurement of the time-of-flight.

Zero-crossing detector

My zero-crossing detector is extremely simple. I set the inverting input of the comparator to half the supply rail by means of R23 and R24. The 100nF cap across R24 (C21) makes sure it stays there and doesn’t swing around itself. I bias the amplifier output to the very same 2.5 volts so I really trigger exactly when the sine wave crosses zero. R22 makes sure the non-inverting input to the comparator can swing freely and the input impedance is reasonably high.

zero_crossing_200us
Zero-crossing detector

Here we see the output of the amplifier / input to the zero-crossing detector (purple) together with the zero-crossing detector output. Everything seems to work fine. As expected, the detector also triggers on very small signals and potentially noise but that should not pose a problem.

zero_crossing_10us
Close-up of the zero-crossing detector input and output

These are the same two signals watched a bit more closely. You might notice that there is quite a bit of time delay from the actual zero-crossing to where the green signal changes. This won’t be a problem as long as the delay is constant but I’m planning to use a faster comparator in my next design. This one has a propagation delay of 8us according to its data sheet. You can get others that are two orders of magnitude faster for nearly the same price such as the MCP6561R with a propagation delay of only 80ns.

Temperature measurement

No surprises here. The output of the LM35 is 10mV per degree centigrade as expected and is amplified by a factor of 4.3 by the op amp. Can’t quite remember why I chose only 4.3, I might change that to 11 by changing R25 to 10k.

Next time I’ll go through the same kind of stuff for the digital circuit. Click here: https://soldernerd.com/2014/11/18/arduino-ultrasonic-anemometer-part-5-testing-the-digital-board/

Arduino Ultrasonic Anemometer Part 3: Analog Circuit

Today I’ll go through the details of the analog cirquit. Click here for an overview over this series of posts on the anemometer project: https://soldernerd.com/arduino-ultrasonic-anemometer/

_MG_1026
The analog board ready to be connected

This is what I would consider the heart of this wind meter. This is where the received signal is amplified and processed so the overall accuracy and reliability of the entire project really depends on it. The functionality of this board can be summarized as follows:

  1. Amplify the received signal
  2. Generate a digital signal when the amplitude exceeds a given threshold (envelope detector)
  3. Generate a digital signal every time the received signal crosses zero (zero crossing detector)
  4. Measure the temperature
20140930_223527
The finished analog circuit on the test bench

This circuit runs on the +5V rail generated on the digital board. There’s no need for a negative voltage here, the +5V is all we need. The input to the amplifier (i.e. the received signal) also comes straight from the digital circuit. The 3 outputs temperature (analog), zero-crossing detector (digital) and envelope detector (digital) are all connected to the Arduino Uno. I’ll go through each of the four parts now.

_MG_1025
Analog board with the Arduino on the left and the digital circuit below.

Amplifier:

Just as Carl, I have used two tuned amplifier stages. Each stage uses a NPN darlington pair built from two discrete transistors. The parallel LC tank at the collector determines the resonant frequency of 40kHz as well as the bandwidth. Check out this wiki page http://en.wikipedia.org/wiki/Common_emitter or google for ‘degenerated common emitter amplifier’ if you’re not familiar with this topology.

_MG_1027
Close-up of the amplifier

 

The main difference to Carl’s design is that it’s running from 5 volts instead of 8 which eliminates the need for an extra rail.

I’ve added a 10k resistor from the emitter of the first transistor to the emitter of the second. This is often done to to enable Q1 to turn of Q2 faster. It’s probably not necessary at our low frequency but leaving it away later is much easier than adding it.

I’ve also added an extra resistor to the emitter degeneration. There is a bypassed resistor as with Carl’s design but I’ve added another resistor in series that can be used to reduce the gain. I’ll use a zero-ohm resistor at the beginning and replace that with whatever is needed to get just the right amount of gain. Thinking of it, it would have been smarter to put the gain setting resistor in series with the bypass capacitor only. That way I could adjust the gain without affecting the biasing. But that’s something for the next version.

For simplicity, I’ve biased the input of both stages to half the supply rail or 2.5 volts. The emitter will be two diode drops lower at around 1.2 volts. That should be sufficient to get a stable quiescent current over a reasonably wide temperature range. Speaking of quiescent current: The 330 ohms emitter resistor will yield a quiescent current of around 3.5mA.

I’ve made a rookie error on the LC tank. Carl had used a 470uH coil with a 33nF capacitor which gives just the right resonant frequency. He reports the DC resistance of his coil to be around 10 ohms which gives a Q-factor of around 10 – not great but sufficient. I didn’t have a 470uH inductor around but there were a few 47uH ones from a previous project. They had a DC resistance of slightly below 1 ohm so the Q-factor would also be just above 10. So I decided to use them, together with a 330nF cap to get the right frequency. Onetenth of the inductance, one tenth of the resistance, ten times the capacity. Same frequency, same Q, just perfect I thought. And yes, the resistance across the LC tank does have the same shape. But it only has one tenth of the value. So I got very little gain out of the amplifier when I first turned it on and had to correct this later. Lesson learned.

Envelope detector

I’ve changed little for the envelope detector. It still uses a two-pole active low-pass filter. The values have changed somewhat but the time constants and cuttoff frequencies remain similar.

_MG_1028
Close-up of the envelope detector

I’ve used a 1M plus 47k resistor at the input before the diode. At a 5V supply this yields a voltage of about 0.2 volts which just about compensates for the voltage drop over the schottky diode.

I’ve added a 10k pot to adjust the gain of the active filter. So there are two parameters you can adjust without grabbing your soldering iron: filter gain and threshold voltage.

I have included a (positive) feedback resistor across the comparator just in case I need some extra hysteris but don’t plan to use one unless tests show it’s really needed. I found that most of the time the comparator itself has enough hysteris of its own. But that remains to be seen, there is space on the board in case we need it.

About the components: The op-amp is a Microchip MCP6061, a precision op-amp. We don’t need this here but I happened to have some of them from a previous project. The comparator is a Microchip MCP6541. A bit slow (up to 8us of propagation delay) but as with the op-amp I already had some at hand.

Zero-crossing detector

I’ve simplified the zero-crossing detector somewhat. I want it to trigger every time the received signal crosses zero. When the signal is small it will most likely trigger on random noise but I’m not worried about that. I’m planning to average a number (say, 16) zero-crossings for each measurement. Exactly half of them shall be positive-to-negative and negative-to-positive. This will help to cancel some of the errors I hope. My plan is to set up my interrupts on the Arduino to trigger on the envelope detector first. Only after that I will enable the zero-crossing interrupts. Once I have captured all of my 16 (or whatever the number happens to be) zero-crossings, I’ll disable both time of interrupts until the next measurement. So this zero-crossing detector may random-trigger as much as it likes during all other times.

_MG_1029
Close-up of the zero-crossing detector

So I bias the signal at half the supply rail at 2.5 volts. The threshold is at 2.5 volts as well so I can even use the same resistive voltage divider.

As with the other comparator, I’ve included a feedback resistor across it but don’t plan to actually use it.

Temperature measurement

At the heart of the temperature measurement is a LM35 temperature sensor. It outputs a voltage of 10mV per degree centigrade. So there’s no way you can measure any temperatur below zero. That’s of course a problem depending on where you live but I see this version as a prototype and for testing it will do just fine.

_MG_1030
Close-up of the temperature measurement

There is also an op-amp that lets you scale up the rather small voltage of the LM35 to the 0…5V measurement range of the Arduino ADCs.

Here are the links to the board layout and the schematic as PDFs. As I’ve mentioned before I’m happy to share the Eagle files if anyone’s interested but at the moment I can’t upload them here. Seems you have to go premium to upload zip files and the like.

analog_RevA_Board

analog_RevA_Schematic

Next time I’ll talk about my first tests with the hardware described so far. Click here: https://soldernerd.com/2014/11/16/arduino-ultrasonic-anemometer-part-4-testing-the-analog-board/

Arduino Ultrasonic Anemometer Part 2: Digital Circuit

I’m keeping my word and continue to document this project that I’ve been working on over the last two or so months. In this post I will talk about the digital part of the circuit.

Click here for an overview over this series of posts on the anemometer project: https://soldernerd.com/arduino-ultrasonic-anemometer/.

_MG_1021
Digital part of my ultrasonic anemometer. I’ve messed up some signals in Eagle and had to painfully correct this later.

What is this cirquit supposed to do? It has 4 ultrasonic transducers attached to it. At any point in time, exactly one of them will be transmitting while the one accross from it will listen and receive the signal. For example, if the North transducers is sending then the South transducer needs to be listening. The other pair of transducers just sits there idle.

The signal to be sent is a series of PWM pulses with a frequency of 40kHz and a duty cycle of 50%. This signal will come from the Arduino, the circuit here just needs to route it to the correct transducers.

For the receiving transducer, one leg needs to be grounded while the other one must be allowed to float freely. The signal on this floating leg is what you are receiving. So this received signal needs to be routed to the analog part of the circuit where it will be amplified and processed. Here, we don’t need to worry about this yet, we just need to make sure, the signal is as strong and clean as possible. That means we will have to protect it from the much more powerful PWM signal.

The Arduino needs some way of telling this cirquit in which of the 4 possible directions to measure. I thought the easiest way of doing this is by means of two signals: Axis and Direction. Axis determines if we are dealing with the North/South or East/West axis. The Direction signal then determines which side is transmitting and which one is receiving.

_MG_1023
Power supply: LM2931 on the left, ICL7660 on the right.

But let’s start at the beginning. Most of the board is powered from a +5V rail but the multiplexers (more on them later) also need a -5V supply to do their job. So I’m using a linear regulator to make +5V from the Arduino’s Vin voltage. Vin is the voltage applied to the Arduino’ s DC jack.I’m using an LM2931 (pin compatible with the 7805) but you could use anything really. I then feed my +5V to a ICL7660 (the Microchip version of the 7660 but again, you could use anything) to get a -5V rail as well. Since the load on the -5V rail will be minimal I didn’t bother using tantalum caps but just used 10uF ceramics.

_MG_1022
Close up of the rat’s nest to correct for the messed-up signals on the PCB. The technical term for this is ECO: Engineering Change Order.

The transducers are driven by a pair of 74HC368, a classic hex inverter with tri-state outputs. This last part is important because like I said, we need to let the receiving transducer float freely (at least one leg), otherwise it won’t be able to receive anything. The inverting nature of this chip allowes us to generate a 180 degrees out-of-phase PWM signal easily. So when transmitting, one leg is always high while the other one is low and vice versa.

The buffers are enabled by a active low enable signal. So when the respective enable signal is low, the output buffer is on and the transducer can send. When the enable signal is high, the output buffer is off and the pins can float freely.

On the receiving side I’ve used three 74HC4052 multiplexers. They allow you to choose 1 out of 4 signal pairs and connect them with a common pair on the other side. Two address pins are used to decide which of the 4 pairs to connect. For this we can just our Axis and Direction signals from above. The 4052s can be turned on and off just like the 368s but we never need to turn them off so we can just ground the enable signal.

We have four transducers and the 4052 can handle 4 pairs of input signals. So yes, we could just use one. But there would be cross-talk from the (powerful) PWM signal to the (weak) received signal. So the solution is to cascade 3 of them in such a way that the receiving and transmitting signals never meet. So you can’t put North and South on one multiplexer (mux) and East and West on another. That won’t help. You have to include one from each axis so one of them is always idle.

I think once everything works as supposed, cross-talk won’t be a problem since we will stop sending before the signal arrives at the receiving transducer. But this is just a prototype anyway so I don’t mind some overkill that will probably save me some hassle during the testing/debugging phase. This way I can send and receive endless PWM signals (and not just bursts of them) while tuning the amplifier for example. But I’m planning to just use one in the next version.

Note that I’ve grounded one pin of the output signal on the first two multiplexers. So when I choose a transducer to receive, one of its legs is automatically grounded while the signal on the other one is routed to the 3rd and final mux.

There is one final thing to watch out for with these multiplexers: They have two supply rails (plus ground) and the signal you want to pass through the mux has to lay between those supply voltages at all time. In our case, the received signal will oscillate around zero volts so it will be negative half of the time. That means we need to provide a negative voltage as well. That’s why we need the -5V rail. It’s not exactly elegant having to generate a negative voltage just for that but the way the circuit works it is needed. In the next version I will probably bias the input signal to oscillate around some positive voltage so I won’t need the -5V any more.

_MG_1024
LEDs are connected to the enable signals to show which way we are currently measuring.

If you have studied Carl’s circuit (highly recommended), most things will look familiar to you up to here. I’ve drawn my own schematic and have done some things somewhat differently but the general idea is really similar. Supply rails of plus/minus 5 volts, a pair of 368s to drive the transducers and cascaded 4052s to route the received signal.

Now there are two things where I’ve changed a bit more. The first is this Axis/Direction approach so I only need two control signals from the Arduino. It saves some pins on the Arduino and simplifies the software. If that’s necessary depends mainly on what else you want the Arduino to do. Carl has used a dedicated Atmega328 rather than an actual Arduino so there are plenty of I/O pins that serve no purpose otherwise. My goal is to (one day, hopefully) build a standard Arduino Uno shield that you can just stack of your Arduino Uno board. So who knows what other tasks that Arduino has to accomplish. That’s why I thought it wise to keep the task as simple and use as few pins as possible. The downside is that I had to use an 74HC139 to decode the Axis/Direction signal and generate the individual enable signals for the 368s. While I was at it, I decided to attach an LED on each of the enable signals. So you can see from where to where you are currently measuring. The final software will probably change that every few milliseconds so you won’t be able to tell anything but for testing and debugging I thought it might help.

One last thing that I’ve added was an NPN transistor that grounds the output signal to the amplifier when turned on. So with an optional mute signal I can turn the output off. Not sure if I will really use it. It’s completely optional but I’m already thinking about the next version and as I’ve mentioned I only want to use a single multiplexer. So I’m thinking about just grounding the output signal while transmitting pulses. A poor man’s RX/TX switching of sorts…

Here are the schematic and board layout as PDFs. I’d be happy to share the Eagle files as well but so far I haven’t managed to upload them here. Only a few file types are allowed here it seems. But let me know and I’ll send them to you.

This is what I’ve built so the errors are still there: digital_RevA_Schematic, digital_RevA_Board

This is the updated version (but I’ve never built one): digital_RevB_Board, digital_RevB_Schematic

Wow, this post got way longer than I ever thought. Here’s the link to the next post where I talk about the details of the analog circuit: https://soldernerd.com/2014/11/16/arduino-ultrasonic-anemometer-part-3-analog-circuit/

Arduino Ultrasonic Anemometer Part 1: Getting started

This is the first of a series of posts to follow. I will describe my attempts to build an ultrasonic wind meter (anemometer) based on an Arduino Uno. By the time of writing, I have a working prototype but it will take me a while to catch up in this blog. So this is just the first post – more will follow soon.

Click here for an overview over this series of posts on the anemometer project: https://soldernerd.com/arduino-ultrasonic-anemometer/.

The finished analog part of the circuit.
The finished analog part of the circuit.

Let me quickly outline the project: My aim is to build an ultrasonic anemometer based on a Arduino Uno board. Now what’s an anemometer? That’s just a fancy name for a wind meter. I want to be able to measure both wind speed and wind direction with high accuracy. Most wind meters are of the cup or vane variety. They turn wind into mechanical motion and then measure that motion to calculate wind speed and possibly direction. An ultrasonic anemometer on the other hand sends and receives ultrasonic pulses and measures the time-of-flight. From the time-of-flight (or the time difference, depending on your approach) you can then calculate the wind speed in a given direction. Add a second pair of senders and receivers at a 90-degree angle and you get both wind speed and direction. As so often, wikipedia gives a nice overview/introduction to the subject: http://en.wikipedia.org/wiki/Anemometer

A preliminary setup to test the basic functionality of my circuit
A preliminary setup to test the basic functionality of my circuit

Surprisingly, there seem to be very few people out there who have done this before. Basically, there is this one brave guy named Carl who has built such an anemometer from scratch and put all the relevant infomation online.His project was published on hackaday.com and this is where I found it: http://hackaday.com/2013/08/21/ultrasonic-anemometer-for-an-absurdly-accurate-weather-station/. All of his documentation can be found here: https://mysudoku.googlecode.com/files/UltrasonicAnemometer.zip. This material makes for an excellent starting point if you want to build your own. I’ve looked carefully at Carl’s schematics and have copied many of his ideas. I did end up changing quite a few things and will explain my reasons for doing so but the general approach is very much the same. Many thanks for sharing this with us, Carl.

The basic idea is simple: You send a ultrasonic pulse and measure the time until it arrives at a receiver located in some distance. Ultrasonic transducers often operate at 40kHz and so do mine. A transducer is a device capable of both sending and receiving a signal. It’s the kind of thing cars uses for their parking aids, telling you if there is an obstacle and at what distance.

The board for the digital part waiting for the components to be placed and soldered.
The board for the digital part waiting for the components to be placed and soldered.

In a 2-dimensional anemometer such as here, you will have 2 pairs of transducers for a total of 4. Let’s call them North, South, East and West for simplicity. You need to be able to send and receive pulses in all 4 directions: N->S, S->N, E->W and W->E. Not all at the same time but one after the other.

So you will need some kind of circuit to route your signals from and to any of the transducers. For example you want to send from the West transducers and receive from your East transducer or vice versa. Let’s call it the digital part even though the received signal is analog in nature. The PCB without components just above is the basis for this digital part. If you wonder who or what Jingling Ding is: That’s the name of my step daughter who helped me drawing and laying out this PCB in Eagle.

You will then need some more circuitry to process the received signal. This circuit is shared among the 4 transducers so only one can be listening at any point in time. That’s why the digital part needs to route the signal from the correct transducer to this signal processing circuit. The received signal is analog in nature and will be very weak compared to the transmitted one. So you will need quite a bit of amplification first. But this analog signal cannot directly be used by your arduino to measure the time of flight. You need some digital signal(s) that you can measure using the timer(s) on the arduino’s Atmega328 chip (in case of the Arduino Uno). Let’s call this the analog part. That’s what’s shown on the photo at the top of this page.

In my next post I will go through the details of the two circuits. Click here for the second post: https://soldernerd.com/2014/11/15/arduino-ultrasonic-anemometer-part-2-digital-circuit/

Switch debouncing using 74HC14

_MG_0978

This was one of the first PCBs I ever made myself as well my very first attempt at soldering SMD components. So if you were wondering why some of the copper on the right has not been removed – that’s why. At that time, I was not even using Eagle yet but some software called Sprint Layout. But this post is not really about this unimpressing board but about proper debouncing. Something I feel strongly about 😉

_MG_0980

As opposed to many people out there, I still prefer to do all my debouncing in hardware. Yes, of course you can do debouncing in software and sometimes you may have to but if you have a choice, debouncing in hardware will generally yield better results and reduces software complexity. Most of the time, my switches will directly trigger an interrupt on a microcontroller so you really want to avoid false triggering. All that context switching associated with an interrupt adds quite some overhead compared with just reading an input pin so there are performance implications of this as well.

_MG_0981

Jack Ganssle has written a really nice paper on this. It can be found here: http://www.eng.utah.edu/~cs5780/debouncing.pdf. He has run some experiments with a wide variety of switches and explains how to deal with them in practice. What I was doing here follows the recommended approach from Jack’s paper: You take a switch and a pull-up resistor, run the resulting signal through an RC filter and add a schmitt-triggered buffer. Cheap, simple and works perfectly every time.

Here are the signals you get when the button is pressed (top) or released (bottom). Yellow is the output of the RC filter and red is the (digital) output of the schmitt-triggered buffer. Note that the 74HC14 is an inverting buffer so the output signal goes from low to high when the button is pressed.

Debounce_Eingang_LowHigh

Debounce_Eingang_HighLow

The time constant of the RC filter and therefore the resistor and capacitor values are quite uncritical if you are working with simple switches as here. As you can see in the scope screens above, it takes around 20ms from when the button is pressed (or released) until the output signal changes. That’s more than enough time even for a pretty poor switch to have stopped bouncing. At the same time, that’s instantaneously as far as the user is concerned. Anything up to 50ms feels instantaneous even to impatient humans.That leaves 30ms for the microcontroller to take the desired action. If that’s enough depends of course on what you are trying to do but generally that’s plenty of time.

Here’s yet another screenshot. This time it’s the digital output (red) as well as the same signal in analog. This is just to convince you that what your are getting is really a clean output signal. It goes high to low in less than 10ns. That’s less than one-sixth of a clock cycle on a typical (16MHz) microcontroller. Yes, there is some ringing but there always is if you look closely enough. In this case it’s well behaved with less than 700mV pp amplitude and dies out within 50ns or so.

Debounce_HighLow_10ns

Getting the balance just right gets much trickier when you’re using rotary encoders. You won’t press a pushbutton 100 times a second but it’s not uncommon to get signals from an encoder with only a few milliseconds between them. So you have to think carefully about how much debouncing you need. Just a bit too little and you pick up bouncing noise. A bit too much and you start missing pulses.

I’ll share my lessons learned on that, too. But that’s for another post in the future.

Here you find the Eagle files as well as PDFs of the board and schematic as a zip file.

Programming sockets for PIC microcontrollers

_MG_0957

I regularly use PIC microcontrollers. I’ve tried some Atmel chips lately but I’m still by far most familiar with the PIC16 & PIC18 chip families. As you can see in my other posts, I tend to use SMD components but once in a while I need to program a DIP package.

_MG_0955

I do all my PIC programming using the MikroC for PIC compiler from Mikroelektronika. They also make this MikroProg programmer/debugger that integrates nicely into their IDE.

_MG_0956

So these DIP sockets have a 5x 100 mil header that lets me connect the MikroProg and route the signals to the respective pins of the PIC. Obviously, different chips have different pin counts and pinouts so I had to make a few of them to cover all the PICs I use.

http://www.mikroe.com/

Constant Current Dummy Load

_MG_0942

This is a constant current dummy load. It’s controlled by a PIC16F1936 microcontroller. As you can see, it’s equipped with a 4×16 character LCD display and, less obvious, a rotary encoder with push button. It accurately sets the desired current via a 16bit DAC and reads both current and input voltage with a single-channel 16bit ADC each. Temperature is measured by the microcontroller’s internal 10bit ADC.

_MG_0933

It needs a 6…16 volts supply for it’s own use. That’s what the upper pair of banana plugs is for. It can then burn up to 4.5 amps in the range of 0…22 volts. You can set any current from up to 4.5 amps in 1mA steps via the rotary encoder. By pressing the encoder you can set the ‘sensitivity’ of the encoder. There are 3 ranges: 1mA, 10mA and 100mA per (encoder) step. This way, you can quickly and precisely set any current you want.

_MG_0934

There is a LM35 temperature sensor mounted directly to the heat sink. The temperature is shown on the display as well as used for protective purposes. The software automatically limits the current if the heat sink gets too hot. Using the temperature, current and voltage, it also calculates the die temperature of the two MOSFETs and makes sure their temperature rating is not exceeded. They have a temperature rating of 125 degrees centigrade and a die-to-heatsink thermal coefficient of around 4 degrees/Watt. So with higher voltages and currents it’s entirely possible to blow the MOSFETs even with moderate heat sink temperatures.

_MG_0935

You might wonder what the Xilinx XC9572XL CPLD is doing on there. Well, this was my very first project involving an LCD display, my first project involving a rotary encoder, my first project involving external ADCs and DACs… My first project at a lot of things. So I appreciated having the flexibility to change some of the signal routing in VHDL. All the signals traveling from the rotary encoder to the microcontroller and from the microcontroller to the display travel via the CPLD so I can re-route those signals any way I want. Now the CPLD mainly takes care of the encoder

The 100mil header at the front is a I2C interface that let the dummy load communicate with the outside world. It was added later so i had to run some wires to get access to the I2C bus.

By the way, this is how I got the idea of building a dummy load: http://www.eevblog.com/2010/08/01/eevblog-102-diy-constant-current-dummy-load-for-power-supply-and-battery-testing/

Simple, resistor based Dummy Load

Another afternoon project. Some time ago I was working on a 80 watts 12-to-36 Volts DC-DC boost converter. Not one of my most successful projects but anyway.

_MG_0936

So I needed some kind of load but my home made constant current dummy load can only handle 20-something volts. A few 100 ohms 15 watt resistors were just what I needed. So I took 6 of them and made a simple, single-sided PCB that holds the resistors as well as 6 switches.

_MG_0937

The resistors are upright and have a bit of an air gap between them. That’s important, they get incredibly hot with 36 volts accross them. I know, I had to learn the hard way 😉

_MG_0938

Together with the aluminium front it has a nice weight for its size and with it’s silicone feet it sits firmly on the bench.

_MG_0939

Variable Voltage Power Supply using a LM317

_MG_0929

A classic afternoon project. I was in need of a variable voltage and didn’t have a proper lab power supply available. But I did have a solid 12 volts from an old computer PSU. So I built myself this little thing.

_MG_0930

It’s really nothing more than a LM317 in a TO220 package with a pot, two capacitors and banana jacks. It measures about 65x55mm and has rubber feet so it sits nicely on the bench. All the parts I found laying around here. The little heat sink can handle 5 to 10 watts without getting overly hot.

_MG_0931

Over a short period of time you can burn quite a bit more so you can draw up to 1.5 Amps (the LM317’s internal current limit) from anywhere between 1.25 and 10 volts when connecting it to a 12V supply.

_MG_0932