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

Xilinx Prototyping Board

Some time ago I wanted to try out programming CPLDs in VHDL. I was entirely new to both of those topics and I didn’t have a real need for a CPLD at the time. So I built myself a nice little prototyping board for the Xilinx XC9500XL complete with some push buttons, LEDs a 7-segment display and a PIC16F688 used mainly as a clock source.

_MG_0915_1

As you can see, I’ve used a socketed PLCC44 package. The CPLD comes in two versions: XC9536XL with 36 macro cells and XC9572XL macro cells. 36 cells won’t allow you to do very much I had to soon find out and even 72 can be quite limiting depending on what you are planning to do. Prices don’t differ that much so I recommend you get the 9572 straight away.

_MG_0916

Notice that I’m using the 3.3V version in this project. There is a 5V version of these chips as well and many of the DIY projects you find on the web use them. But they are increasingly hard to find and might cost several times more. When I was doing this project, Farnell was selling them around $15 in small quantities compared to maybe $4 for the 3.3V version.

The board is powered from anywhere in the range of 4 – 16V so you can easily power it from USB. All the CPLD pins are accessible from the 100mil headers you on the top and the bottom of the board. On the right you can see the programming headers for the PIC and the CPLD, respectively. I’ve also included a few 3.3V ‘outlets’ that I can use to power other boards connected to it.

Here’s a list of related projects:

http://bitcycle.org/electronics/1st_CPLD_project/

http://hackaday.com/2008/12/11/how-to-programmable-logic-devices-cpld/

http://startingelectronics.com/projects/xilinx-CPLD-board/

http://dangerousprototypes.com/docs/XC9500XL_CPLD_breakout_board

 

 

DIY Electronics