Tag Archives: USB

MPPT Solar Charger Rev C – First Test Results

Over the last few weeks I have been quite busy with my MPPT Solar Charger project. I’ve built up a first board and started writing firmware for it. Since the last version was not too different in terms of hardware I was able to re-use most of that code. But I hadn’t even touched on the whole USB stuff back then so there was still a lot of work to do. While the project is still far from being complete I am happy to say that I’ve made quite some progress. Most importantly, the new design seems to work well and so far I haven’t found any mistakes in the board layout. But let’s go through this step by step.

USB

I regularly find USB communication to be the most complex and obscure part of the firmware. That’s why I like to get that working first and then add all the other functionality later. I’ve started with some sample code that Microchip provides for their PIC1846J50 family of chips. That way I was able to get the my board act as a composite HID (Human Interface Device) / MSD (Mass Storage Device) quite quickly. Of course, that demo application doesn’t do anything particularly useful but it provides a solid basis for adding the functionality you need.

At least for the HID I’ve implemented most of that functionality. I can read all the relevant data such as settings, currents, temperatures, voltages and so on over USB. I can also control all the outputs as well as the actual solar charger remotely. More on that later.

On the MSD side there is still lots to be done. The solar charger successfully enumerates as a USB flash drive and you can read and write data from and to it. But that’s really it. The charger doesn’t care about the files you save there and also doesn’t put any data there.

Flash and EEPROM

This brings us to the next topic: Non-volatile memory. There is both a I2C EEPROM as well as a SPI flash on the board. Communication with the EEPROM is fully implemented but currently its only used to save the time and date. The idea is to save all the settings and calibrations on the EEPROM. That shouldn’t be difficult but I haven’t had time for that yet.

The flash also works just as it is supposed to but the chip I chose turned out to be a bad design choice. It can’t do page erase, only entire 16k sectors can be ereased. That makes it difficult to use since you have to temporarily save the sector’s data somewhere when you want to change only part of a sector. We don’t have that much RAM so we have to save that data to flash itself. That can all be done but it’s just a hassle. Apart from that a sector erease takes time. A loooot of time. So I’ll just juse a different chip when I do the next iteration of the board. For now I’ll just use the first 512bytes of each sector. That’s extremely wasteful but will do for now I guess.

Solar Charger

The actual charger circuit hasn’t changed much since the last version so I expected little trouble in getting it to work. However, I managed to confuse the low and high gate pins in firmware and only found that bug days later when I had already done plenty of damage to the board. By the time I found and fixed the problem I had already killed the input current sensor, the ADC, as well as some of the PIC’s output drivers.

So I built up a second board but only with the components required to test the buck. And much to my relief it works. And it works well. I haven’t done any precise measurements yet but it seems at least as efficient as the last version. I had it running at its rated power of 75 without it getting overly hot. As expected, most power dissipation takes place in the coil so the coil did get quite warm but not hot. The FETs heat up a bit due to their proximity to the coil but otherwise don’t care much. My main problem with these tests was to somehow sink the power at the output without overcharging the battery. My home-made dummy load can sink up to 4.5 amps but not for very long before it regulates down to avoid overheating. I had the charger running at around 40 watts for several hours and it only got modestly warm.

Also, the wave forms on the scope look nice and clean. There’s considerably less ringing and overshoot than with the last version. So the improved layout seems to work well. During the tests so far I have turned the charger on and off at least a hundred times, switched from asynchronous to synchronous mode and vice versa and had it running for about 10 hours. I also pushed it all the way up to about 85 watts where the coil starts saturating and the caps have to handle more ripple than they are rated for. I’m happy to report that during all these tests I haven’t killed a single fet nor any other component (once the firmware was ok). I am confident that it will stay this way.

Synchronous bucks are somewhat dangerous in the sense that it is easy to short the input or output to ground when you’re not careful. My solution to this is having rigorously tested functions for turn-on, turn-off, switching mode and changing duty cycle and then rely only on these functions when implementing different MPPT strategies. If these few functions do what they should you can get away with quite a bit of abuse without damaging anything.

What I also noticed during my tests is that the break-even between synchronous and asynchronous mode is somewhere in the region of 1 amp. That’s about twice what it was with the last version and is thanks to the extremely efficient diode that makes asynchronous mode much more efficient.

USB Charger and power outputs

This is something that has changed quite a bit since so I was eager to see how it performs. I haven’t done any detailed tests but I’m very pleased with it so far. It definitely performs better than the last version. In theory, you should be able to simultaneously pull 2 amps from each of the two USB charging ports. I haven’t done that yet but when fast-charging two cell phones (approximately 2 amps judging from the power it pulls from the battery) it stayed surprisingly cool – unlike the last version.

