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 30: Downsized Hardware

In my last post of this series I’ve looked at different transducers and finally decided on a entirely waterproof 14mm model. The much lower signal level from those kind of transducers makes it  necessary to reduce the distance between the transducers in order to still receive a reasonable signal amplitude.
So I took my previous lasercut design and reduced it in size so that the distance between the transducers is only 120mm. I went to the local FabLab and and lasered two copies of the downsized design.

Since the new transducers are only 14mm in diameter but those plastic pipes are only available in 16mm I had to pad the transducers with short sections of aluminium tube with an outer and inner diameter of 16 and 14mm, respectively.
I previsously connected the wind meter to an Arduino with a LCD display to test the I2C functionality as well as to read the wind speed and direction without having to connect the anemometer to a PC. Now I have used my I2C user interface for that purpose. It is powered from the wind meter’s 3.3 volt rail and is controlled via I2C including the backlight brightness and display reset. The user interface usually also includes a rotary encoder with push-button not present in this application.

In an attempt to boost signal amplitude I’ve also changed the first stage op amp’s gain from 11 to 31 by replacing the 10k resistor with a 30k one. I’ve argued in my last post that this is probably about as far as you can safely push it.
Even with the lowered transducer distance and increased gain the signal amplitude after the first stage is less than impressive. But we knew that already. And we have a second variable-gain stage at our disposal. Setting the second stage’s gain sufficiently high we hopefully get the 3 volts peak-to-peak amplitude we are aiming for.

By the way, I’ll started from scratch with the firmware. The reason for that is mainly USB. Currently, the anemometer acts as a HID device. While working on my solar charger I started to play around with HID / MSD (human interface device / mass storage device) composite devices. They still act as HIDs with all the functionality just like before. But when you plug it into a PC it also enumerates as a mass storage device, i.e. it behaves just like a memory stick. You can read and write the files on it from any computer, irrespective of the operating system and without needing any particular softwar or driver installed. So you can put all the configuration parameters in a text file that resides on what looks like a memory stick. I guess that’s the most user friendly way of dealing with those user-specific configuration parameters. Just plug it in, open a text file, change what you need, save the file and you’re done. This is how the solar charger will operate and  I’ve decided to implement the same here.
Microchip’s Harmony library includes all that functionality so I have no doubt it’s doable. But I’ve figured that it’s likely easier to do this as a new project and then add the previously implemented functionality step-by-step.

And then there’s another USB-related feature that I had in mind right from the start but which I haven’t event started to implement so far: A USB boot loader. That would enable people to do a firmware update without needing a in-circuit programmer such as the PICKit 3. Users could just download a new HEX file and upgrade the firmware without needing any special hardware or even skills.
USB boot loaders come in various flavours. The Harmony library includes support for an HID boot loader. But that’s not really ideal if you ask me. It means that you need to run some software on your PC that communicates with the anemometer and sends the new firmware via USB. The need for software means that it matters what kind of operating system you run. And needing additional software is undesirable in the first place.

There are also MSD bootloaders which do not have all those downsides. The device acts as a memory stick to the PC. The user then just copies the HEX file to that memory stick and that’s it. Just drag-and-drop, no extra software, no matter what OS.

The problem is that the Harmony library does not support that out of the box. Indeed, Microchip doesn’t seem to have implemented that for any of their chips. That’s kind of strange because other chip manufacturers have done so long time since. There is at least one implementation for PICs out there in the web but I haven’t looked at it yet because the website it was hosted on no longer exists it seems. Probably I’ll have to implement this myself but the Harmony support for MSD will hopefully do much of the heavy lifting.

So that’s the plan. Implement a bootloader, preferably of the MSD variety. And then run the anemometer appliction as a HID/MSD composite device. You may say that I set the wrong priorities given the fact that the actual measuring is not yet as good as it needs to be. But this kind of fundamental architecture is easier to get right from the very beginning. So that’s why.
If you’re interested in this lasercut design you can find iton github.com or more precisely on https://github.com/soldernerd/AnemometerLasercut. This version is called Anemometer_03.scad and the PDF that was used for the actual laser cutting is Anemometer_03.pdf.

Standalone Inductance Meter on a Etched Board

In late 2014 and early 2015 I had posted a short series on an inductance meter project. The first post in that series described an Arduino shield that allowed an Arduino UNO to do inductance measurements and got this blog mentioned on dangerousprototypes.com for the very first time.

I got a lot of encouraging feedback and some time last year Andy Beasley asked me if I could help him extracting Gerber files from Eagle so that he could get some boards made and build his own. I was happy to do so and was rewarded with half a dozen boards. Thank you very much, Andy.

At the time I was busy working on other projects so the boards collected some dust until Sean Connolly sent me a message asking if I could make an inductance meter for him. That was a great opportunity to finally build up one of these boards.

The result was the most  beautiful of my inductance meters so far. There’s nothing new technically – It’s still the circuit described in this post.

By the way, I’ve started to share more and more of the projects on github. All the photos, descriptions and so on will continue to be published here on soldernerd.com but I will put the download material such as source code, eagle files and the like on github.com/soldernerd where it is easier to keep files in sync and to potentially collaborate with other developers.

So here’s a list of the relevant repositories on github:

Ultrasonic Anemometer Part 29: Transducer Comparison

It’s been way too long since the last post in my Ultrasonic Anemometer series. But better late then never.

So far I have always used the same type of transducers. When I started this project I looked around and found the Multicomp MCUSD16A40S12RO. They were comparatively cheap and readily available so I ordered some and used nothing else for the next two or so years.

