Akom's Tech Ruminations

Various tech outbursts - code and solutions to practical problems
Hardware Hacks

Adventures in Modifying a UPS for external DC power and LiFePO4 batteries

Posted by Admin • Saturday, June 26. 2021 • Category: Hardware Hacks

I have an ancient APC Smart-UPS 1400 RMNET. It's a very nice UPS, but I have frequent multi-hour power outages and battery life becomes a problem. I have these issues:

  1. Short battery runtime, especially as batteries age
  2. Lead-acid batteries require frequent replacement and quickly lose capacity (and there are 4 of them)
  3. UPS will not accept 110v from a cheap generator (mine is a 700w). This means that I can't do a live power transfer from mains to this generator, and I have to reboot everything to switch

So, I had a few ideas

  • What if I could feed externally-generated DC battery voltage directly to the batteries? For example, via a generator powering a AC-DC power supply
  • What if I could substitute Lithium batteries for Lead-Acid? LiFePO4 would be ideal in this application because weight doesn't matter but the long cycle life does. A 4S pack would have a similar voltage to a 12v lead-acid battery

Hack 1: External DC Power

For this modification I want to be able to plug in an external DC power source. However, I don't want this power source to be always directly connected to the UPS circuitry for fear of... well, a lot of things. So, I'd like to add an input connector, but I want it to be "live" only when there is no mains power. This means adding a relay: UPS modified wiring Now, whenever mains power comes back on, the DC PSU will be instantly disconnected from the UPS. My relay is only rated for 10A, it really should be bigger, but in my usage it won't see high currents. Here is what it looks like in real life: I soldered 12AWG wire directly to the battery lines (hot glue for insulation). The low-current 120v coil wiring is simply scotch-locked on. The relay is hot glued in place as well.

Testing DC input

For my PSU, I got an adjustable 15A switching power supply. I chose 15A because my UPS is normally only running at 6% max load, or an output of about 50 watts, for which I shouldn't need more than 6A. This PSU can do 0-29v or so (24v officially). The next step was to figure out the correct voltage. The UPS itself trickle-charges the batteries at about 28v (maybe 27.7v). So, expecting some minor voltage loss, I set my PSU to 28.5v. This turned out to be a mistake. (also see more below on Low Battery condition) The UPS would trigger a Low Battery alarm (with insane beeping) any time I changed battery voltage. This wasn't consistent, so it may have been due to the fact that the UPS considered the batteries to be low at that time (see below on how that works). UPS Testing with PSU

Silencing the Alarm

Speaking of insane beeping, by default this UPS beeps every 30 seconds or so whenever running on battery. If I want it to run for hours, that's going to drive me insane. Fortunately, I was able to switch BEEPSTATE setting to "L" using apctest. "L" means beep on low battery condition only.

The Bad News about Low Battery Alarm

Now for the bad news. The UPS doesn't determine that the battery is low by monitoring battery voltage! It measures power going in and out over time and counts remaining capacity. The capacity value is based on previously performed (or manually set) calibration of the battery constant. For example, right now, with my worn out batteries, the UPS believes that it has 26 minutes of run time at 6% load. (See more on calibration/battery constant below) This means that if I introduce an unexpected variance, like an unlimited power source, it will still reach low battery condition after the same number of minutes, and apcupsd will want to shut down the computer and the UPS even though the batteries are full. Note though that UPS does not power off on its own, it just triggers the low battery event (which, if BEEPSTATE is set to "L", also means insane beeping). It's apcupsd that decides on shutdown. I see two ways around this:

  1. Set the Battery Constant to something very large. The side effect is that if I am running on just batteries, there will be no warning before power is cut.
  2. Disable low battery shutdown altogether (on computer and UPS). This will have two side effects:
    • Same as with option 1, when running on batteries (no PSU/generator), the connected computer will lose power once the batteries run out
    • The low battery alarm will go off, so I'll need to disable it (set BEEPSTATE to "N")