Also no surprise with the 4 power outputs. I had changed the mosfet drivers and mosfets in order to save board area. Apart from that everything works like before. I can still turn off the drivers when none of the outputs is in use in order to preserve power. All works as it should.

Solar Charger App

Of course, all the USB HID functionality is of little use without some software on the other side, i.e. running on a PC. I’ve spent a lot of  time writing my Solar Charger App over the past few weeks and I can say it’s getting pretty good. I has already proved very useful in testing the buck. Since I can monitor and control everything via USB there is no need to have a user interface sitting on top of the board during testing. That means unrestricted access for scope and multimeter probes. And since there’s so much more space on a PC screen than on the little LCD I can display all parameters simultaneously.

The program is written in C#, using my recently published HID utility and WPF .  I’ve tested it on Win7 and Win10 and runs absolutely stable. It also copes well with ultra high resolution displays where everything gets scaled-up in order to still be visible/readable. The screen shot above gives you some idea of its current functionality. Take the efficiency measurement with a grain of salt, though. The measurements are yet to be calibrated.

The code is available on github: github.com/soldernerd/SolarchargerApp. To compile it you need VisualStudio 2015 Community which is available free of charge.

Measurements

Measurements is another important topic. The newly chosen 16-bit ADC works well. Actually, I don’t feel much of a difference to the 18-bit version used previously. Anyway, the measurements are done with 14-bit precision only in order to speed them up.

 

The readings I get from the two current sensors are surprisingly accurate even without having done any calibration so far. So for now, all measurements have been done with their theoretical (i.e. calculated) multipliers and offsets.

The temperature measurements are done by the PIC directly, using a 2.5V external voltage reference. Both the temperature sensors (one on-board, up to two externally) as well as the voltage reference perform just like they should but I get a lot of noise in my otherwise reasonable measurements. This is quite certainly a software issue. I might not give the PIC’s internal ADC enough time to settle after switching channels or something like that. I’m sure it can and will be solved but I haven’t given this very high priority so far.

Next steps

A lot of work remains to be done. One of the next things I will do is to implement proper calibration for the voltage and current measurements. At the moment, all the relevant constants are hard-coded so I first need to change them being variables, store them in EEPROM and retrieve them from there at startup. In a second step I need to make them accessible over USB. Once that’s done it should be possible to calibrate them in a fully automated fashion. I’ve never done that so far but my multimeter as well as my power supplies can be controlled via USB (or GPIB, respectively).  So I want to write a calibration routine that sweeps the device under test, calculates the proper calibration values and sends them to the solar charger.

Getting the Mass Storage Device working from FLASH is another big thing to do. As reported, the currently 7kb of memory on the flash drive are mapped into the PIC’s internal flash memory. I’ll have to dive quite deep into the Microchip USB code in order to figure out how to change that. I expect to spend a significant amount of time until that works but there’s no way around it in the long run.

Once mass storage works properly I can also start implementing settings as a configuration file on the flash drive. So as an alternative to doing things via HID which requires dedicated software to run on the PC you can also check and change settings by editing a text file residing on the flash drive. The next step will then be to also write measured data to that storage.

Then most of the low-power features are still to be implemented. The most basic stuff is there: The 5V buck for USB charging is turned off when not in use and so are the mosfet drivers for the power outputs and the solar charger. The user interface is also turned off after a certain time of inactivity. But the PIC constantly runs at 48MHz, the USB module is never turned off even when not in use, it never goes into any of the several low-power modes and so on. So at the moment it consumes around 10mA with the display off and 16mA with the display on.

And yes, there’s also more testing to be done on a lot of aspects. The code could definitely use a clean-up once I’m done with it, I also have plans of adding a boot-loader so users can update the firmware via USB… I won’t run out of work any time soon.

The firmware is on github, too: github.com/soldernerd/SolarChargerRevC_Software. It is updated much more frequently than I do posts here so if you’re interested I suggest you track the most recent development there.

The next post on this topic is here.

MPPT Solar Charger Rev C Design

Over the last year or so I’ve designed, built and tested a standalone solar charger. It performed quite well but as with any complex design there were a number of things that needed to be improved.  So I eventually reached the point where I decided to design a revised version. And this is what this post is all about.

Things to improve

Here’s a list of things that I wanted to improve besides fixing the design errors of the old design:

  • Downsize the board and give some thought to how to put the whole thing into a case. Consider carefully where to put screw holes, connectors and the like.
  • Reduce complexity wherever possible. Reduce the number of distinct components.
  • Reduce total component cost without sacrificing performance.
  • Reduce height of the assembled board so that it can ship in a padded envelope.
  • Turn user interface on by means of a logic signal as opposed to turning its power supply on and off. Ability to control the display entirely via I2C, including backlight brightness and reset.

Let’s look at these points one by one.

Downsize the board