However, they are not hermetically sealed and therefore not the most suitable type to use outdoors all year around. Some of you have already experimented with other, truely watertight types and have reported that the signal level with those is dramatically lower. So I decided to see what’s available and do a more systematic comparison. That’s what this post is about.

The Contestants

  1. Multicomp MCUSD16A40S12R0 (Farnell 2362677),  16mm, not waterproof, no wires attached.
  2. Multicomp MCUSD14A40S09RS (Farnell 2362679), 14mm, waterproof, no wires attached.
  3. Multicomp MCUSD14A40S09RS-30C (Farnell 2362678), 14mm, waterproof, with attached wires.
  4. Multicomp MCUSD18A40S09RS-30C (Farnell 2362680), 18mm, waterproof, with attached wires.

You might wonder why I’m only considering Multicomp models but those 3 models are pretty much all the 40kHz watertight transducers I can get from Farnell.

So what I did is I attached all 4 models to the same anemometer so that I can switch back and forth between them. That turned out to be rather tedious and time consuming and resulted in a big mess of wires so I was happy that I only had 4 types to worry about.

I’ve measured the signal after the first (fixed gain) stage of the op-amp. So the signal reported here is already boosted up by a factor of 11.

The Benchmark

Let’s first look at the model used so far. As we already know it delivers a solid signal amplitude.

Zooming in at the burst at the center of the screen (the one with the smalles amplitude) gives us a reading of 1.9 volts peak-to-peak.

14mm waterproof transducer without wires

Let’s look at the first waterproof model. The signal amplitude us barely noticable at first.

Zooming in (both horizontally and vertically) then reveals the amplitude: 47 millivolts, a factor of 40 less than the benchmark model.

14mm waterproof with wires

Next in line is a transducer that looks virtually identical but has a pair of drilled wires at the back as opposed to just two pins. The overview looks just like before.

Zooming in shows an even smaller signal amplitude of only 37millivolts. That’s surprising because it has somewhat better specs compared to the previous model.

18mm waterproof with wires

Once again, the overview shows hardly anything for the 18mm model.

Zooming in we find an amplitude of 38 millivolts, basically the same as the last model.

Conclusion

The first fact is obvious: with hermetically sealed transducers you can only expect a small fraction of the signal at the input.  I knew that but was still surprised to find how much smaller that singal is.  In this comparison it’s a factor of 40in the very best case.

But an anemometer is useless if it cannot withstand the elements so I guess we have to live with that. I will use the 14mm without wires type going forward. Not only did it perfom best in my comparison but it is also the most affordable (waterproof) model. Apart from that I like its small 14mm form factor allowing for slim designs posing less resistance to the airflow.

The road ahead

We obviously need to make some hardware changes to deal with the low signal amplitude. The most obvious solution is more gain. We can get more gain of the first (fixed gain) stage by just changing a resistor. However, we need to be careful not to push the op amp beyond its limits. I’ve looked at the LMC6482 datasheet again and found a gain/bandwidth product of 1.5MHz. That means we can get a maximum gain of 37.5 at 40kHz. You probably don’t want to push the op amp right to its limit so something like 31 (changing the 10k resistor to 30k)  is probably about the best we can do here.  That gives us an extra factor of 2.82.

Making the physical design smaller and therefore reducing the distance between the transducers is another thing we can do.  The current desing is 245mm which is rather large. Someone has reported to me that he reduced that all the way down to 100mm. I don’t think I will go that far but will try 120mm which is about half of what I have now. That should double the signal amplitude. And the smaller transducers should make the task easier.

The two measures combined give an extra gain of factor 5.6. That leaves us with another factor 7 to be compensated elsewhere. Fortunately, we still have a second op amp stage (the one controlled by software) which hasn’t been doing much so far.  With the previous transducer model it only had to deliver something like a factor 1.5. If we boos this up to 10 we pretty much have all we need.

A software bug

During my tests I also discovered some weird software behaviour when the signal (after both stages of amplification) is not in the expected range. USB may hang, among other things. The pulse-sending sequence can also get upset. Someone had reported this to me earlier but I wasn’t able to reproduce the problem until now. I don’t expect this to be a major thing to fix but you never know. But I’ll definitely look into this.

 

 

 

ReflowR on indiegogo.com

This will be my shortest post ever. But I just spotted a project on indiegogo.com that I think is worth mentioning: A small and affordable tool to do reflow soldering. It’s basically a heating plate specifically designed for reflow soldering. So it can reproduce JEDEC temperature profiles, it does data logging and and you can even control it via a web interface if you spend an extra 9$ on the wifi upgrade.

Here’s the link: https://igg.me/at/reflowr/x/15560432 or http://reflowr.com

I’ve been looking around for some kind of reflow oven for a while but nothing affordable quite convinced me. This morning I just stumbled accross this project by chance. I’ve ordered a “Large ReflowR” with the wifi upgrade and an external thermoucuple  and will report on how it performs once I get it which should be some time in February next year.

MPPT Solar Charger Testing II

It’s time to follow up on the MPPT Solar Charger project. Progress has been slow since I’m currently working full time and doing a master’s degree at the same time. Given that this blog has previously been something close to a 50% job at times things will necessarily slow down a bit. But all the projects, including this one and the ultrasonic anemometer are alive and well and I’m working on them whenever I find some time.

20161012_userinterfacereva_014

User Interface

So what’s new with the MPPT solar charger? First of all, it got this nice user interface. Unfortunately there were still some issues with the first version so there is an identically looking but much-improved and bug-free Rev B.  I’ll do a separate post on that documenting all the things I’ve changed.

I re-used the white-on-blue display from the initial version for the Rev B. as opposed to the black-on-white used with the Rev A. They are pin compatible so you can use whichever you prefer. I more and more start liking that black-on-white look. It’s about 10 bucks cheaper as well. What’s your opinion on this?