It may be possible to work around the abrupt shutdown issue by implementing my own shutdown logic. For example: on "Low Battery" event, check the voltage. If it's healthy, ignore the event. Here is a working script for that. This script goes into /etc/apcupsd/doshutdown and /etc/apcupsd/mainsback (can be symlinked). These need to be executable and you can test by running them manually first. See /etc/apcupsd/apccontrol for how this works.

Hack 2: Lithium Batteries

The original lead-acid batteries in this UPS are in a 2S2P configuration (4x12v batteries with a 24v total). They are 7-9Ah rated, so at their peak performance the UPS has 14-18Ah at 24v to work with (336 - 432 watt/hours). Of course, their peak performance only happens once :-). For my experiment, I plan to cram two LiFePO4 batteries (4s/12v packs, two in series), into the body of the UPS. I chose 20A batteries that are too large to fit into the normal battery space, so I'll need to remove some of the metal. If everything works perfectly, I'll have 20Ah at 24v or 480 watt/hours.

Important Questions

  1. Will the BMS in the batteries recover from a low voltage cut-off (LVC) once power comes back on? 

    NO: UPS always outputs a charge voltage when it is on, but you cannot turn the UPS on if the battery voltage isn't present.   This is an open issue.   There are two ways around it: prevent full discharge through conservative eeprom config, or improvise a low current PSU that will wake up the batteries and hopefully won't fry anything.
  2. Will the batteries become unbalanced since they are used in series? 

    Yes, they will become unbalanced over a year or so.  Fortunately, there are very cheap always-on "Battery Equalizers" that solve exactly this problem.  I got one on Amazon for about $20.  They are meant for lead-acid batteries in series, but they don't really care what kind of battery you have, they simply equalize voltage all the time.  They are powered by the batteries.
  3. Will the UPS freak out over high battery voltage and the flat voltage discharge curve?

    No, it seems OK.  
  4. Will the UPS charge these adequately? I don't want it to hit HVC (high voltage cutoff) or under-charge them.

    YES. 27.9 (measured by UPS) is right where I'd like to float charge these, and I'm getting very healthy runtimes starting at that voltage

Initial Testing

I got the cheapest BMS-equipped LiFePO4 packs I could find - two 12v 20Ah "Milady" brand packs from Amazon. These are rated at 20A max discharge, with about 5A recommended for longevity. 5 amps happens to be exactly the load they would be running. As you can see, they do not fit inside (oh well).

Lithium Batteries connected

For my load test, I hooked up a bunch of big fans and got the UPS up to 42% load (that's probably over 20A discharge, so I wouldn't do this a lot). After 30 minutes on batteries (starting at 27.9v), voltage under load was 24.4v, and no-load 26.0 (that's 3.25v per cell, which is at least 50%). With my measly 6% load, I should have 6-7 hours of backup time! Over time, I hope to answer the other questions I raised above.

Resetting the UPS Battery Constant

My UPS, as I already mentioned, is stuck on "my batteries have 26 minutes of capacity". Calibration didn't work. Fortunately, there is a way to set the constant manually with apctest. My UPS had it set to 1E, which isn't even on the chart. I first set the constant back to the normal value for the SU1400RM (hex: 89). Surprise, surprise, that got me about 137 estimated runtime minutes, which is 89 converted from hex to decimal. My original 1E translates to "30", which is close to my 26 minutes. I then tried higher values and settled on a conservative value of F1, which is 241 in decimal. The UPS now reports about 255 minutes of estimated battery life, which is probably good enough to let it manage itself. Now that this is fixed, I could run calibration using apctest, except that calibration requires 30%+ load, which is probably too stressful for my batteries. I can just leave it set to 255 minutes, or use the modifications mentioned earlier (disable low battery shutdown and alarm).

0 Trackbacks

  1. No Trackbacks


Display comments as (Linear | Threaded)
  1. No comments

Add Comment

You can use [geshi lang=lang_name [,ln={y|n}]][/geshi] tags to embed source code snippets.
Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
Markdown format allowed

Submitted comments will be subject to moderation before being displayed.