I looked around for a suitable case for my solar charger and finally decided on a 90x115mm cast aluminium case. The specific model chosen is available from Farnell at around 10 bucks which I found very reasonable. With the case chosen the size of the board was pretty much given. The inside shape of the case is rather special since there are also mounting holes for the case itself that take away space for the board. However, I decided to keep the board rectangular so it stays universal and is not just made to fit that particular case. That left me with a board of 85x78mm as opposed to 90x140mm of the last version. That’s about half the size in terms of board area so fitting everything on the new board was really a challenge.

The main space saving came from using much smaller mosfets. The model previously used was rather huge in physical size. I’m now using NXP PSMN6R0-30YL in a LFPAK package that is much smaller while delivering similar if not better performance.

The main inductor is also somewhat smaller. I found that the Coilcraft MSS1210 series delivers pretty much the same performance as the MSS1583 while saving some space.

Apart from that I didn’t downsize any of the components in order to keep everything hand-solderable  and hobbyist-friendly. Particularly, all the resistors and ceramic capacitors are at least 0805 in size.

Getting the board made from dirtypcbs.com also allowed me to do a denser layout, mainly by using smaller vias. But I didn’t push it to the limit, all traces are still at least 12 mils (0.3mm) wide with 0.4mm vias and 6 mils clearance.

Now all the power connectors are located at the top of the board with a single 12-pin 200-mil connector. USB is still located at the front and the programming header is at the right edge of the board. External temperature sensors and fan output are now on the left side. The header for the user interface is now located so that the user interface can just be stacked on top of the charger and sits precisely in the middle. There are also mounting holes for the user interface on the charger board.

Reduce complexity

The obvious place to start was the combination of PIC18F26J50 microcontroller with a I2C multiplexer and a port extender. The same PIC family also includes a 44-pin version that allows replacing all 3 chips with a single chip.  I’m now using the top-of-the-line PIC18F46J50. That not only simplifies the board but also the software since we no longer need to care about the mux and which pins are on the PIC and which are on the port extender.

The 4 mosfet drivers for the power outputs have been replaced by 2 MCP14A0153 dual mosfet drivers that also don’t require a reference voltage signal which further reduces complexity somewhat.

The 5V switching converter for USB charging on the last version needed quite a few external components to function. Besides that it got rather hot at 2 amps. I’ve replaced it with a Texas TPS54428 synchronous switcher that is more efficient, uses less external components, delivers up to 4 amps and has a thermal pad at the bottom which helps keeping it cool. The new Coilcraft MSS1048 coil is slightly higher but otherwise the same size and helps keeping power dissipation low.

I’ve tried quite hard to keep the number of distinct capacitor and resistor values to a minimum. You can easily see that the same values such as 10k, 300k and 680k appear over and over again. The only point where there are still a lot of distinct resistor values are the USB charging ports where I’ve tried to emulate an Apple and Samsung charger, respectively. I’m not sure to what extent one can cut corners here without risking that certain devices don’t charge properly.

Overall, the number of distinct components has been reduced from 60 to 47 despite some added features.

Reduce cost

Getting rid of the I2C mux and the port extender already saves some cost. The same goes for the dual mosfet drivers and the downsized inductor. There were some unnecessarily expensive components on the last version. There was an 18-bit ADC that we didn’t really need. The Microchip MCP3428 is a very similar model that only has a maximum resolution of 16 bits and is quite a bit cheaper without making any difference to our application. Another component that was somewhat of an overkill was the voltage reference. Note that the voltage reference is only needed for the temperature measurements. The voltage and current measurements are done by the external ADC that comes with a precise on-board voltage reference. I found the Silicon Labs TS6001 which provides a sufficiently precise 2.5V reference.
I’ve also replaced the large and relatively expensive EEPROM with a much smaller 16kbit Microchip 24AA16 EEPROM in combination with a cost-effective serial Flash (Spansion S25FL208K) with 8Mbit of capacity. This way we get much more storage at a similar total cost while still keeping some easy-to-use EEPROM for configurations and the like.

Reducing height

Since the only overly high components on the last version were the input and output capacitors this was an easy task. I decided that I want to use the same model for both input and output which meant that I needed a 25 volt rating. Maintaining the 10mm diameter and limiting the height to 12.5mm left me with a maximum available capacity of 470uF. The ripple current rating of the new caps is also lower so I now have to use 2 caps in parallel at the input to not exceed this rating at 75 watts.
The caps are still the highest components on the board but only slightly higher than the USB connector, the main inductor and the 200-mil connector. The resulting total height of about 15mm is low enough to comfortably ship the assembled board in a padded envelope which is much cheaper than a small parcel.

User interface