img_4334

Solar Panel drains Battery

My intention with this design was to just leave the solar panel connected to the input of the buck converter. There’s a problem with that, however. The input of a buck is always at least at the output voltage minus a diode drop. With a 12V lead-acid battery at the output the input (i.e. where the solar panel is connected) the voltage never drops much below 12 volts.

That’s a serious problem since even a small solar panel like the monocrystalline 30W panel I have here sinks around 10mA at that voltage. So whenever the panel is not providing any power it considerably drains the battery.

Try a Diode

Obviously we need a way to avoid that. The first solution that comes to mind is a diode. But there’s a problem with that, too. To keep the power loss in the diode acceptable, the diode needs to have a low forward voltage. However, any diode with a low forward voltage also comes with a high reverse leakage.  Physics seems to dictate that.

Leakage can easily be in the range of milliamps for a diode that can handle, say, 4A like needed here. And that reverse leakage is also highly temperature dependent. It may be ok-ish at room temperature and then detoriate by an order of magnitude at 50 degrees centigrade.

To get an acceptable reverse leakage one needs to tolerate at least half a volt of forward drop which is something like 3% in efficiency. Since our converter operates at around 97% efficiency that would mean doubling the energy dissipated.

P-Channel or N-Channel Mosfet

So the next obvious thing to try is a mosfet acting as a switch.  Yes, a mosfet also has a body diode that also has a reverse leakage. But the body diode is a bad diode in terms of forward drop and has a correspondingly low reverse leakage.

A nice way of solving our problem would be to use a p-channel high-side switch disconnecting the battery from the converter whenever the panel is not producing. That not only disconnects the panel but powers off the entire buck including the input and output caps and everything. Where there is no voltage no power can get wasted. Perfect.

img_4342

Unfortunately, powerful (i.e. low Rds-on) p-fets are relatively large,  rare and expensive. As a rule of thumb a p-fet needs twice as much silicon area for the same performance compared to a n-fet. Besides that, that would be another type of component and I’m trying to not use too many distinct components.

So the other solution is to use an n-fet as low-side switch just disconnecting the panel. We already have 6 powerful n-fets in our design and they are cheap, too. So this is what I’ll do in the next version.

For now I’ve used one of the power outputs to connect the panel. I’ve cut some traces and soldered in some wires so that the fet is on whenever the buck is powered on.

Buck Software

During early testing of the buck converter I managed to kill the bottom fet several times. Since I was able to run the buck at relatively high power levels for prolonged periods of time without any issues (and without getting hot) I suspected that this was caused by carelessly written software. This seems to have been the case indeed. Whenever I killed a fet it happened at startup or shutdown, usually the latter. In the mean time I’ve written well-defined startup and shutdown routines and never had any issue since.

bootstrapcapacitorcharging

Synchronous converters are dangerous in this respect. It is very easy to short the battery to ground via the bottom fet. All it takes is a duty cycle that’s too low or a timer is running too slow or not at all. Or you stop the PWM module at a time when the bottom fet is on and it will stay on forever.  Or at least a few milliseconds until it’s dead.

Asynchronous topologies are much more forgiving in this respect since you can’t short anything. So an easy solution would be to start up and shut down in asynchronous mode. We can easily make this an asynchronous converter in software by just not utilizing the bottom fet. The diode in parallel with it will then automatically take over.

Unfortunately we cannot start up in asynchronous mode. Why? To enable the upper fet we need a bootstrap voltage above the input voltage. And we don’t have that unless the converter is running. It’s a chicken and egg problem, really. So we need to start up in synchronous mode at least for a few switching cycles for the bootstrap diode to charge up.

That’s exactly what the startup routine does. It completes 16 cycles in synchronous mode at a neutral duty cycle. What do I mean by neutral? Simple: Duty Cycle = Output Voltage / Input Voltage. That means no current actually flows on average. So this is a nice, soft way to start up. After those 16 duty cycles the buck enters asynchronous mode. As the screenshot above shows, the bootstrap capacitor is fully charged after just one full duty cycle so that number is more than sufficient.

This routine is critical. If it doesn’t do precisely what it should chances are high that the buck is destroyed. So I’ve checked it carefully by both looking at the code and the scope. I’ve run it many times and observed closely what it does just to be sure it starts up nicely very time.

Why run in asynchronous mode? Because it’s more efficient at low power levels. Once the current rises above a software-defined threshold the converter will change to synchronous mode. If the current later falls below a second (lower) threshold, the buck changes back into async mode.

The optimal values for the two threshold will have to be determined experimentally but will likely be in the range of a few hundred milliamps.

buckturnoff

The shutdown sequence is simple. The buck is shut down if the current falls below a very low threshold (say, 10mA) below which it cannot run profitably. If the current falls even lower we are better off shutting down the buck and entering a low-power mode. Since the current is low when we shut it off, the converter is already in async mode. So shutting it down is now easy and uncritical. We just turn off the top fet and can then also turn off the timer and supply voltage to the buck. The screenshot above shows an example of that.

Conserving power

A main feature of this solar charger is it’s ability to (hopefully…) run at a very low (<100microamps) current when not in use. So we obviously need to turn off everything we don’t need and run the PIC at a much lower frequency as well.

The PIC’s maximum operating frequency is 48MHz. This is the frequency it runs at when the buck and/or USB (not yet implemented) is on. These two features need that clock frequency to perform their task.

If both the buck and USB are off we can clock the PIC down to 8MHz which already saves a great deal of power. At 8MHz we can still do everything else, including running the user interface. Updating the display and particularly calculating the display content consumes quite some computation time and so we need a few MHz to do this.

