Last time I’ve presented my new design for the ultrasonic anemometer driver circuit. So now it’s time to see how it performs. If you’re new to this project you might want to check out the overview page or at least my last post.
By now I had the time to build up the board and to do some testing. My main struggle was with the power supply. The linear regulator LM2931 comes in both fixed and variable voltage configurations. Unfortunately there is absolutely no way to tell them apart from their markings. So I accidentially used the variable voltage variant resulting in an almost 12 volts output voltage blowing up half of my circuit. I later noticed that I was out of 5V parts alltogether and had to use a LM7805 in a TO-92 package as you can see from the photo below.
After having fixed the blown-up components, the circuit worked quite well. The first thing I did was to write some basic software for the PIC16F1936 to output a burst of40kHz PWM pulses every 2 milliseconds. After every burst the Axis and Direction signals are changed so the transducers take their turns in a clockwise order (North-East-South-West-…). The screenshot below shows part of such a burst sent from the South transducer. Note that the signal is a precise 40kHz with a duty cycle of 50% as it should be.
Below you see a full burst of 10 pulses. The number of pulses to send will be something to optimize in software once the hardware is finalized.
From the following screenshot you can nicely see how the transducers are selected by means of the Axis and Direction signals. The microcontroller always outputs its PWM burst from the same pin. All the signal routing is controlled by means of these two signals so there is not much of a software burdon.
So sending pulses is easy and works well. But that’s the easy part. Now let’s see how the circuit performs in receiving and amplifying singals.
Below you see a complete send-receive cycle. A number of pulses is sent (red) and somewhat later received (yellow) and amplified (green). Notice the different scales. Despite being only slightly larger in amplitude on the screen, the ampified signal is about 15 times larger in amplitude. Remember from the last post that the gain is controlled by a pot so this is just a temporary setting.
The distance between the transducers is 230mm so the time delay should be roughly 700us. Looking at the screenshot below this seems to be the case.
Note that I’m sending much more pulses this time and that there is a larger-than-usual gap after the 18th pulse. As mentioned, I’m still experimenting with how many pulses should be sent and how. Here I’ve sent 18 pulsed plus 7 more pulses 180 degrees out-of-phase. My hope was that the received signal will decrease more rapidly in amplitude after reaching its peak which would make the peak easier to identify. This is still work in progress but I think this might be a simple way to improve the reliability of this wind meter.
Below you see an overview over a round of measurements. Note how different transducers produce different patterns. There seems to be quite a bit of manufacturing spread between them even though they are presumably from the same production lot.
Now let’s look at these signals in a bit more detail. There is a significant amount of noise present in the received signal but it seems to be largely gone after the amplifier stage. The amplifier is a single op amp with a DC-coupled input and a pot acting as resistive divider setting the gain. That’s about as simple as it gets. There are no filters or anything up to this point. But the output looks nice and clean.
Here’s a close up making this even easier to see. There are narrow spikes present in at the input but the limited slew rate of the op amp seems to filter them all out. So the output is clean as a whistle without any filtering. Much better than expected. Wow.
If you’ve read my last post you know that there is a second op amp which I intended to use for a active band pass filter. But there seems to be no need for that at all. Simplifies the circuit, saves an op amp as well as quite a bit of board space. Great.
Nevertheless you might have noticed that there is a wider and much larger spike in the received signal every time the axis and direction signals change. The cause of this is most likely charge injection through the p-cannel Mosfets that are used as switches between the Mosfet drivers and the transducer.
Being much slower and wider than the noise we’ve looked at so far, this spike makes through the amplifier with only slight attenuation. The good thing is that this spike occurs when we switch from one transducer to the next. That’s a time when we won’t want to look at the received singal anyway. We haven’t even sent any pulses yet. The spike abates long before the received singal starts being of interest. So I’m confident that this spike causes no real harm and can savely be ignored.
All in all I’m positively surprised how well this design has performed. I’m obviously getting a much stronger gate drive of 12 volts as opposed to 5 volts with my old design. And not only that. The Mosfet drivers used can source and sink several amps so there is reason to hope that the signal is not only larger in amplitude but also cleaner and more square. I’ll have to look at the shape of the wave form at the transducers in more detail to verify if this is really the case.
But I’m most surprised of how well the simple op amp performs. Using this super-simple setup I’m getting an output signal that’s just as clean as what I got from the rather complex two-stage tuned common emitter amplifier. No need to tune this thing making it much more production friendly. And it saves plenty of board space as well.
So this is the way to go I think. The next step will be to come up with some circuitry to process the received and amplified signal. I have some ideas in my mind and will elaborate on them shortly. But first I’ll take a closer look at the new lasercut mechanical design.
It’s been about one and a half years since I started out with my ultrasonic anemometer project. Like others before me I had to notice that this a much more demanding project than it appears to be at first. After countless hours of development and testing I have built this Arduino shield. It worked but the reliability of the measurements was never what I had aimed for. The problem was mainly how to figure out the absolute phase of the received signal. So the measurements were always precise – but sometimes off by a full wavelength. Then I was more or less inactive for most of 2015, mainly due to personal reasons. So the project was kind of stuck but i kept (and keep) getting a lot of encouraging feedback from you folks. I came up with new circuit ideas and decided to pretty much start with an entirely new design and to re-think each and every design choice I had made back then.
I will now outline and explain my new design for the send/receive circuit. So the board we are looking at today will handle the signal routing from the microcontroller to the individual transducers and from the transducers back to the amplifier where it is cleaned-up and amplified. There’s the circuit explained step by step.
Powerful 12V drive
My last design drove the transducers from a 74HC126 line driver / buffer. This chip has tri-state outputs which made it easy to switch to receive mode by releasing the respective transducer. It also has a strong (for a logic IC) output drive of up to 125mA to switch the capacitive load that the ultrasonic transducers present.
Unfortunately, the drivers only provided a 5V amplitude. Even worse, a more contemporary design would probably operate from a voltage of only 3.3 volts potentially making things worse in the future. So I decided to use a pair of Texas Instrument LM5111 Mosfet drivers. They can handle up to 18 volts so I can run them at a 12 volt input voltage directly. Mostet drivers are designed to drive large capacitative loads so they typically have powerful outputs. Specifically, the LM5111 can sink and source 5 and 3 amps, respectively. Thats more than any logic chip could ever provide. They also share a industry standard pin-out so they are easy to replace should the LM5111 not be readily available from your preferred supplier.
Discrete Mosfet Switches
The downside of using a Mosfet driver is that they lack the handy tri-state output. So I had to find another way to release the transducers for receive mode. Readily available integrated switches and multiplexers don’t have the low Rds-on that we need here. And they are definitely not happy if you’re trying to pass 5 amps through them. So I decided to use a discrete p-channel Mosfet for each transducer. With the gate at -5V the Mosfets conduct in the 0 to 12V range of the driving signal with a on-resistance of far below 1 ohm. So the strong drive of the LM5111 is not forfeited. With the gate at +5V the Mosfet is not conductive for signals a few volts around ground. So the receiving transducer can swing freely, unaffected by the LM5111.
Op-Amp Amplifier and Filter
The last design used a tuned two-stage common emitter amplifier. I found the design quite beautiful with nice biasing and everything but there were severe drawbacks. Mainly, the LC tank had to be tuned carefully to have it’s center frequency at 40kHz. Coils especially have large tolerances, plus/minus 20% is quite typical. This makes it at least difficult to produce any quantity of these things efficiently. It also takes some test equipment to see if your resonant frequency is correct so the design is not really suitable if you want to distribute it as a kit.
So this design uses a dual op amp at its center. I’ve decided to use a Texas Instrument LMC6482. This is an affordable precision OpAmp with rail-to-rail inputs and outputs that can run from a wide range of supply voltages. One of its main advantages for this application is its slew rate of 1.3 volts per microsecond. This is not especially much or especially little. But it’s just right for us. And this is why: A 40kHz signal with a peak-to-peak amplitude of 10 volts needs a maximum slew rate of 1.25 V/us. So 1.3 volts is enough when operating from a +/- 5V supply. And because it is just enough it will quite effectively block any high frequency noise/spikes that might be present at the input. This is a trick I’ve learned from Horowitz & Hill’s classic Art of Electronics. It’s my first time to use it so I’m exited to see how it works.
For now, the gain of the amplifier is controlled via a pot. Future designs will probably have a fixed gain once I’ve figured out how much gain we need.
Active Bandpass Filter
Just in case the slew rate limitation of the op amp isn’t enough to get a nice, clean output signal I have planned ahead and used the second op amp from the dual LMC6482 for an active band pass filter.
I’ve played around with an Excel spreadsheet and LT Spice for a few hours trying to find suitable values for the various resistors and capacitors. I’ll do some more experimenting once I can test the results on the real circuit. So don’t pay too much attention to the compoent values of this filter for now.
Signal Routing via 74HC4052 Dual 4-Channel Multiplexer
This is something that hasn’t changed much. The 74HC4052 has already been part of my last design. I’m now using two of them, one for transmitting and one for receiving.
The first half of the transmitting multiplexer (IC2 in the schematic) takes the PWM signal from the microcontroller and sends it to the correct Mosfet driver according to the axis and direction signals that control which transducer is sending and receiving. The second half of that IC releases the receiving transducer located opposite of the transmitting one. It does so by providing +5V to the corresponding p-channel mosfet. Pull-down resistors to the -5V rail ensure that the mosfets are conducting when not actively turned off. The +5V release signal can be controlled from a microcontroller pin. Not sure if we need this functionality so a future version might just connect this signal directly to the positive rail.
The first half of the receiving multiplexer (IC1 in the schematic) routes the signal from the receiving transducer to the amplifier input. Note that there are 10k pull-down resistors on the floating leg of the transducers so the received signal is centered around ground. In order to avoid cross-talk, the second half of IC1 actively grounds the transmitting transducer’s signal. In order to make this possible, there are 10k resistors in the signal path before the multiplexer. Given the very hight input impedance of the op amp this should not have a negative effect.
This circuit runs from a 12V input voltage that is directly used for the mosfet drivers. For everything else, a linear regulator generates a +5V rail. An ICL7660 inverts this voltage to generate a -5V rail. The multiplexers and the op amp then run from this +/- 5 volt supply. This is somewhat of a complication compared to the sleek plus-five-volt-only approach that I took with the Arduino shield. But this gives us a much stronger 12V drive on the transducers even if a future design will run on +/- 3.3 volts. And the split supply allow for easy control of the discrete p-channel mosfet switches and ground referenced signals in the receiving circuit.
I’ve included a PIC16F1936 on the board. No, I don’t have any plans to use a PIC16 in my final design. I just thought it is convenient to generate the singals necessary for testing right on the board. I do consider using a dedicated on board microcontroller in my final design. I see several advantages of doing so. The design would no longer be Arduino specific. You could still interface it to an Arduino using a standard I2C or SPI interface. But you could also interface it to a Raspberry Pi or just about anything else. That would make it much more flexible and versatile. And even if you interface it to an Arduino the Arduino is free to focus on other things than handling the technical details of running the wind meter. With the shield one had to pay close attention not to upset the timing by running other code. So a design with an on-board chip would be easier to use as well. Cost would not really be an issue since powerful microcontrollers are available for around 2$ even in modest quantities. Feel free to share your thoughts on this. I’m currently looking at different architectures but no decision has been made yet.
This is it for now. In my next post I’ll share my test results with this circuit. The Eagle files and PDFs are available as a download on the project overview page. As always I very much appreciate your comments and suggestions.
In my last post I’ve described the design and construction of my LED dimmer project. This project here is similar but a bit more involved. It controls RGB LEDs so it can not only change the brightness but also the color of the light. Instead of a simple pot it used a pair of rotary encoders with push buttons. One controls the brightness, pushing its button turns the light on or off. The other changes the color, pushing its button toggles between color and white.
There’s also a I2C interface included this time. I originally had the idea to hook this thing up to a Raspberry Pi and so be able to control the light from my computer or cell phone. I did establish an I2C connection to the RPi and it all works but it’s now installed as a stand-alone solution.
Since we’re now controlling RGB LEDs we obviously need three independant PWM outputs, one for each for red, green and blue. But let’s go through the circuit step by step.
The board is powered from a fairly powerful 12V supply that is always on. A LM2931 turns this into a microcontroller-friendly 5V. But if we want to connect this board to a Raspberry Pi we need to match the RPi’s 3.3 volts operating voltage. Apart from hobbyist projects there aren’t many microcontroller circuits running at 5V nowadays. Most of the PIC16Fxxx family of chips still handle 5 volts but this is becomming more and more of an exception. So in order to be compatible with the rest of the world this board will need a way to adapt it’s voltage.
What I’ve done here is the following: The board has it’s own 5V regulator and you can power from that using a jumper on the I2C header. On the other hand, if the board is connected to a Raspberry Pi over I2C, it will just freeride on the RPi’s 3.3V operating voltage. Since the board is only drawing a few milliamps at 3.3V this is perfectly fine. The RPi specs allow for 30mA or so to be drawn in this fashion.
I’m using a pair of Bourns PEC11R-4215F-S0024. These are 24 steps-per-rotation encoders with a push button that I’ve used for other projects before. I’ve made it a habit to debounce switches and encoders in hardware rather than having to worry about it in software. There’s even an entire post just on that subject: https://soldernerd.com/2014/11/12/switch-debouncing-using-74hc14/.
So all 6 signals comming from the encoders are first RC filtered and then run through a 74HC14 schmitt-triggered inverter and reach the PIC nice and clean.
I’ve once again used a PIC16F1936 but this is entirely uncritical since most microcontrollers come with the features needed here. We mainly need 3 10-bit PWM modules and an I2C interface if we want to connect to the Raspberry Pi.
The PIC is running at 32MHz using its internal oscillator which gives us a maximum (10-bit) PWM frequency of 31.25kHz which has proved adequate in my last dimmer project.
I once again used the inexpensive yet powerful Infineon IPB136N08N3 N-channel MOSFETs. Since I have to drive 3 of them this time I need two LM7111 dual MOSFET drivers. As opposed to last time when each output had its own capacitor, they now all share a 1.5mF electrolytic cap.
As so often, most of the interesting stuff happens inside interrupt service routines (ISRs). This one serves two tasks:
Read the input from the rotary encoders. Every time one of these input signals changes, an interrupt (interrupt-on-change, IOC) is triggered and the ISR calculates the updated values for brightness and color and sets an update flag so the main code knows that something has changed.
Send and/or receive data over I2C. The PIC is configured as Slave so it won’t do anything unless some other device attached to it will request or transmit data. The ISR just technically handles the sending and receiving o data. It just fills a receive buffer or sends data from a send buffer. It is entirely up to the regular code what should be sent and how received data is interpreted.
As I’ve mentioned I’m not using the I2C interface at the moment so the implementation is somewhat basic. Data can be sent to the board and it is stored in a recieve buffer but nothing is not processed. When asked for data it transmits up to 11 bytes indicating it’s current state of operation such as brightness of each color channel and some more data.
There is also nothing preventing the content of the buffer from being changed while a transmission is in progress. So if you’re planning to really use this I2C feature you probably want to improve it somewhat but the code (download link at the end of this post) gives a good, working starting point. If you need help, just ask.
Controlling the outputs is not that challenging. Its jus 3 10bit PWM modules running 120 degrees out-of-phase to smoothen the current seen at the input. Again, the LM7111 I’ve used are of the inverting type so the duty cycle has to be inverted in software.
I’ve used a lookup table for brightness (only 32 brightness levels this time) and color. I’ve defined 24 colors that make a nice color circle. You can turn the color encoder infinitely and just loop through the colors defined in the lookup table. When you press the button on the encoder, the color changes to plain white but the color is remembered so when you press the button again the same color comes back. Brightness works in a similar way: press the button and the light goes off, press it again and the light is back with the same brightness as before. Overall, this makes a quite intuitive user interface.
Testing and Troubleshooting
Acoustic noise was not an issue this time. I started with 31.25kHz switching frequency and 120 degrees phase shift right away. Apart from that the power level is lower, more like 70 watts maximum. And I was using a different supply that might be less susceptible to acoustic noise. don’t know, haven’t tried.
Mass connections have proved to be a problem, though. Usually I take great care during board layout to make sure all components have excellent ground connections. Together with the generous use of 100nF ceramics decoupling capacitors this prevents lots of problems before they even appear. Thank you John Catsoulis (http://shop.oreilly.com/product/9780596007553.do) for stressing this point when I started designing my own circuits. You might have noticed that just about every IC on any of my designs has its own ceramic cap on each of its power supply pins. That’s thanks to John and it has served me very well.
But back to the problem: It seems that this time I’ve been a bit sloppy with my ground connections around the two MOSFET drivers and the encoder on the right. They’re not that bad but aparently not good enough. The LM7111 are quite powerful. Up to 5Amps peak current according to the datasheet. And together with my not-so-great ground connections that was enough to get false triggering from that encoder. A few wire bridges improving the ground connections solved that problem. I’ve already fixed that problem in Eagle so the files available for download should be fine.
There was also another problem: It was impossible to turn the green (middle) channel off entirely. No matter what I did in software, the green LEDs always stayed on if only a little bit. I looked at the PWM signal from the PIC on a scope and there was a slight glitch every full PWM period, aparently when the PWM register overflows from 1023 to 0. The other two channels (red and blue) didn’t suffer from this problem.
As I said, I have to correct for the inverting nature of the LM7111 in software. The enhanced (ECCP) PWM modules can do this automatically. But there are only two if them in a PIC16F1936 so I had to use a regular (CCP) module for the green channel. So in order to turn the green LEDs off the duty cycle has to be 100%. And that seems to be impossible without that little glitch.
I first tried a pull-up resistor on that PWM signal but that didn’t help. The pic seems to actively pull that pin low. So I resorted to a 10pF cap to ground which finally solved the problem.
Since the board is installed hidden in some kind of bookshelf I didn’t make a new pretty board with all these fixes already in place. But I’ve now been using it for two months or so and it works perfectly every day.
I’ll finish this post with a few impressions of the final product and the download link below.
As always, here you find the Eagle Files, PDFs of schematic and Board as well as the code.
I have recently moved to a new apartment and was looking for a PWM dimmer to control some 12V LED strips. I thought that should be easy enough nowadays but it proved more difficult than I thought. All I found either didn’t meet my requirements, were uggly or expensive. So I decided to build my own, tailor-made to my needs.
Handle 100W @ 12Volts comfortably
Controlled by a simple on-board pot (no remote control or the like)
No acoustic noise
Fine-grained control down to very low brightness levels
I’ll go through these requirements one-by-one.
Handle 100W @ 12Volts comfortably
My LED strips suck up a bit more than 20 Watts per meter and there is a maximum of 4-5 meters of LED strips per dimmer so I need a power rating of around 100W. If you do the math you’ll find that there will be a maximum current of about 8.3 amps.
I don’t want this thing to get hot nor do I want to put a heat sink on it. So the total power dissipation in the dimmer should stay below, say, 1 watt. So if we use a single FET, we need a Rds-on of 14.5 milliohms. Thats not a lot but there are inexpensive MOSFETs that meet this requirement. And we can always parallel two or more of them if necessary.
And yes, there will also be some switching losses but they should be low given the modest switching frequency of an application like this.
Controlled by a simple on-board pot
This is most likely the simplest way of controlling a dimmer but it’s surprisingly hard to find. A lot of commercially available dimmers come with IR remote controls nowadays. And some of the higher quality models expect a 0-10V control signal which means that you have to use an external pot which you have to mechanically attach somewhere. I would like everything on a single PCB to keep things simple.
I needed 3 of these things so cost was a factor, too. All the nicely-made dimmers I could find were priced at $50 and uppwards. Not that bad but I figured that I could make my own for a small fraction of this, perhaps $10.
No acoustic noise
We all know those dimmers that produce audible humming. Especially when dimmed somewhere half-way down. I hate it. Drives me crazy.
This proved to be more difficult to archieve than I thought. More on this later.
Fine-grained control down to very low brightness levels
This is where most products fail miserably. Most of those remote-controlled things only have 8 brightness levels. And just about everything I found works linearly which makes very little sense if you ask me. We humans perceive brightness logarithmically, rather than linearly. So going from 1% to 2% seems the same as going from 50% to 100%.
Linear control will not give you fine control at the lower end. Ideally, you want to have an exponential transfer function from pot position to PWM duty cycle to compensate for the logarithmic nature of the human vision. I found the easiest way to do this was using a microcontroller. Furthermore, the ability to do all of this in software enables you to play around with it and find a transfer function that you’re happy with.
High granularity at the lower end also means that we need quite a bit of PWM resolution. The common 8-bit resolution translates to about 0.25% per step. Going from 0.5% (wich is about what I mean by very low brightness) to 0.75% is already quite a step. Many microcontrollers are capable of 10 bits which is 4 times better and probably good enough.
At the center of my design is a 8-bit PIC microcontroller, a PIC16F1936. There’s not much special about this particular model, it’s just a type I’ve used several times before and still had some on stock.
A LM2931 provides the PIC with 5 volts from the 12 volts input voltage. I use the LM2931 as my standard 5V regulator. It’s pin compatible with the legendary 7805 but survives input voltages in the range of -50 to +60 volts making it very robust against transients.
The PIC controls a LM5111 dual FET driver that provides a powerful 12V gate drive to a pair of Infineon IPB136N08N3 N-channel MOSFETs. This is the same transistor that I’ve recently used for my Arduino Solar Charger Shield. Its an inexpensive (< $1), large SMD type with an exellent Rds-on of 11.5 mOhms.
There are several variants of the LM5111. It comes in inverting and non-inverting configurations as well as combinations of inverting and non-inverting. At Farnell, the the inverting ones were by far the cheapest so that’s what I’m using here. It doesn’t really matter since you can change the polarity in software as needed.
Why am I using two FETs despite the fact that one could easily handle the entire current? First, I’m driving two LED strips with this dimmer and using two transistors simplifies the layout so I have two outputs exactly where I need them. Secondly, the LM5111 is a dual FET driver anyway so I get the second gate drive for free.
I’ve provided each output with a generous 1.5mF capacitor in order to shield the supply from the ripple that is inevitably produced by the PWM. I’ve also taken care to use a cap with low serial resistance (ESR) and a high current rating. The Panasonic FR series fulfills both of these requirements while being good value for money. I thought this should be enough to avoid excessive ripple and therefore also acoustic noise.
The input to the PIC comes from a quite nice 2 kOhms pot that I’ve recovered from some scrap. There is also a voltage divider to measure the 12V input voltage. The idea was to only enable the output once the input voltage has stabilized but I found this to be a quite unnecessary feature when programming the PIC.
I’ve built the two different versions of this dimmer. The schematic is exactly identical for both of them, they only differ in their physical layout and board dimensions. I’ve just tailor-made them to their specific application so the pots are located in a handy position and the outputs are exactly where I need them.
Software and Testing
My first version of the software measured the voltage from the pot using the on-chip ADC and outputed an identical 2kHz PWM signal on both outputs. 2kHz should be enough to avoid visible flicker and seemed a reasonable choice. Everything worked but the power supply made quite a bit of noise over most of the brightness range. Worse than any commercial design. Even worse, there was an awful lot of flicker. Ouch.
Looking at the power supply output / dimmer input voltage on a scope if became clear that the two 1.5mF caps still allow too much ripple at this frequency.
The first thing I tried was running the two outputs out-of-phase. Since I’m using two FETs I have two independent outputs. So I can run them 180 degrees out-of-phase. Now, at duty cycles below 50% it looks like I’m only driving a load half the size with a frequency and duty cycle twice as high. At precisely 50% duty the supply even sees a constant load at its output since exacly one LED strip is on at any point in time. At duty cycles above 50% the on-times overlap so the load only varies from 50% to 100% and with twice the frequency. As you can see from the scope screenshot below, this already helped a great deal but the problem was not yet resolved. So the natural thing to do was to increase the PWM frequency.
At 8kHz, things already looked (and sounded) much better. Ripple and acoustic noise were much reduced but the supply was still audible at least in a quiet environment.
So I moved the PWM frequency up as far as i could. Given the PIC’s 32MHz clock and a 10 bit resolution this was 31.25kHz. Now every last bit of audible noise was gone. Finally.
I then noticed that the phase shift was 176 degrees as opposed to the intended 180 degrees.
Not that this makes much of a difference in practice but I solved it anyway. I’ve implemented this phase shift by starting one PWM module at 128 and the other at 0 (we’re only talking about the 4 most-significant bits here, so the maximum is 255). The two instructions are on successive lines in my C code but 3 clock cycles are needed to process each of them so they are not enabled at the precisely same time. Starting the first PWM module at 131 has solved the problem as you can see below.
With these changes in place the flicker mentioned previously was also much reduced but had not yet disappeared. Looking at the voltages on a scope for a while the problem became clear. I was measuring the voltage from the pot at fixed intervals that had no connection with the switching frequency. So I was effectively measuring at random points in time.
I said that the input voltage now showed much less ripple but some ripple is inivitable. Some of that ripple is likely to somehow feed through to the voltage from the pot. That introduced noise in the value measured by the ADC which lead to variations in the duty cycle which was noticable as flicker.
I did two things to resolve this. First, I’m generating an interrupt signal (from the same timer as I use for the PWM) every 64 PWM cycles. In the corresponding interrup service routine (ISR) I read (and save) the ADC value and start a new conversion. This way I’m always measuring at the same point during the PWM cycle. So the effect of the ripple should be similar every time. I’m also averaging 32 measurements which further helps to smooth the value I’m using to calculate the duty cycle. So flicker is gone as well as you can see below.
Now for the transfer function. My first try was exponential. The problem with that was that it gave away too much of the pot range for very low brightness levels. I played around with this for quite some time and finally settled for a combination of linear (at the very low end of the range) and exponential (for everything above that). Also, two of my dimmers can be fully turned off by turning the dimmer all the way to the left. Their power supply is always on and the light is only controlled by the pot so I need to be able to really turn them off (not only down). The third one has a slightly different transfer function that only allows to turn it down to 2% or so. That one has its power supply controlled by a conventional light switch so I don’t want the pot to completely turn it off.
After all, I’m very happy with the result. There is no noticable power dissipation on the board. There certainly is a bit of dissipation but the board doesn’t heat up noticably so I’d say its clearly below a watt.
The components have cost me around $10 per board. Some stuff like the connectors I have bought a flea markets, they can be surprisingly expensive through regular retail channels. The PCBs are home-made so they have cost me a considerable amount of time but not much in terms of cash.
They are, furthermore, controlled by a simple pot, produce no audible noise and can be finely dimmed just as planned. So I can proudly state that all the requirements have been met.
If you’re in need of a dimmer and have a soldering iron and a bit of spare time I can only encourage you to build your own. It’s not too hard, needs only few components and is very doable on a prototyping board if you don’t want to etch or mill your own board.
As always, attached is a zip file with all the eagle files, board layouts, schematic as well as the software.
When I made the PCB for the stand-alone inductance meter, I erroneously used a SSOP footprint for the microcontroller (instead of the desired SOIC). The PIC is available in a SSOP package (PIC16F1963-I/SS instead of PIC16F1936-I/SO) but I didn’t have any at hand so I simply made a new board with a SOIC footprint.
Apart from the footprint, the SSOP board is identical to what I’ve finally used and is fully functional. If anyone is interested I’m happy to give it away for free – first come, first served.
By the way, I’m building a second inductance meter for my father who has asked me if he could get one, too. It’s technically identical but this time the 3D-printer had orange PLA in it so I used just that.
By pure coincident, the color just about matches the newer Agilent / Keysight multimeters 😉
From a high-level point of view the new software is very similar to the Arduino sketch I wrote for the Inductance Meter Shield (https://soldernerd.com/2014/12/14/arduino-based-inductance-meter/). If you look a bit closer, you’ll notice some differences for several reasons:
This project uses an entirely different microcontroller: A PIC 16F1936* instead of the Atmel Atmega328
This code is written in C (for the MikroC for PIC compiler by Mikroelektronika), not Arduino-style C++
The display I’m using here comes with a I2C interface rather than the familiar Hitachi interface
*: In an earlier version I wrote 16F1932 instead of 1936. Thanks to Ralph Doncaster for pointing this out to me. By the way, Ralph has his own blog at http://nerdralph.blogspot.ca which I regularly enjoy reading.
I’ve noticed that the MikroC compiler is not very popular among hobbyists but I like using it. It’s entirely free as long as your compiled code does not exceed a certain size. You can use any features, any library, just anything for free when you’re getting started. Yes, once your projects get bigger you’ll run into the limit and will have to buy a license but it was worth the price to me.
As expected, the I2C display took me some time to get used to. It’s a MIDAS MCCOG21605B6W-BNMLWI (Farnell: 2063209). It seems to use a Hitachi-compatible controller with a I2C interface built on top of it. I like the concept and will probabely use one of these again. If there is a downside, it’s the data sheet. I had to do quite a bit of guessing and trial-and-error to get it working. I had used Hitachi-compatible MIDAS displays before so I had some idea what might work otherwise I might have given up. Examples?
No page numbering. Yes, this is a minor thing but have you ever seen a data sheet without page numbers?
There is a reset pin. As many reset pins, it’s active-low. But the data sheet never says so. Not explicitly, not with a bar accross the RST, not with a ~RST. Absolutely nothing.
It explains some of the Hitachi-functionality in great detail but does not really tell you that this functionality is not accessible over the I2C interface.
Like Hitachi-compatible types, this display needs some start-up time before you configure it. Otherwise it will just not work. But the data sheet doesn’t mention that with a single word.
But it’s all working fine now. The PIC16F1936 has more than enough ROM, RAM and processing power for this meter so don’t expect the code to be optimized in any way. It was just not necessary. It does most of the math in floating-point which bloats the (compiled) code size and is dead-slow on this kind of architecture but it’s still more than fast enough and only uses around half of the available RAM and ROM.
I think the code itself is quite readable but don’t hesitate to ask if you have any questions. Here’s the code as zip: LMeter
The arduino-based meter works well and made a great proof-of-concept. But for everyday use you’re probabely not looking for an arduino solution but rather something that looks and feels more like a multimeter. That’s why I’m following up with this stand-alone version.
So this version is battery powered and comes complete with a 3D-printed case. It uses a mid-range PIC microcontroller, a PIC16F1936. Not that there’s much special about this model, I just happened to have some left from previous projects. I also thought about using a Atmel Atmega328, the same chip that is on the Arduino UNO.
Using an entirely different chip means I’ll have to write the software from scratch. But I felt that the Atmega328 was just too much of an overkill just to measure a frequency and control an LCD. They are quite a bit more expensive than the PIC, CHF 3.70 compared to CHF 1.90 @10pieces at Farnell where I get just about all my chips.
Talking of the LCD: The one I’m using here comes with a I2C interface. It’s blue with a white backlight and 2×16 characters and really tiny. I bought 2 of them years ago because they were small and relatively cheap (around 15CHF) and don’t require so many precious I/O pins of your microcontroller. Somehow I never used them but here their small size makes them a good choice. I/O pins aren’t a constraint here obviously as most of the 28 pins are unused.
I’m not yet familiar with the details of how they are controlled. I had a look at the data sheet and it looks like you send them just about the same commands like with the standard Hitachi compatible ones, just over I2C. But I expect to spend an evening or two figuring out the details.
The case was designed using FreeCAD. As the name suggest, it’s a free (and open-source) CAD design tool. This was only the second time I was using it but I found it quite easy to learn.
I printed the case at the Zürich fab lab (zurich.fablab.ch) on one of their Ultimakers. Was my first 3D-printing project, thank you very much for your support, everyone.
As always, I’ll put all the files online as a zip. So you can download all the Eagles plus PDFs as well as the FreeCAD models. Here it is: InductanceMeter. I haven’t written any software yet but I’ll but that online, too, as soon as it’s finished.