Sep 292018
 

So, I’ve been pondering doing a more capable power controller for the purpose of enhancing or even outright replacing the solar controllers I have now on the Solar-powered cloud computing cluster.

The idea started as a straight DC power meter with a Modbus interface, as there’s pretty much nothing on the market.  Lots of proprietary jobbies, or display-only toys, but nothing that will talk an open protocol.  I started designing a circuit.  I thought: it’d be handy to have digital inputs and outputs.

Lots of mains energy meters have them, and they’re handy for switching loads.  My remote reset facility when porting the mainline kernel to the TS-7670 was a digital output on the CET PMC-519.  If I crashed the TS-7670, I basically fired up ipython, loaded pymodbus, connected to a Modbus/TCP gateway, then issued a few write-coil commands to power-cycle the TS-7670.

Often the digital inputs are hooked to water or gas pulse meters to meter usage: you get a pulse every N litres of water or every N cubic metres of gas.

A meter with digital I/O that’s programmable would be just perfect for the job my little power controller is doing.

I could make the channels PWMable, thus be able to step down the voltage.  Put an INA219 on there, and I’d have current measurement and power control.  The idea evolved to putting the INA219 and a MOSFET on a board, so it was a separate module: just to make board layout easier and to reduce the size of the boards.

For a buck converter, you just add an inductor and a few smoothing capacitors.  Better yet, two INA219s and a MCU would let me measure power in, out, and have localised brains.  Thus the idea of a separate, smart module, was born.  For kicks, I’m also adding the ability to boost as well by tacking a boost converter to the end.

The principle is really quite simple.  A buck converter has this topology (source, Wikipedia):

If you swap out that diode for another MOSFET, you get a synchronous buck converter, which looks like this (same Wikipedia article):

It’s worth noting that a MOSFET switch has a body diode that might be exploitable, I’ll have to check.  You drive the two switches with complimentary outputs.  Both these circuits will step down a voltage, which is what I want to do 99% of the time, but it’s also useful to go up .  A boost converter looks like this (source: Wikipedia):

Again, that diode can be replaced with another MOSFET.  This will step up a voltage, but not down.

There are a few options that allow going both ways:

  • Flyback : which uses a transformer and provides galvanic isolation.  The downside is the secondary must take all the output current, and finding a transformer that can do 50A is EXPENSIVE!  So scratch that.  (And no I am not winding my own transformers… tried that back at uni when a lecturer asked us to build a flyback converter.  Bugger that!)
  • SEPIC is basically a boost plus a buck-boost.  Efficiency is not their strong suite apparently, although there are ways to improve it.  I’m not sure the added complexity of two boost converters sandwiching a buck converter is worth it.
  • Ćuk is no good here because it inverts its output, unless you want an isolated one, which is going to be $$$$ because of the transformer needed.  Yes, I’m chickening out!
  • Split-Pi looks real interesting, in that it’s bi-directional.  In the event I ever decide to buy a front-wheel motor for my bicycle, I could use one of these to do regenerative braking and save some wear on my brake pads.  I haven’t seen many schematics for this though, just generalised ones like the one above.
  • Zeta also looks interesting, but it’s pretty unknown, and has a higher parts requirement.  It could be worth looking at.  It’s a close relative of the SEPIC and Ćuk.

The route I’m looking to try first is the 4-switch buck-boost, which looks like this:

The goal will be to have a simple microcontroller-based switch-mode power supply module with the following characteristics:

  • Up to 50A current switching capability
  • 9-30V input voltage range
  • 12-15V output voltage range
  • 250kHz switching frequency

99% of the time, conditions will be:

  • input voltage: 18~20V
  • output voltage: 13.8~14.6V

So I’m thinking we design for a buck converter, then the boost just comes along for the ride.  There’s a handy primer here for designing a buck converter.  For a 20V input and 14.6V output, their formulas suggest a 33µH inductor should cut the mustard. One of these which can handle >50A is not a big or expensive component.

In the above system, we need to be able to drive up two pairs of complementary outputs at high speed.  We can forget the hacker darling ATTiny85, as with 5 pins, it barely has enough to do the SPI interface, let alone talk I²C and drive four MOSFETs.

A good candidate though is the chip I used for the #Toy Synthesizer — the ATTiny861 .

This chip has the same high-speed PWM, and I already know how to drive it.  It doesn’t have a lot of brains, but I think it’ll do.  The challenge will be in-circuit programming.  There are just 3 PWM outputs that don’t clash with ICSP.