If the user interface is not used for a certain time (say, 10 seconds), it is turned off. We can then lower the board voltage to 2.3 volts and lower the CPU frequency even further to 32.768kHz.  This is the frequency of the real-time clock that is running anyway. At such a low frequency the PIC’s computational power is low but still sufficient to do some housekeeping tasks.

One can wake up the user interface at any time by pressing the push button. Turning the encoder won’t help because that, too, has been powered off.

While in this low power mode every 6 seconds the board voltage is raised to 3.3 volts and all temperatures as well as the input and output voltages are measured. That all happens at 32.768kHz. After the measurement is complete the PIC decides if the panel voltage is high enough to start harvesting energy or not. If this is not the case the board voltage is lowered again and a new set of measurements is captured 6 seconds later.

img_4336

Despite all those efforts the board consumes something like 530 microamps which is much more than it should. About 100 microamps comes from the voltage divider used to measure the panel voltge. That’s an easy to solve design problem that I’ve described earlier already. But that still means that something is drawing 400 microamps. Not much at all but still way too much.

I’ve spent an evening trying to find the problem but I still don’t know. I’ve suspected the capacitors but when I measured some spare caps of the same type they hardly drew any current at 12 volts. I also un-soldered the buck’s mosfet driver but that made hardly any difference so that’s also not the problem. It may even just be some near-short on my board homemade board. So I leave that for now and check again once I have a revised design with a proper PCB.

Buck testing

I’ve saved the most interesting part for last 😉 I’ve established before that this converter has a similarly high efficiency than the Arduino version published some time ago. But at that time I was only able to test up to 35 or so watts.

This solar charger is capable of handling much more power than that. Testing how much was a bit more difficult than expected. Unless the battery is very empty it won’t draw as much as this charger is able to provide. And you don’t want to discharge a lead acid battery too much, they don’t appreciate it at all. So once again my constant current dummy load came to the rescue.

img_4339

With the dummy load at one of the power outputs I was able to draw some serious current. I set the dummy load to 4 amps and the battery absorbed (or provided) whatever was left. Obviously, I can only do that for a limited amount of time until the dummy load gets too hot. It automatically shuts down once the heat sink reaches 70 degrees centigrade which is soon the case at 4 amps.

I let the charger draw 4.5 amps at a bit more than 17 volts for as long as I could. The coil got quite warm, slightly hot even, maybe something like 60 degrees. The mosfet only got lukewarm and I’m not sure if this was because of their own power dissipation or due to their proximity to the coil.

img_4341

So from this test I’d conclude that this was about the power which the charger can handle for a prolonged period of time. So I think something like 75 watts is a realistic power rating.

I’ve also had another look at the datasheet of the coil and it pretty much confirmed my findings. 75 watts at (say) 13 volts output corresponds to 5.8 amps through the coil. The datasheet states that the coil starts saturating at 8.2 amps which means we’re still safe with 5.8 amps plus the ripple current. The datasheet also states a 40 degree temperature rise at 5.3 amps. So thermally the coil is pretty much at its limit at 75 watts. That, too, seems realistic to me having touched it after some time at that power.

The road ahead

So how to continue? As we have seen, there is a number of design issues but the general concept works. During testing and debugging I’ve cut and re-soldered many traces and also made some modifications like the one with the n-fet described above. I’ve unsoldered and changed many components as well. All of that doesn’t improve the reliability of the board. At some point it makes sense to design a new version, build it and take it from there. A clean slate kind of.

I think this point has been reached here. So I will work on a new revision from now on. The concept won’t change at all but I’ll try to apply what I’ve learned so far. I also hope to reduce the number of different components, reduce the size and total cost while not sacrificing performance. In other words move a step towards a design that may one day be built as a small series. Let’s see.

Low Power User Interface

20161007_userinterfacereva_001

As you may have noticed I’m quite busy working on the MPPT Solar Charger project. The latest version uses a 4 lines x 20 characters LCD that connects via I2C as well as a rotary encoder with a push button.

20160904_solarcharger_006

While the display got its own little board, the encoder connected directly with the solar charger where its signals aredebounced in hardware and then routed to the PIC.

20160905_solarcharger_015

After a few little fixes (see my last post) that worked but I had to use the signal intended for controlling the  backlight brightness for the display’s reset signal. I don’t want to run any more wires to the display and there are no spare pins on the PIC anyway so I had to come up with another solution.

20160905_solarcharger_017

And it was not very elegant that the display was powered off by just cutting the entire power supply. Having a digital enable/disable signal would be preferable

20161012_userinterfacereva_014

Design a universal User Interface

I then decided to design an new board that also includes the rotary encoder with all the necessary debouncing. That way I get a quite universal, easy to use user interface that I can use for other projects as well. That eliminates the need to design the same functionality (think debouncing) again and again. The size of the board is mainly given by the size of the display so there is plenty of board space.

20161012_userinterfacereva_011

So far so good but that doesn’t solve the actual problems yet. I still need a way to control both the backight as well as the reset signal without needing any more singnals. Since the display connects via I2C it was quite straight forward to use I2C communication for those purposes as well. My first thought was to add a I2C port expander just like I’ve done on the solar charger board. Those chips aren’t expensive but they typically provide 8 or 16 extra GPIO pins which seemed a bit wasteful. And PWM control of the backlight would require a great deal of I2C communication which puts a burdon on the microcontroller.

20161007_userinterfacereva_002

I also considered adding a sub-dollar PIC16 which could be programmed as an I2C slave and control both the backlight and the reset signal (as well as giving the option of getting the encoder input via I2C). But I wasn’t eager to write any software for this thing.

