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/.
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.
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.
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.
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.
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/