I’ve already presented a user interface that fulfills most requirements listed. However, I still needed to again revise the user interface for two reasons. First, the previous version would not physically fit inside the cast aluminium case. So I had to somewhat taper off the board towards the side so it would fit. I also had to re-locate the mounting holes inward so that they lay on the charger board. Secondly, I need to be able to shut down the user interface without blocking the I2C interface. This was not an issue with the last version where I had a I2C mux in between. So the new  interface now includes a 2-channel bi-directional switch that is controlled via the same signal that turns the interface on and off.

Next steps

I’m looking forward to my ReflowR hopefullly arriving soon so I can build up the board in an efficient way.  As you can see below I have already prepared a setup to apply the solder paste to the board. I have glued three faulty user interface boards to a piece of coated plywood to repeatedly align the board. I have limited experience with reflow soldering but I will hopefully learn quickly and report my progress and lessons learned here.

As you can see from all the photos here the boards have already arrived and I’m excited to try them out. All the eagle files as well as the Gerbers and everything are on github: github.com/soldernerd/SolarChargerHardware.

C# USB HID Utility

Have you ever tried to write a program that connects to some device via USB? I have done so a few years ago and was shocked how much of a pain that is (at least on a Windows plattform). I always thought there should be a nice little library that wraps all those uggly DLL imports, marshalling and COM API calls and offers a nice and clean C# interface to the outside world.

Much to my surprise I found nothing that really did what I was looking for. Now I finally sat down and wrote my own. It’s on github.com under GNU GPLv3 license for anyone to modify and use.

My starting point was the Microchip PIC18F46J50 FS USB Demo Board. This nice little board comes pre-programmed as a HID (Human Interface Device) / MSD (Mass Storage Device) USB composite device and is a great starting point for anyone interested in building a USB device based on a PIC.

Once uppon a time, Microchip also wrote a WindowsForms application to showcase the USB functionality of their microcontrollers and that application (in various versions) can still be found here. It lets you read an analog voltage from the board, tells you if a pushbutton is pressed or not and lets you toggle an LED. Very simple but all you need to get started with your own device and application.

Unfortunately, that code no longer gets maintained and is quite outdated by now. It was created with VisualStudio2010 and .NET 2.0.  And all USB and WindowsForms code is mixed up in a single file which makes it difficult to re-use. It also lacks some functionality such as the ability to list available devices. Apart from that it works very well and stable so I used it as a starting point.

My solution is now based on VisualStudio Community 2015 (which is available for free) and .NET framework 4.6. So you can just download VisualStudio and open the HidUtilityDemo.sln file.

There are 3 projects inside the solution:

  • A WindowsForms application named HidDemoWindowsForms
  • A WPF application named HidDemoWpf
  • A console application named HidDemoConsole

All projects use a common file named hid.cs. This file is what this is all about. The applications mainly just show how to use it and give you a starting point for your own application.

hid.cs is not pretty. 900 something lines of DLL imports, COM object calls and marshalling. It’s C# but it doesn’t look and feel like C#. But it does all the heavy lifting for you and offers a nice, clean, truely C# interface for you to work with HID devices.

You add it to your namespace, create an instance of HidUtility, tell it what device to connect to  and subscribe to the events you are interested in:

// Get an instance of HidUtility
HidUtility HidUtil = new HidUtility();
// Connect to device with Vid=0x1234 and Pid=0x5678
HidUtil.SelectDevice(new hid.Device(0x1234, 0x5678));
// Subscribe to the events you care about
HidUtil.RaiseDeviceRemovedEvent += DeviceRemovedHandler;
HidUtil.RaiseDeviceAddedEvent += DeviceAddedHandler;
HidUtil.RaiseConnectionStatusChangedEvent += ConnectionStatusChangedHandler;
HidUtil.RaiseSendPacketEvent += SendPacketHandler;
HidUtil.RaisePacketSentEvent += PacketSentHandler;
HidUtil.RaiseReceivePacketEvent += ReceivePacketHandler;
HidUtil.RaisePacketReceivedEvent += PacketReceivedHandler;

You can also obtain a list of all available HID devices at any time:

foreach (Device dev in HidUtil.DeviceList)
{
Console.WriteLine(dev.ToString());
}

As the three projects demonstrate, the very same hid.cs file can be included in just about any C# project. There is not a single API call or anything in the remaining files.

Just register some event handlers and your application will be informed whenever a device has been added or removed, when a package of data has been received from the device, when the connection status has changed or whatever else.

So you don’t have to re-invent the wheel every time and can fully concentrate on the application you have in mind, not the details of USB communication.

A word of caution: I am by no means an expert C# programmer. I have tried the applications on 3 different PCs running Win7 and Win10, respectively. They seem to work reliably on any of these. Apart from that the code has not yet been productively deployed and there may well be some bugs and issues. If you find anything that doesn’t work, please let me know and I will do my best to get things fixed and updated on github. Also, please comment on this post if anything needs clarification.