20161007_userinterfacereva_003

Requirement: Ultra Low Power State

Another design requirement was to keep this a very low-power design. To be sure: when the display and especially the backlight are on it will consume several milliamps to several dozen milliamps. Illumination doesn’t work without power, such is life. But when the user interface is not in use, we need a way to put it in a very low power state where the display as well as the rotary encoder is off but the push button still works in order to wake up the microcontroller. In that state the user interface must not use more than a few microamps. Furthermore the encoder signals must assume a high impedance state when the user interface is disabled.

20161012_userinterfacereva_012

My final solution was as follows:

  • Use the previous (backlight) PWM signal as an enable signal. Power can now always stay on. When the enable signal is high, the display is on, when enable is low, the user interface goes into its low-power state.
  • Add a dual I2C digipot to control both the reset signal as well as the backlight.

The reset signal is connected directly to the wiper of one of the two digipots. Of course any intermediate digipot values don’t make sense. The digipot should always be either at its minimum or its maximum.

The backlight brightness is controlled by the other digipot via an op-amp and a n-channel mosfet.

The debouncing is basically unchanged. Like in the solar charger design, a 74HC126 quad tri-state buffer is used together with some resistors and capacitors.

Since there are 4 gates on the 74HC126 and I only need to debounce 3 signals, there is still one gate left. I used that gate to power the display as well as the encoder and the encoder’s gates(without the push button which is always powered on). So the enable signal only controls the input of that gate. I thought that’s a nice and elegant solution. Well, if you think so too, think again. More on that later.

Testing

20161007_userinterfacereva_010

First of all nothing worked at all. I asserted the enable signal and nothing happened. Nothing was powered on. The error was soon found. I made a design error with the result that the respective gate was permanently in a high-impedance state. Somehow I had tied the gate’s enable input to ground instead of VCC. The mistake was corrected by cutting the ground connection and conecting the respective pin to the enable singal itself which was available from the pin right next to it. Not pretty (see below) but problem solved.

20161007_userinterfacereva_006

Then ok, power was there but when I tried to turn off the reset singal (i.e. pulling the reset signal high) nothing happened – again. Again, the reason was simple. The digipot’s upper terminal was floating instead of being connected to VCC. On the schematic the wire touched the respective pin but there was no connection. While that was really hard to notice on the schematic I should have noticed the problem when I laid out the board. There was obviously no connection to that pin.

20161007_userinterfacereva_007

This was a bit harder to fix than the previous error. There were no signals to cut but the digipot’s pins are much more closely spaced and the right signal was not to be found nearby. I ended up soldering a thin wire accross the digipot to a resistor that is connected to VCC on the upper end.

20161007_userinterfacereva_005

Even less pretty but problem solved anyway. Turning on the backlight basically worked as intended but the load was a bit much for the 74HC126. While it can supply up to 35mA according to the data sheet, its output voltage is nowhere near its positive supply rail when it supplies that much current. Even with a more modest 5mA load the gate’s output voltage was about half a volt below the input voltage. As a result, the display as well as all the other components only get to see about 2.8 volts instead of 3.3. This didn’t pose any problems so far but it’s not nice.

Another issue I noticed was that the LM321 op amp I had chosen is not a rail-to-rail op amp. The LM321 is inexpensive and I had quite a few left from another project so I used it without giving it much thought. I measured that the output voltage doesn’t get closer than about 1.4 volts of the positive supply rail. Since the n-mosfet used to control the backlight has a very low threshold voltage that didn’t pose a problem but the LM321 is not really a good choice here. While it does work from as little as 3 volts it’s made for split supply and higher voltages, say plus/minus 12 volts. I’ll use a low-voltage rail-to-rail type next time.

Software

Getting any MIDAS I2C display to work is a nightmare. They make nice, pretty and affordable displays. That’s why I buy them. And once you’ve managed to properly initialize them they are easy to work with. But getting them initialized with the right settings is always a lengthy trial-and-error process. I’ve ranted about that before but I feel the need to do it once again.

The entire initialization sequence needs to be written in one single I2C transmission. At least for me it didn’t work otherwise. The data sheet says absolutely nothing about that.

userinterfacestartupsequence

The data sheet doesn’t even mention the initialization sequence. Nor the timing of the reset singnal. The reset signal needs to be pulled low for 10ms. One then needs to wait for 5ms before the initialization sequence is sent. There is not one word about that it in the current datasheet. There is an older version in the net somewhere that mentions those timing issues and at least gives a sample initialization sequence.

userinterfacestartupsequence2

There are various contrast settings that must be set properly via I2C commands but there is very little information on those commands in the data sheet. I wrote an email to their customer support asking if there is a list of commands the display supports. That was more than a month ago and I still didn’t get any answer. As so often, google was my friend and others have faced similar problems before so I managed to find some commands that make the display work properly. I’m sending 10 or so bytes to the display but for most of them I have not a clue what they actually mean or what they are supposed to do. And the commands for this black-on-white display are different to the (otherwise identical) white-on-blue display. Have fun…

Debouncing

I’ve devoted one of my very first posts to the much-neglected issue of debouncing. The logic is pretty much the same here except that I use different (non-inverting) gates here. The reason for that is the need for 3-state outputs as mentioned before.

debouncing_pushbutton_press

Unfortunately the 74HC126 doesn’t have schmitt-triggered inputs so I need to implement the necessary feedback myself via the 680k resistors.

Debouncing something like a pushbutton is quite easy. Just use a relatively long time constant (i.e. large resistors and capacitors) and all will be fine. That will introduce some delay in the output signal but as a rule of thumb anything below 50ms is not noticable. And a time constant of a few milliseconds is totally sufficient so you might end up with something like 10ms of delay. No human user will ever notice it and it’s more than enough to perfectly debounce any switch that I’ve seen.