Don’t be fooled by the presence of two DI/DO/USCK pins, it’s the one UCI interface, just you can switch which pins it uses.  That’ll be handy for talking I²C, so I’ve earmarked those pins in purple.  The nRESET pin is marked in green, the PWM pins in blue.  When nRESET is pulled low, PB[012] switch to the functions marked in red.

This doesn’t matter for the toy synthesizer as I only need two PWM channels, and so I chose OC1B and OC1D.  Here, I need nOCID (no problem) and nOC1B (uhh oh).

During run-time, I could put my SPI interface on PA[012] and bit-bang the I²C, but I don’t want MOSFETs chattering when flashing new firmware.  Thus, when in reset, I need to inhibit nOC1B somehow.

The other way of doing this is to just forget about nOC1B altogether.  Consider this:

  • When stepping up: SW1 will be held on , SW2 will be held off , and the PWM will drive SW3/SW4.
  • When stepping down: SW3 will be held off , SW4 will be held on , and the PWM will drive SW1/SW2.

We’re only PWMing two MOSFETs at a time, so could get away with just one complementary pair, OC1D/nOC1D.  We ignore OC1B and can now use it for something else.  We just need a means of “selecting” which pair of MOSFETs we’re driving.  A PWM output with 8-bits resolution and 250kHz cycle frequency has a minimum pulse width of about 15ns (1/64MHz).

A SN74AHC244 tri-state buffer will do nicely.  We can use two GPIOs to control the two enable pins to switch the OC1D/nOC1D and a pair of other pins for manual control.  Perhaps PA[01] to select where the PWM signals get routed, and PA[23] to control the non-PWMed MOSFETs.

Due to switching speed requirements, we will need to run the ATTiny861 at 5V.  So maybe make some room for some level shifting of the SPI interface to support 3V master interfaces as this is much lower speed than the PWM output.

This leaves PB3, PB6, PA1 and PA3 free for GPIOs to use however we wish.  Two of these should probably be made part of the host interface, one for chip select (PB3 seems a good choice) and one for an interrupt (maybe PB6).  Add the 5V/0V power rails, and nRESET, and the same interface can be used for ICSP too.

The idea looks doable.  The challenge will be making the control algorithm work within the constraints of the ATTiny861, but given what people have done with the ’85 which has the same core, I’m sure it can be done.

Sep 272018
 

So, the last few days it’s been overcast.  Monday I had a firmware glitch that caused the mains supply to be brought in almost constantly, so I’d disregard that result.

Basically, the moment the battery dropped below ~12.8V for even a brief second, the mains got brought in.  We were just teetering on the edge of 12.8V all day.  I realised that I really did need a delay on firing off the timer, so I’ve re-worked the logic:

  • If battery drops below V_L, start a 1-hour timer
  • If battery rises above V_L, reset the 1-hour timer
  • If the battery drops below V_CL or the timer expires, turn on the mains charger

That got me better results.  It means V_CL can be quite low, without endangering the battery supply, and V_L can be at 12.8V where it basically ensures that the battery is at a good level for everything to operate.

I managed to get through most of Tuesday until about 4PM, there was a bit of a hump which I think was the solar controller trying to extract some power from the panels.  I really need a good sunny day like the previous week to test properly.

This is leading me to consider my monitoring device.  At the moment, it just monitors voltage (crudely) and controls the logic-level enable input on the mains charger.  Nothing more.  It has done that well.

A thought is that maybe I should re-build this as a Modbus-enabled energy meter with control.  This idea has evolved a bit, enough to be its own project actually.  The thought I have now is a more modular design.

If I take the INA219B and a surface-mount current shunt, I have a means to accurately measure input voltage and current.  Two of these, and I can measure the board’s output too.  Stick a small microcontroller in between, some MOSFETs and other parts, and I can have a switchmode power supply module which can report on its input and output power and vary the PWM of the power supply to achieve any desired input or output voltage or current.

The MCU could be the ATTiny24As I’m using, or a ATTiny861.  The latter is attractive as it can do high-speed PWM, but I’m not sure that’s necessary in this application, and I have loads of SOIC ATTiny24As.  (Then again, I also have loads of PDIP ATTiny861s.)

The board would expose the ICSP pins plus two more for interrupt and chip select, allowing for a simple jig for reprogramming.  I haven’t decided on a topology yet, but the split-pi is looking attractive.  I might start with a buck converter first though.

This would talk to a “master” microcontroller which would provide the UI and Modbus interface.  If the brains of the PSU MCU aren’t sufficient, this could do the more grunty calculations too.

This would allow me to swap out the PSU boards to try out different designs.