So once again, the code is available for download from github.com/soldernerd/HID_Utility.

Ultrasonic Anemometer Part 23: First successful measurements

In my last post I was happy to report that I managed to get the USB interface to work. This interface has since proved to be extremely valuable in software development and testing. While the device is taking measurements you can look at the results (or intermediate results) at your PC in real time. You can even log large amounts of data to a .csv file and inspect the results in Excel.

20160514_StandaloneAnemometer_049

But let’s look at the developements in a bit more detail. Last time the device was sending pulses and capturing some of the resulting zero-crossings but not much more than that. And in a not very structured way.

Measuring amplitude

Now it’s not only capturing the times when the zero-crossings occur but also measures the amplitude of the half-waves in between. In order to do that an interrupt is generated at every zero-crossing capture. Inside that interrupt service routine time of the zero-crossing is saved (as previously) and the ADC is started. In order to measure the amplitude at its maximum (or minimum in case of a negative half-wave), the ADC first samples the input for a 6.25 microseconds (which corresponds to a quarter-wave at 40kHz). I’ve chosen the sampling period slightly shorter to compensate for the time from when the zero-crossing occured unil the ADC is started. After the sampling period the internal sample-and-hold amplifier switches from sample to hold and the actual analog-to-digital conversion takes place.

The PIC’s datasheet advertises a maximum sampling rate of 1 million samples per second. Beware, though, that this requires separate Vref+ and Vref- connections and doesn’t work in differential mode anyway. In my configuration without separate analog references and differential measurements the maximum sampling rate drops to 400k samples per second. And the reported conversion time doesn’t include the sampling time yet. I wasn’t aware of that but luckily the PIC’s ADC is still more than fast enough for what I’m doing here.

20160428_StandaloneAnemometer_028

Finding the absolute phase

Capturing the zero-crossings is relatively easy and the results are very precise. But there’s a challenge: there are hundreds of zero crossings for each burst of pulses sent. How do you know which zero-crossings to use?

The Arduino-based anemometer used an analog envelope detector to solve this problem. After averaging plenty of samples this works most of the time. But even after many attempts to tweek the analog circuit the envelope detector approach was never as reliable as I wanted it to be.

My standalone anemometer has an entirely different approach. Being able to digitally measure the amplitude of each half-wave we can tackle the challenge in software. We have a series of measurements and we have an idea of that the signal we are looking for looks like. Looking the scope screenshot below you could easily and reliably determine where the maximum amplitude occurs. That’s what we need to teach the software to do.

ZCD_Capture

One could, of course, just loop through the all the amplitudes and find the maximum. But there are a lot of similar amplitudes and so any noise would make the result unreliable.

I did a bit of reading on digital signal processing (DSP) and realized that this is a classic DSP problem. The solution is a matched filter. You take the signal you are looking for (also known as kernel or template) and multiply it sample by sample with the captured signal and sum up the results. Do that for every possible (or reasonable) overlap of signal and kernel and find the position where the result reaches its maximum.

If you’re new to the subject (like I am), Steven W. Smith’s Digital Signal Processing is a great place to start. It’s even available online for free at dspguide.com. The method is also referred as convolution or correlation depending on who you ask. This wikipedia article gives a nice introduction to the subject.

Implementing the matched filter

I’ve parameterized the software to capture 34 zero crossings as well as the n=33 amplitudes in between them. The kernel consists of k=17 data points with a peak in the middle.

There are n-k+1=17 possibilities to entirely overlap the kernel with the signal. We can skip all the odd numbers where a negative kernel value would be multiplied with a positive sample value and vice versa. This leaves us with 9 possible positions to chose from.

For each position we need to do 17 multiplications and 16 additions. And we need to do that for every single measurement, i.e. 512 times per second. That sounds like a lot of work and it probably is. Luckily, since this is a very common DSP task, microcontrollers like the PIC32 have a special instruction for this. It’s called MAC – Multiply Accumulate and executes in a single clock cycle. The result is just amazing. The corresponding ISR takes less than 30 microseconds, including some housekeeping tasks as can be seen in the screenshot below.

Once the maximum amplitude is found, the 16 zero-crossings around it (i.e. the 8 before and the 8 after) are summed up and the sum is saved as the result of that measurement.

ConvolutionTime

Averaging measurements

The goal is to report wind speed and temperature four times per second. Since there are 512 measurements per second we can use up to 128 individual measurements  (32 in each direction) to do our calculations.

So we have plenty of data to identify and exclude outliers and do some averaging of the remaining samples. Robust statistics is the key word here, click here for the corresponding wikipedia article.

For now I’m doing something reasonably simple: First the 32 results per direction are sorted. The 12 lowest and 12 highest results are ignored and only the 8 results in the middle are summed up.