debouncing_pushbutton_release

With rotary encoders things get much trickier. The basic circuit is exactly the same but choosing the right component values is more difficult. You can’t press a button more than a few times a second but a rotary encoder might produce pulses just milliseconds or even less apart.

debouncing_ccw

So you face the challenge of debouncing the signal while still letting relatively fast transitions pass. If you use a time constant of a few milliseconds like with the push button you will not be able to detect when the encoder is turned quickly.

debouncing_cw2

The data sheet of the Burns encoder I’m using here recommends using two 10k resistors together with a 10nF cap. I’ve increased the value of one resistor to 22k but have otherwise followed that recommendation.  So the time constant is now a few hunderd microseconds.

debouncing_ccw2

Toghether with the positive feedback via the 680k resistors that works very well. I expected to tweak those values a bit but found that they work so well that I just leave them as they are.

debouncing_clean

I’ve inserted plenty of scope screenshots here to give you an idea of what the undebounced and debounced signals look like. Even with the same encoder there’s plenty of variation as you can see. But with the hardware debouncing applied here we get a clean, digital output singal nevertheless.

debouncing_typical

Power consumption

Very low standby power consumption was one of the key design goals. When in low-power mode only the push button pull-up and the 74HC126 is supplied with power. Everything else, the display, the op-amp, the digipot and the pull-up for the rotary encoder are all completely powered off.

As long as the push button is not pressed, no power flows there so the only power consuming device is the 74HC126. Its datasheet specifies a maximum static current consumption of 8 microamps (worst) at room temperature.  There’s no typical figure so that’s all the information I had. When I measured it, this is what I got.

20161012_userinterfacereva_018

That’s 4 nanoamps  at 3.3 volts which is nothing really. Actually the measurement fluctuated between about 0 and 15 nanoamps. I thought something is not hooked up correctly but when I pushed the button the current jumped to 326 microamps which is just what I expected since there is a 10k pull-up resistor conected to that button.

20161012_userinterfacereva_019

So the measurement works and it seems that the 8 microamps given in the data sheet are just a very conservative worst case. I mean CMOS is close to zero-power when static and only a single tri-state gate is active so essentially no current flows. Cool.

Next steps

After the two hardware fixes this user interface works quite as intended. Using the spare gate to supply the rest of the circuit with power was not as good an idea than I thought. On the positive side the debouncing works just perfect with the chosen component values. And as mentioned, the op-amp was not a great choice for the job at hand.

But I like the look and feel of this universal user interface and think the overall concept is good. So there will be a Rev B of this board with those issues solved.

Here you find the eagle files as well as PDFs of the schematic and board. The two errors are already corrected but I haven’t actually built them so check carefully yourself. I’ve also re-exported the gerbers so they, too, already include the fix.

MPPT Solar Charger Testing

20160927_solarcharger_036

In a previous post I have presented a design for an MPPT Solar Charger. In the mean time I have built a prototype and also wrote some software for it. So today I’ll go through my findings of what works well and what needs to be improved. And yes, there are some flaws in the design…

The software is far from final but with the notable exception of USB all the basic functionality has been implemented.

Power Supply

20160904_solarcharger_002

One of my main goals with this design is to archieve very low standby current, somewhere in the tens of microamps. The basis for this is a low-power buck on the basis of a Texas TPS62120 where the microcontroller can switch the output voltage between 2.2 and 3.3 volts nominally. This works as intended. With no load and the output voltage low, the supply consumes 12.9 microamps at 12V input voltage. With the high output voltage the idle current goes up to 14.3uA. Quite a bit of that current is due to the voltage divider that sets the output voltage. The regulator itself consumes about 9uA in both cases.

Microcontroller

20160928_solarcharger_045

The PIC18F26J50 starts up using the primary oscillator’s 8MHz crystal with the internal PLL disabled. It can then switch to 48MHz operation by enabling the PLL or to the secondary oscillator running at 32.768kHz. The latter is always running since it also serves as the clock source to the real-time clock and calender (RTCC). Switching between clock sources as well as the RTCC have been implemented in software and work fine.

I2C Multiplexer and Port Expander

20160928_solarcharger_046

The microcontroller doesn’t have enough GPIO pins so a I2C port expander (Microchip MCP23008) is used to give us another 8 pins. The display is connected via I2C as well but since the display is entirely powered off when not in use, the display cannot be on the same bus. Otherwise it will pull the SCL and SDA lines low and block the bus. The NXP PCA9546 multiplexer takes care of that. Both devices, the mux as well as the port expander work as they should.

Voltage Reference, Temperature Sensors and Fan

20160904_solarcharger_004

There is a total of 3 temperature sensors, one on the board and 2 external ones. The temperature is measured by the PIC directly so it has a 2.5V voltage reference in order to get meaningful results. At room temperature all three temperature sensors deliver very similar results, typically within a few tenth of a degree. Better than expected. The fan output can also be enabled if the on-board temperature gets too high.

Voltage and Current Measurements

20160928_solarcharger_047

The more important measuements, namely the input and output voltages and currents are performed by a MCP3424 4-channel 18-bit ADC. I was already familiar with that type so I quickly got it to work. In this application I don’t use its internal PGA (programmable gain amplifier) or rather I leave the gain at 1. All the measurements are done with 14bit accuracy which is reasonably fast (23ms worst case) and sufficient here.

User Interface

20160904_solarcharger_006

The debouncing of the rotary encoder works ok but I’ll tweak the resistor and capacitor values a bit when I get time. The push button is uncritical but there is a bit too much debouncing for the rotary encoder itself making it miss some very fast turns. But it already performs reasonably well as it is.

The display module is the first real flaw in my design. It has 5 wire connections: GND, VCC, SDA, SCL and Backlight. The idea was to turn the display off by simply cutting off VCC when the display is not needed. When in use, the brightness of the backlight is then controlled by the Backlight PWM signal.

20160905_solarcharger_015

Since the display needs quite a few supporting components (mainly 1uF capacitors) and has no mounting holes I made a little one-sided PCB for it. When I first tried it nothing worked. A ground connection was missing and I didn’t notice that in Eagle because in Eagle it was a double-sided board. That was easily fixed by a short piece of blank wire soldered in place. So far so good.

Unfortunately the display (a Midas MCCOG42005A6W-BNMLWI) still didn’t work. Besides the data sheet being a nightmare it needs to be reset after having powered up. So you need to power it up, wait for a while and then do a reset by pulling its reset pin low. So just pulling the reset pin high with a resistor like I have done won’t work. My solution for now was to connect the backlight signal to the reset pin. So I can now use the display but the backlight brightness is permanently  at it’s maximum.

20160905_solarcharger_017

I already have a new and hopefully better version of this display unit in the making and there will be a separate post on that. My idea is to have a rather universal module that I can use in other projects as well.

USB Charging

20160928_solarcharger_049

The USB charging module works reasonably well. When pulling the full rated current of 2A it gets rather warm but doesn’t overheat. I was able to pull 2.5 amps for a prolonged period of time without any issues. I only had a Samsung A5 to try but at least that phone charged perfectly fast pulling around 1A of current. With that load the module only gets slightly warm.

20160927_solarcharger_038

Turning the USB charger on and off in software also works as planned. This can now even be done via the user interface – see above.

Power Outputs

20160928_solarcharger_053

The 4 power outputs can be controlled in software. In order to save power, the mosfet drivers can be powered off if none of the outputs is on . All that is already implemented in software and the outputs can be turned on and off individually via the user interface.

20160927_solarcharger_037

I plan to implement a low-frequency (say, 100Hz) PWM functionality for these outputs in order to e.g. control some LED lighting but that has not been done yet.

EEPROM

20160927_solarcharger_042

I haven’t implemented any data logging functionality yet but I have written a few library functions for the EEPROM. When the date and time is set via the user interface those values are saved to EEPROM and restored after a reset. Reading from and writing to the EEPROM therefore works.

20160927_solarcharger_041

Solar Charger

Yes, I’ve left the main thing for last. Don’t know why.

20160928_solarcharger_051

When I first assembled the board I noticed that I had ordered the wrong mosfet driver – a MIC4605-2 instead of a MIC4605-1. They are near-identical except the fact that the -1 has two independant inputs while the -2only has one PWM input plus an enable signal. That also works but doesn’t give us the option to run the converter in asynchronous mode. So I’ve unsoldered the chip again and replaced it with the MIC4605-1 that I had in mind when I designed this thing.

20160928_solarcharger_050

As you can see on the photos above, I’m now using a 22uH coil, not a 68uH coil as shown in the schematic. The reason for that is that I’m using a relatively high switching frequency of 48MHz / 256 or 187.5kHz. That high switching frequency enables me to use a lower value inductor which massively increases its current rating while pyhsically being the same size. Since the inductor was the limiting element in this design before this significantly increases the power rating of this solar charger. The previous version was (very conservatively) rated at 30 watts only. With the new 22uH inductor this very similar design can handle something like 75 watts. I need a more powerful power supply to do some serious testing but at 35 watts it’s getting slightly warm at the most. I’ve only done some quick and dirty testing but efficiency at 35 watts is around 97%. That means we are only losing about 1 watt which is the reason the charger barely gets warm.

20160912_solarcharger_026

There will likely be another post focussing only on the charger itself so I won’t go into more details here. The code regarding the buck is extremely basic and potentially dangerous at this point. I’ve killed the bottom mosfet twice due to the not very graceful way the buck turns off. If it turns off while the bottom fet is on, that fet will stay on, effectively shorting the battery to ground. At least that’s my explanation at the moment.

20160927_solarcharger_033

Oh yes, there’s another issue with the buck as well. With the battery at its output there will always be the battery voltage minus a diode drop at its input where the panel is connected. So when there is no sun, the battery is powering the panel. I’ve tried that with a small 30W panel and the panel draws 8mA at 12 volts which several magnitudes more than we are willing to use when the charger is sitting idle. So the next version will have to disconnect the panel when the charger is off. And we will also need to disconnect the voltage divider at the charger’s input when we’re not measuring the voltage, just like we’re doing at the battery.

Summary

There are a lot of features on this board and getting them all to work properly requires quite a bit of work. But most of the heavy lifting has been done so I can now focus on improving the software.

20160912_solarcharger_030

First and foremost I need to work on the way the buck is controlled. First there needs to be a strict and safe procedure how this thing is turned on and off. I’m confident that there won’t be any blown-up mosfets once that’s done. Then I also need to improve the algorithm of how the maximum point of power is tracked. And I also want to implement asynchronous operation at low loads in order to improve efficiency. I’ll spend some time on all these issues next, looking at the signals on a scope and trying to improve things.

But all-in-all I’m quite happy with how how this design has performed so far. Yes, there are some issues but nothing that can’t be fixed with relative ease.

For those of you interested, the code can be found under downloads on the overview page. In my next post we will take a closer look at the display unit / user interface.

Ultrasonic Anemometer Part 28: New hardware tested

20160907_standaloneanemometer_024