This might seem wasteful but it makes the average very robust against outliers and still results in 16 x 8 = 128 zero-crossings being averaged. The resolution of each zero-crossing is equal to 1 / 48MHz or about 20.83 nanoseconds. Summing up 128 of them gives us a resolution of far below a nanosecond. Beware however that resolution doesn not imply accuracy.

As a last step, the resulting sum is multiplied with 125 and then divided by 768 to make the unit 1 nanosecond. So every 250 milliseconds we finally have 4 time-of-flight measurements with a resolution of 1 nanosecond. That’s what we will use to calculate the winds speed as well as wind direction and temperature.

This sorting and averaging step is a bit more costly in terms of computation time. It takes around 600 microseconds to complete (see below). But unlike the convolution, it only has to be performed 4 times per second so this is more than fine.

CalculatingAverageToF

Calculating wind speed

We are finally in a position to calculate the actual wind speed. There are various ways of doing this. For now I’ve just done the simple approach of taking the difference in time-of-flight, assuming room temperature and solving for wind speed. This means solving a quadratic equation for which I have resorted to floating point math and using <math.h> for the square root function.

I don’t have my wind tunnel any more so doing any testing was difficult. But one thing was soon obvious: at zero wind speed, the time-of-flight measurements match extremely well and are extrordinary stable from measurement to measurement. Also, looking at the intermediate results (i.e. the 128 single measurements before averaging) shows that there are basically no outliers present. I could randomly pick a measurement and still get a very reasonable value.

Something seems to be systematically wrong with the first of the 128 measurements but I haven’t had time to look into this. Otherwise, the results are impressively stable. And I’m only using a relatively primitive kernel for the matched filter.

USB data logging

As I’ve mentioned at the beginning, the USB interface lets me do some serious data logging even at this early stage of development. Here’s a list of what I can do by sending a character to the device from a USB terminal.

  • ‘Z’: Get all the 34 zero-crossings of a single measurement
  • ‘A’: Get all 33 amplitudes of a single measurement
  • ‘F’: Get a full single measurement, i.e. 34 zero-crossings plus 33 amplitudes
  • ‘T’: Get all the 4 x 32 = 128 time-of-flights for a measurement series
  • ‘R’: Get the 4 averaged time-of-flights as well as wind speed and temperature

Some versions of these commands also let you specify the direction you’re interested in as well as how many sets of data you want to receive. This makes it easy to log large amounts of data that you can use to test possible algorithms on your PC before you implement them on the PIC.

20160428_StandaloneAnemometer_025

Next steps

The next step is to get the I2C digipot working so I can control the amplification in software. My idea is to aim for a maximum amplitude of around 3 volts independent of wind speed and so on.

There’s also plenty of work to do to improve the algorithm that calculates wind speed and temperature. And then I also have to implement the I2C and SPI interfaces that let the anemometer communicate to other embedded devices like an Arduino or Raspberry Pi.

Having used floating point math and <math.h> I’m also running out of flash memory. I’m currently using 93% of flash (32kB total) and 52% of ram (8kB total). There will be a slightly revised board (Rev B) that uses a PIC32MX250 which is identical to the MX220 used here but has four times as much flash and ram.

That’s it for today. On the overview page you find the software at the stage of developement just described as well as some examples of logged data (all at zero wind speed) as .csv files.

The next post on this project is here: Part 24.

Ultrasonic Anemometer Part 21: Standalone Anemometer Hardware

Last time I went through the design of my new standalone anemometer. Now it’s time to build this thing and see if it works as planned.

20160428_StandaloneAnemometer_034

After I fried a couple of chips on my driver circuit testing board due to a wrong chip in the power supply I was a bit more careful this time and built up the board step by step.

20160426_StandaloneAnemometer_016

Only after I confirmed that the power supply was ok I dared to solder some more.

20160426_StandaloneAnemometer_019

The next step was to add the PIC32 with the crystal, the programming header and all the caps they need. This is a chip family that I’ve never used before so I wanted to first see if I can program it. All went well and I managed to get it to run on the crystal’s 8MHz boosted up to 40MHz by an internal PLL. So I was ready for the rest.

20160428_StandaloneAnemometer_031

I wrote some very basic software and confirmed that at least the basics were working ok. I was able to send and receive pulses, the pulses got amplified, the zero-crossing detector worked and so forth.

20160428_StandaloneAnemometer_024

As mentioned, I’m entirely new to the PIC32 microcontroller series. There are a lot of similarities to the PIC16 and PIC18 series that I’m quite familiar with but still it’s always a challenge to work with a new family of chips and the tools that come with it. I took me the better part of an afternoon to master the vectored interrupts with the different priority levels and so on.