I last time proudly presented the new RevB board and got a lot of feedback from people who want one, too. As mentioned I have all the components here to ship up to 10 kits but I was reluctant to send anything until I had the chance to do some hardware testing. Not much had changed since the last revision but I don’t like taking chances on things like this.

20160907_standaloneanemometer_029

In the mean time I managed to do some rudimentary testing and now feel confident to take orders. These tests concern the hardware only. What I said last time about the state of the software still applies. But let me tell you what I’ve been able to test so far.

rxtx_overview

Tests performed so far

  • The PIC32 can be programmed from a PICKit3 via the ICSP header without any issues.
  • Power consumption is as expected. Like the previous version it draws 45mA@12V (programmed) and the other two rails come up with +3.310 and -3.279V, respectively. Also as expected. Regulator stays cool.
  • With the PIC controlling the AXIS, DIRECTION and SIGNAL pins, the transducers receive the 12V signal from the mosfet drivers. HOWEVER: the signals AXIS and DIRECTION are incorrectly labeled both in Eagle as well as on the silk screen. Electrically everything is fine but the names have been confused.
  • The signal from the transducers is properly received (Rec pin on the board) and amplified by a factor of 11 by the first stage of the amplifier (S1 pin on the board).
  • The PIC is able to control the digipot over the internal I2C bus and the second amplifier stage also performs as expected.
  • The zero-crossing detector (ZCD) works.
  • The input to the PIC’s ADC (ADC+ and ADC-) look fine, too. HOWEVER: the labeling on the silk screen is wrong. Eagle is correct, it’s just the silk screen. Plus should be minus and vice-versa. Again, electrically everything is fine.
  • The PIC can communicate (as a slave) with an Arduino UNO connected to the external I2C bus.
  • Communication over USB to a YAT-terminal under Win 7 works.

rxtx_north

rx_closeup

The following has not been tested so far

  • For my tests I still used the transducers already used previously. I believe the ones I ordered last week are of the same type but I haven’t tested them.
  • EEPROM. I haven’t tried the newly added memory yet. I have confirmed that it has power and is connected to the same bus as the digipot so I have no reasons to assume there are issues with it. But testing it would require some software first.
  • The external SPI bus has never been tested, neither on the Rev A board nor with the new one. I don’t expect any problems but I haven’t done any testing so far.

20160907_standaloneanemometer_028

Is there anything important that I forgot to mention? In that case just ask.  A lot still needs to be done but at this point I’m confident that the board has no major flaws and performs much like the prototype.  Want to give it a try? I have some kits left for you.

i2c1_arduino

Continue here to the next post of this series.

Ultrasonic Anemometer Part 27: Ready to take pre-orders

20160903_StandaloneAnemometer_001Good news: the boards from dirtypcbs.com have arrived and look great. I also got all the components for the 11 boards. Why 11? I ordered about 10 (they call it a protopack) and was lucky enough to get 11. Thats dirtypcbs.

Last week I also upgraded my hobbyist Eagle license to a proper Premium LS license which means I can now legally start selling stuff. So I’m basically ready to ship the first kits.

20160903_StandaloneAnemometer_002

Today I assembled one of the boards and it at least looks great. All the footprints are correct and it was a pleasure to solder. Now what I want to do is to run some tests with it just to make sure it works as intended. I didn’t change much since the last version but I want to be sure first.

20160903_StandaloneAnemometer_003

About the kit

There’s one thing I want to be absolutely clear about. At this stage of development the wind meter is not yet ready to be deployed. While I think the hardware is final now, a lot more work is needed to get the software ready. So for the time being this kit is intended for people who want to join the development and testing. I’ve done most of the low-level, register-fiddling stuff but much remains to be done at a higher level. I know there are a lot of people out there with much more experience in signal processing than me and I’m looking forward to work on this challenge together. And a challenge it is. But the PIC32 still has plenty of RAM, Flash and CPU time left to try out new ideas and approaches until we find one that works well.

20160903_StandaloneAnemometer_004

The kit contains the board and all the necessary components. Details can be found in the BOM linked on the overview page. Once assembled it should look precisely like on the photos on this page. But as the name suggests, it comes as a kit, i.e. as components that you have to solder yourself. Most components come in relatively large SOIC packages but there are a few smaller MSOP and SOT-23 packages as well. They can all be soldered with a conventional soldering iron and strain solder just like I’ve done today.

20160903_StandaloneAnemometer_005

The microcontroller is not yet programmed so you will need a suitable programmer. Microchip’s PICKit3 (USD47.95) is the obvious choice here. This is also what I’m using and matches the board’s pinout. All the software (MPLAB X IDE and XC32 compiler) are available for download from Microchip free of charge.

Taking pre-orders now

I’ll start taking pre-orders now but as mentioned I won’t ship the kits until I’ve done some tests with my own board. Once that’s done I’ll let you know and if you’re still interested by then I’ll give you my PayPal details and ship the kits.

Some have mentioned that they already have some ultrasonic tranducers and/or want to try some specific model so you are free to order your kit with or without the transducers.

20160903_StandaloneAnemometer_007

There’s no online shop or anything like that so just use the contact form on the about me page.

Pricing

Now it starts getting interesting. I’ll quote all prices in USD, EUR and CHF.  Choose what’s cheapest or most convenient for you.

  • Kit without transducers: USD 70 / EUR 63 / CHF 69
  • Kit with transducers: USD 95 / EUR 85 / CHF 93

The prices above include worldwide shipping. The kits ship by Swiss Post Priority Mail in a padded envelope.  I’ve used this service before to locations like Brazil or India and never had problems. However, there are no tracking numbers.

Any other questions? Just ask.

20160903_StandaloneAnemometer_006

 

DIY Electronics