20160428_StandaloneAnemometer_040
Driver circuit (front) and standalone anemometer (back) side by side.

By the way, with this project I’m using the free MPLAB X IDE with the also free XC32 C compiler from Microchip. So anyone is able to write, modify or compile code for this thing with free software. At least at the moment you need a programmer to actually burn the chip. But the PICkit3 only costs around 50 dollars and my idea is to write a USB bootloader so that any user can modify the software of a pre-programmed board.

20160514_StandaloneAnemometer_050

So now comes what I think might be the hardest part: Getting the USB to work. I’ve spent quite a few hours so far but haven’t managed to get it working properly yet. If anyone has experience with this kind of software development – Let me know, any help is highly appreciated.

It now works: Click here to view it.

Ultrasonic Anemometer Part 20: Standalone Anemometer Design

Last time I outlined my reasons to ‘go digital’ by adding a powerful on-board microcontroller and designing a standalone wind meter.

20160426_StandaloneAnemometer_001

In the weeks that followed that decision I tried to find a suitable microcontroller and to design a prototype. Today I’ll show you the result of that work.

20160426_StandaloneAnemometer_003

I looked at various series of microcontrollers from different manufacturers and finally decided to go for the Microchip PIC32 series. It offers everything I could possibly ask for: 32 bit architecture, inexpensive, vectored interrupts, integer division, any interface you want (depending on the model of course) , available in large, low pin count, hobbyist friendly packages and so on.

20160426_StandaloneAnemometer_011

As you can see above, the model chosen for my prototype is a PIC32MX220. This is low to mid-end representative of this series but even so the specs are quite impressive. CPU clock up to 50MHz, one instruction per clock cycle, full-speed USB 2.0, 32kB flash, 8kB RAM and all of that in a SOIC28 package at a price of CHF 3.58 in single quantities.

20160426_StandaloneAnemometer_005

After having chosen a chip the next task was to come up with an actual design. I took my anemometer driver design and tried to integrated the new PIC32. That driver circuit had performed extraordinary well so I changed very little. I left away the RELEASE signal since my tests had shown it to be unnecessary. I also replaced the LM5111-1M mosfet drivers by LM5111-2M. The difference is that the 2M is inverting while the 1M is not. The reason for changing this is because the 2M is available at a significantly lower price of CHF 1.35 vs CHF 2.25. Not a big deal if you just build a single prototype but I thought it might be smart to change this anyway. This also required some resistors to be changed from pull-downs to pull-ups. Except these details everything stayed the same with the drive circuit.

20160426_StandaloneAnemometer_012

I also had to re-design the power supply since the PIC needs a 3.3 volt rail as opposed to 5 volts in the driver test circuit. Since I had to re-design it anyway I also downsized the power supply somewhat. I’ve otherwise resisted all temptations to use smaller components but the power supply was just a bit too big with the two  SOIC8 chips and four size C tantalum caps.

The prototype now uses an MCP1755 linear 3.3V regulator in a SOT23-5 package with a 33uF size B tantalum cap at its input and a 10uF 0805 size ceramic cap at the output. A TCM829  (also in a SOT23-5 package) and two more 10uF caps produce the -3.3 volts output. So there is a total of three supply rails: +12V, +3.3V and -3.3V.

20160426_StandaloneAnemometer_006

A major challenge was to make do with the very limited number of I/O pins on the PIC. 28 pins seem like a lot for the task at hand but plenty of them are already used for things like supply voltages and the like.

In the end I managed to still get three independent interfaces to the outside world: USB 2.0, I2C and SPI. All these interfaces as well as just about any other signal of interest is easily accessible from one of the numerous 100mil headers along the edges of the board.

20160426_StandaloneAnemometer_007

The amplifier still uses a LMC6482 dual op amp , now running on a+/- 3.3 volt supply. The first stage amplifies the ground-referenced input signal by a fixed factor (currently 11 but this might change). The output signal is then biased to 1.65 volts and amplified once again. This time the gain can be adjusted digitally via a MCP4561 I2C digipot.

20160426_StandaloneAnemometer_008

Before I forget: The PIC gets its system clock from a 8MHz crystal. That might seem low but there are two (variable)  PLLs inside the PIC that (together with a number of pre- and post-scalers) let us produce the 48Mhz signal needed for USB as well as a reasonable clock speed to run the CPU and peripheral bus on (probably also 48MHz but we’ll see).

20160426_StandaloneAnemometer_013

The board layout proved to be a bit tricky because there isn’t that much space on the board and I had quite clear ideas where I wanted certain headers to be. So I was more than happy when all the traces were finally laid out.

As you can see, the PCB is already milled and the vias soldered. I can’t wait to build this thing up and start to do some programming. That will be the topic of my next post.

20160426_StandaloneAnemometer_014

As always, a zip file with the eagle files and PDFs of the schematic and board layout can be found on the overivew page.

And here‘s the finished board.

USB Boost Converter

_MG_1042
Finished 5V to 12V USB boost converter

I frequently need a low-power supply to run a microcontroller system. Typically, one uses a lab power for such purposes. But at least on the desk where I do the programming I don’t have one. Since these systems typically consume little current it would be handy to be able to power them from USB. Most of my devices have on-board regulators so the voltage is rather uncritical. For 3.3 volt devices, the 5V from USB is just right. But others have a 5V regulator so they need a higher supply voltage. And even others might even need 12 volts.

_MG_1035
Fully assembled PCB

So I decided to build a small low-power boost converter with a USB plug on its input. The output voltage is set by a pair of resistors. So once built the output voltage is fix but my idea is to build several of them anyway. So some will produce 12V while others will produce 7.5V. The latter is intended to power all those systems with on-board 5V regulators. Of course, you could use a trimmer or pot if you wanted a variable voltage version. However, the feedback loop requires a capacitor for stability and its value also depends on output voltage. You might well find a value that results in stable operation over a say 6 – 12V range, but I haven’t tried that.

_MG_1015
Bottom side

I had a look for a suitable integrated switcher IC and found the Texas Instruments LMR62014. It comes in a small SOT23-5 package. It switches at a high frequency of 1.6MHz which will keep the other components small, too. It switches up to 1.4 amps. It’s easy to use. And even afordable, around 1.50 a piece. The datasheet is very helpful when it comes to PCB layout. It includes a two-layer sample layout that works even with hobbyist-sized components (0805, 1206 for the input and output capacitors).

20141115_173315
Not a bad heat sink

Generally, layout is important with switch-mode DC-DC converters. Their operation requires switching square-wave power signals (as opposed to just logical-level signals where little current flows). And that requires careful layout in order to minimize stray inductance, mainly. Things are more forgiving when you work with relatively slow (say 100kHz) switchers but get much more demanding when switching at higher frequencies. There has been a steady trend to ever-higher frequencies and 1.6MHz is fairly high even by 2015 standards. So I was very happy to have a nice layout example to start with.

_MG_1014
Top side

As you can see from the photo above, the thing is small, only 26 x 14mm. Also note how the layout makes the components magically fit together without any long traces and few vias.

20141115_173232
Home brew constant current dummy load in action

So far, I’ve built two units, one running at 12V, the other at 7.5V. Theoretically, one should be able to pull 580mA and 930mA from them, respectively. Of course, these are theoretical figures assuming no losses. Also, the 1.4A rating on the IC is likely the current limit at the top of the switching cycle (the datasheet will tell you or course but I don’t have the PDF open right now), not an average. And thermal considerations might also put limits on continuous currents. More on that later. And don’t expect to be able to pull 1.4A from a random USB port (which would violate the USB specifications anyway). But given my use-case for these things I’m entirely happy if I can pull a 100mA or so. And that should work comfortably.

20141116_144615
Switcher IC: 70 degrees @ 200mA
20141116_144627
Diode: 58 degrees @ 200mA
20141116_144553
Coil: 50 degrees @ 200mA

I’ve pushed both versions to their respective limits on the bench, using a stiff 5V supply and my home-brew constant current dummy load (link). With case temperatures approaching 100 degrees centigrade I was able to pull around 250mA of continuous current from the 12V version. The ICs include thermal limiting so you don’t need to worry too much about damaging them when performing this kind of tests. As you can see on the photos, I did these tests with the naked PCBs sitting in a vise which probabely made a not-so-bad heatsink for the board as a whole.

20141116_144738
Output voltage folds back when the switcher gets too hot

I’ve encountered slight stability problems with the 12V version (but not with the 7.5V one). There is some oscillation at currents above 200mA or so. Changing the value of the compensation capacitor changed the frequency and amplitude but I haven’t managed to get rid of it entirely. But anyway, I won’t run them at 200mA so I haven’t put much more effort into this.

_MG_1045
Close up of the final product

The finished units have a USB wire on the input and a arduino-compatible plug on the output. To protect against short-circuits I’ve put them in a piece of shrinking hose which is a bit of a themal nightmare of course. There is also a voltage drop over the USB cable which means the input voltage seen by the converter is below 5V even with a perfectly stiff USB port. Which in turn means more work for our converter, making things worse.

_MG_1040
Shrinking hose doesn’t help in keeping it cool

I have frequently used the 7.5V version to power my Ultrasonic Anemometer which pulls around 60mA. That’s the kind of application that I had in mind for this little device and it works well for that. It hardly gets warm at all and provides reliable power on my desk without the need for a lab power supply.

Attached the Eagle files as well as a PDF of the schematic and layout: USB_BoostConverter