APC Smart-UPS 1500 and 1000: an FT232RL COM adapter, because USB cannot calibrate
Our APC Smart-UPS 1500 RM and Smart-UPS 1000 are connected to the computer with a USB cable. The cable is fine for status, but not every command works over it. Runtime calibration, for one, refuses to start over USB:
$ upscmd -u admin ups1500 calibrate.start
Smart-UPS 1500 RM calibrate.start: CMD-NOT-SUPPORTED
Over USB the UPS acts as a standard USB power device (HID), and that command set simply has no calibration. The full command set is only available on the COM port, where the UPS speaks APC's own protocol (Smart). Hardly any computer has a COM port these days, so we build a USB → COM adapter around an FT232RL chip. For the connector on the UPS side we use a ready-made one from an old motherboard: a COM port bracket, or the DB9 itself from the rear panel.
This article has two parts.
Part 1. Theory — why USB cannot calibrate, which commands work where, and three adapter wirings for any parts: a MAX3232 module, two NPN or two PNP transistors.
Part 2. Practice — how we built the adapter from old motherboard parts: photos of the parts, the circuit with our parts and the perfboard layout.
Part 1. Theory
How the UPS talks to the computer, what the adapter needs and how all three wirings work. These sections apply to any parts; how we actually built the adapter is in part 2.
Three ways to connect
| Connection | How the UPS talks | What it can do |
|---|---|---|
| USB cable | standard USB power device (HID) | status, self-test, shutdown; no calibration |
| COM port (DB9) | APC Smart protocol, 2400 bps | everything: calibration, tests, shutdown, every setting stored in the UPS |
| AP9617 network card (in the SmartSlot) | the card talks to the UPS in the Smart protocol and gives you a web interface, SNMP and telnet | calibration, self-test, shutdown, the main settings |
We never use USB and COM at the same time: unplug the USB cable while you work over COM.
Which commands work where
The USB and COM columns list NUT commands (upscmd): the usbhid-ups driver handles them over USB, apcsmart over COM. For COM, the Smart protocol letter is in brackets; you can also type it by hand in a terminal. upscmd -l <UPS name> shows the exact list for your UPS.
| Action | COM (Smart) | USB (HID) | AP9617 card |
|---|---|---|---|
| runtime calibration | calibrate.start, calibrate.stop (D) | none: CMD-NOT-SUPPORTED | yes |
| battery self-test | test.battery.start, test.battery.stop (W) | test.battery.start.quick, test.battery.start.deep, test.battery.stop | yes |
| LED and beeper test | test.panel.start (A) | test.panel.start, test.panel.stop | not checked |
| simulate a mains failure | test.failure.start (U) | none | not checked |
| turn the output on | load.on | load.on.delay (with a delay) | yes |
| turn the output off at once | load.off (Z twice) | load.off.delay (with a delay) | yes |
| shut down and restart when mains returns | shutdown.return (S) | shutdown.return | yes |
| shut down and stay off | shutdown.stayoff (K twice) | depends on the driver, check upscmd -l | yes |
| shut down and restart after a set time | @nnn in a terminal (nnn in tenths of an hour) | shutdown.reboot (after 10 s) | yes |
| cancel a pending shutdown | byte 0x7F in a terminal | shutdown.stop | not checked |
| bypass mode | bypass.start, bypass.stop (^), only on models with a bypass | none | only on models with a bypass |
| beeper | setting k in a terminal | beeper.enable, beeper.disable, beeper.mute | yes |
In NUT over COM, load.off, shutdown.return and shutdown.stayoff have to be sent twice: the second time no sooner than 3 s and no later than 15 s after the first.
Settings stored in the UPS:
| Setting | COM (Smart) | USB (HID, upsrw) | AP9617 card |
|---|---|---|---|
| number of external battery packs | > | none | not checked |
| mains limits for switching to battery | l, u | input.transfer.low, input.transfer.high | yes |
| mains sensitivity | s | input.sensitivity | yes |
| battery date | x (date of the last replacement) | battery.mfr.date (NUT calls it the manufacture date) | yes |
| "battery low" warning | q | battery.runtime.low | yes |
| shutdown and startup delays | p, r | ups.delay.shutdown, ups.delay.start | yes |
| voltmeter calibration and battery constant | only in PROG mode over COM | none | none |
The full list of Smart protocol letters with their replies is in the article about the APC Smart-UPS on a LiFePO4 battery.
How many decimal places
COM gives the most precise numbers: the Smart protocol returns them as text with a fixed number of digits.
| Value | COM (Smart) | USB (HID) | AP9617 card |
|---|---|---|---|
| battery voltage | hundredths: 27.40 | depends on the UPS firmware, check upsc | not checked |
| mains frequency | hundredths: 50.00 | depends on the UPS firmware | not checked |
| input and output voltage | tenths: 230.4 | depends on the UPS firmware | not checked |
| load, % | tenths: 012.3 | whole numbers | not checked |
| battery charge, % | tenths: 100.0 | whole numbers | not checked |
| internal temperature, °C | tenths: 030.1 | depends on the UPS firmware | not checked |
| runtime estimate | whole minutes: 0117: | whole seconds | not checked |
- COM is guaranteed to give hundredths wherever the protocol has them: battery voltage and mains frequency.
- USB: the USB power device standard reports charge and load as whole percentages. Everything else comes with whatever precision the UPS firmware uses.
upsc ups1500shows what your NUT actually sees. - The AP9617 card reads the values from the UPS over the same Smart protocol, but we have not yet checked how many digits it keeps on its web page and in SNMP. APC's regular SNMP values are whole numbers; the more precise ones, in tenths, live in a separate part of the MIB, and not every card firmware has it. Check with
snmpwalkon your card.
What you need
| Part | What for |
|---|---|
| an FT232RL module with a 5V / 3.3V jumper | USB → serial port with logic levels (TTL) |
| a level converter: a MAX3232 module (wiring 1) or two transistors, 4–5 resistors and 2 diodes (wiring 2 or 3) | converts TTL into the RS-232 levels the UPS understands |
| a COM port bracket from an old motherboard | a ready-made male DB9 that fits the UPS socket, plus a 2×5 header for the wires |
| Dupont jumper wires: 4 female–female and 3 male–female (for wiring 1) | female–female between the modules; male–female from the MAX3232 module into the bracket header, which is itself a socket |
| a multimeter | to trace the bracket wiring and check voltages and transistors |
Why the FT232RL cannot go straight to the UPS. The FT232RL outputs TTL: an idle line sits at +5 V (or +3.3 V), and a "zero" is 0 V. RS-232 is inverted: an idle line is negative, a "zero" is a positive voltage, and a UPS swings it by up to 10–12 V. The UPS will not understand a TTL signal, and the voltage from the UPS can damage the FT232RL input: its pins only take voltages between ground and about 5.5 V. The converter, a MAX3232 module or two transistors, handles both the inversion and the levels.
To check it yourself: UPS switched on, multimeter on DC volts, black probe on pin 9 of the UPS socket (it is connected to the case), red probe on pins 1 and 2 in turn. On our Smart-UPS 1500 RM one pin read 0 V and the other 11.3 V. Anything above 5.5 V, positive or negative, means RS-232, and an FT232RL module must not be wired straight to such a line. The converter reads both that and a zero idle voltage correctly, so we fit it either way.
What about cables that "work directly"? Write-ups of home-made APC cables sometimes say "wired it straight in and it works". Look closer and TTL never goes straight to the UPS. Either people take a ready-made USB → COM adapter with a DB9 (a PL2303 one, say), which has an RS-232 converter chip (SP3243 or similar) next to the USB chip, remove the DB9 and solder the wires on after the converter. Or they build the converter from two transistors, as in wiring 2 and wiring 3 below. The quick test: if the adapter board has no second chip besides the USB one, the adapter's pins carry TTL.
5 V or 3.3 V
| Where | Which voltage |
|---|---|
| jumper on the FT232RL, wiring 1 (MAX3232) | 5V (3.3V works too; what matters is that the MAX3232 runs from the same voltage) |
| jumper on the FT232RL, wiring 2 or 3 (transistors) | 5V only: the UPS then gets about +3.5–4 V; with 3.3V it would be only about +2–2.5 V, on the edge of the UPS receiver threshold (up to 2.4 V) |
| MAX3232 supply | from the VCC pin of the FT232RL module, i.e. the same 5 V |
| lines to the UPS | RS-232, plus or minus a few volts; the MAX3232 makes them from its 5 V supply |
| on the COM bracket | no power at all: only data and ground go to the UPS |
Why 5V: the VCC pin of the FT232RL module then passes 5 V straight from USB. With the jumper on 3.3V, the same pin is fed by the FT232RL's internal regulator (up to 50 mA). That is enough for the MAX3232, but with less headroom. The logic levels between the FT232RL and the MAX3232 match in both cases, because both chips run from the same voltage.
⚠ Use a MAX3232, not a MAX232: the MAX232 is designed for 5 V only, while the MAX3232 works from 3 to 5.5 V.
Wiring 1: a MAX3232 module
| FT232RL | MAX3232 | COM bracket, DB9 pin | In the UPS |
|---|---|---|---|
| VCC (5 V) | VCC (pin 16) | — | — |
| GND | GND (pin 15) | 9 | ground |
| TXD | T1IN (11) → T1OUT (14) | 1 | UPS receive |
| RXD | R1OUT (12) ← R1IN (13) | 2 | UPS transmit |
- The pin numbers are for the MAX3232 chip itself. Modules usually label their pins TXD / RXD on the TTL side and on the RS-232 side; go by the labels on your module.
- If the MAX3232 module has its own DB9 connector, take the signals from the pads, not from that connector: its pinout differs from module to module.
- Leave DTR, RTS, CTS, DSR and DCD unconnected. In some APC cables these lines control UPS shutdown, and the Smart protocol does not need them.
- This is the same pinout as APC's own 940-0024C cable: the computer transmits to pin 1 of the UPS, receives from pin 2, and ground is pin 9. An ordinary straight-through COM cable will not work here.
The COM port bracket. The male DB9 on the bracket plugs straight into the UPS socket, so pins 1, 2 and 9 in the diagram are also the UPS pins. A ribbon cable runs from the connector to a 2×5 header socket (the one that fits onto the motherboard pins). How the DB9 pins map to the header holes depends on the board maker, so:
- Set the multimeter to continuity.
- Put one probe on pin 1 of the DB9 (the numbers are moulded into the plastic next to the pins) and find the header hole that beeps with the other. Do the same for pins 2 and 9.
- Mark those three holes: the wires from the MAX3232 go into them.
There are two layouts in the wild, so check yours either way. Intel (most boards of the last twenty years): hole N is DB9 pin N, so DB9-1 → hole 1, DB9-2 → hole 2, DB9-9 → hole 9. DTK (older boards):
| Header hole | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|
| DB9 pin | 1 | 6 | 2 | 7 | 3 | 8 | 4 | 9 | 5 |
With that layout: DB9-1 → hole 1, DB9-2 → hole 3, DB9-9 → hole 8.
No soldering and no MAX3232: you can buy a ready-made FT232RL USB → RS-232 cable with a DB9 connector; it already has a level converter inside. Then all you need towards the UPS is a three-wire adapter: cable pin 2 to UPS pin 2, 3 to 1, 5 to 9.
Wiring 2: two NPN transistors
If you have no MAX3232 module, you can build the converter from two transistors that are easy to salvage from old boards. Transistor Q1 carries the signal from the UPS to the FT232RL, Q2 from the FT232RL to the UPS. Each of them also inverts the signal, so there is no need to turn inversion on anywhere else.
| Part | Qty | Substitute |
|---|---|---|
| Q1, Q2 — small-signal NPN transistor | 2 | any from Which transistors will do |
| R1, R2, R3 — 10 kΩ resistor | 3 | 4.7–22 kΩ |
| R4 — 1 kΩ resistor | 1 | 680 Ω – 1.5 kΩ |
| D1, D2 — 1N4148 diode | 2 | 1N4001–1N4007 or any other small silicon diode |
| From | Through | To |
|---|---|---|
| UPS pin 2 (UPS transmit) | R1 | Q1 base |
| ground | D1, stripe towards the base | Q1 base |
| Q1 emitter | — | ground |
| Q1 collector | — | FT232RL RXD |
| FT232RL VCC | R2 | Q1 collector |
| FT232RL TXD | R3 | Q2 base |
| Q2 emitter | — | ground |
| Q2 collector | — | UPS pin 1 (UPS receive) |
| FT232RL VCC | R4, then D2 with the stripe towards the collector | Q2 collector |
| FT232RL GND | — | UPS pin 9 |
Why the transistors are needed
The UPS and the FT232RL send the same bytes, but at different voltages:
| Side | "1" (and idle) | "0" | What the input withstands |
|---|---|---|---|
| UPS, RS-232 | −5 to −12 V | +5 to +12 V | ±15 V and more |
| FT232RL, TTL (5 V supply) | +5 V | 0 V | only 0 to 5.5 V |
So the converter has two jobs: shift the levels (±12 V ↔ 0 / 5 V) and invert the signal, because in RS-232 a "1" is negative and in TTL it is positive. A MAX3232 does this inside the chip; here two transistors do it, one for each direction.
Here a transistor is a switch controlled by a small base current. An NPN transistor turns on when its base is about 0.6 V above its emitter: the collector is then connected to the emitter, which in this circuit is ground. When it is less, the transistor is off (the switch is open). The resistor in front of the base limits that current to about 1 mA, so the input can safely take 12 V.
That gives the two properties the circuit relies on:
- The output takes its voltage from its own supply, not from the input. The switch only connects or disconnects; the output voltage comes from the module's +5 V through a resistor. That is how ±12 V from the UPS becomes 0 / 5 V for the FT232RL, and 0 / 5 V from the FT232RL becomes roughly 0 / +3.5–4 V for the UPS.
- The switch inverts the signal: voltage on the base gives 0 V at the output, no voltage gives +5 V. That is exactly the inversion RS-232 needs, so nothing has to be turned on in software or in the driver.
What happens in wiring 2
Receive: UPS → computer (Q1).
| What the UPS sends | UPS pin 2 | Q1 | FT232RL RXD | What the FT232RL gets |
|---|---|---|---|---|
| idle or "1" | −5 to −12 V | off | +5 V through R2 | "1" |
| "0" | +5 to +12 V | on | ≈ 0 V (Q1 to ground) | "0" |
Transmit: computer → UPS (Q2).
| What the FT232RL sends | FT232RL TXD | Q2 | UPS pin 1 | What the UPS gets |
|---|---|---|---|---|
| idle or "1" | +5 V | on | ≈ 0 V (Q2 to ground) | "1" |
| "0" | 0 V | off | ≈ +3.5–4 V through R4 and D2 | "0" |
There is no real negative voltage on pin 1, but an RS-232 receiver treats anything above its threshold (1 to 2.4 V, depending on the chip) as a "0" and about 0 V as idle. The standard leaves −3 to +3 V undefined, but real receivers behave this way, so +3.5–4 V is read correctly. Most home-made transistor cables rely on this.
What each part does:
- R1 (10 kΩ) limits the base current of Q1 and the current the circuit draws from the UPS line: about 1 mA at +12 V.
- D1 protects Q1. When the line is negative, D1 conducts and keeps the base from going below −0.6 V. Without it the base–emitter junction would see up to −12 V in reverse, and it only takes about 5 V.
- Q1 is the receive switch: when on, it pulls RXD to ground.
- R2 (10 kΩ) pulls RXD up to +5 V while Q1 is off. Without it only the FT232RL's weak internal pull-up (about 200 kΩ) would hold RXD, which is too little against noise.
- R3 (10 kΩ) limits the base current of Q2 and the current drawn from the TXD pin: about 0.4 mA.
- Q2 is the transmit switch: when on, it holds UPS pin 1 at ground.
- R4 (1 kΩ) feeds the module's +5 V to UPS pin 1 while Q2 is off. It has to be 1 kΩ, not 10: the UPS receiver loads the line itself (3–7 kΩ to ground), and through 10 kΩ only about 1.5 V would reach it.
- D2 lets current flow only from R4 to the UPS and, if more than +5 V ever appears on pin 1 (say, the cable is plugged in wrong), keeps it out of the FT232RL module's supply.
- Ground (module GND to UPS pin 9) is the common reference: without it the voltages on the two sides mean nothing, and nothing works.
The connector to the UPS is the same COM bracket as in wiring 1: find pins 1, 2 and 9 on the header the same way.
Wiring 3: two PNP transistors
PNP transistors work too, for example the PMBT2907A in a SOT-23 package. The circuit mirrors wiring 2: the emitters go to +5 V, and the resistors that set the idle state go to ground. Do not put PNP transistors into wiring 2, or NPN ones into wiring 3: they will not work.
| Part | Qty | Substitute |
|---|---|---|
| Q1, Q2 — small-signal PNP transistor | 2 | any from Which transistors will do |
| R1–R5 — 10 kΩ resistor | 5 | 4.7–22 kΩ |
| D1, D2 — 1N4148 diode | 2 | 1N4001–1N4007 or any other small silicon diode |
| From | Through | To |
|---|---|---|
| FT232RL VCC | — | Q1 emitter |
| UPS pin 2 (UPS transmit) | R1 | Q1 base |
| Q1 base | R5 | Q1 emitter (VCC) |
| Q1 base | D1, stripe towards VCC | FT232RL VCC |
| Q1 collector | — | FT232RL RXD |
| Q1 collector | R2 | ground |
| FT232RL VCC | — | Q2 emitter |
| FT232RL TXD | R3 | Q2 base |
| Q2 collector | D2, stripe towards the UPS | UPS pin 1 (UPS receive) |
| UPS pin 1 | R4 | ground |
| FT232RL GND | — | UPS pin 9 |
What happens in wiring 3
A PNP transistor is the mirror image of an NPN one: it turns on when its base is about 0.6 V below its emitter. Here the emitters are tied to +5 V, so a transistor that is on connects the collector to +5 V rather than to ground. The signal is still inverted: low voltage at the input gives +5 V at the output.
Receive: UPS → computer (Q1).
| What the UPS sends | UPS pin 2 | Q1 | FT232RL RXD | What the FT232RL gets |
|---|---|---|---|---|
| idle or "1" | −5 to −12 V | on | +5 V (Q1 from VCC) | "1" |
| "0" | +5 to +12 V | off | ≈ 0 V through R2 | "0" |
Q1 stays on as long as the line is below about +4 V, so both at the negative idle voltage and at zero.
Transmit: computer → UPS (Q2).
| What the FT232RL sends | FT232RL TXD | Q2 | UPS pin 1 | What the UPS gets |
|---|---|---|---|---|
| idle or "1" | +5 V | off | ≈ 0 V through R4 | "1" |
| "0" | 0 V | on | ≈ +4 V (from VCC via D2) | "0" |
What each part does:
- R1 (10 kΩ) limits the base current of Q1 and the current the circuit draws from the UPS line.
- R5 (10 kΩ, Q1 base to emitter) keeps Q1 off when the line is at +4 V or more. Without it, Q1 would stay on during the loopback test (see below).
- D1 (from the Q1 base to +5 V) protects Q1. Without D1, +12 V on the line would lift the base to about +8.5 V (R1 and R5 split the voltage in half), 3.5 V above the emitter. With up to +15 V on the line, or with R1 smaller than R5, that reaches 5 V or more, and a PMBT2907A only takes 5 V in reverse. D1 keeps the base from rising above +5.6 V and diverts the excess into the module supply.
- Q1 is the receive switch: when on, it puts +5 V on RXD.
- R2 (10 kΩ) pulls RXD to ground while Q1 is off.
- R3 (10 kΩ) limits the base current of Q2 and the current drawn from the TXD pin.
- Q2 is the transmit switch: when on, it sends +5 V towards the UPS.
- D2 lets current flow only from Q2 to the UPS and stops a positive voltage on UPS pin 1 from reaching the TXD pin through Q2.
- R4 (10 kΩ) holds UPS pin 1 at 0 V while Q2 is off. 10 kΩ is enough here, because the +4 V comes from Q2 when it is on, not through the resistor.
- Ground (module GND to UPS pin 9) is the common reference, as in wiring 2.
Which transistors will do
You need small-signal transistors, the kind boards carry by the hundred. The currents here are below 2 mA, so almost any of them will do.
| Type | Through-hole | SMD, code on the package |
|---|---|---|
| NPN — for wiring 2 | BC547, BC548, BC546, BC337, 2N3904, 2N2222, S9013, S9014, S8050, KT315 | 1AM (MMBT3904), 1F and 1G (BC847), 1P (MMBT2222A), J3 (S9013), J6 (S9014), Y1 (SS8050) |
| PNP — for wiring 3 | 2N2907, BC557, BC558, BC327, 2N3906, S9012, S8550, KT361 | 2F (PMBT2907A, MMBT2907A), 2A (MMBT3906), 3F and 3G (BC857) |
SMD codes often carry an extra factory letter: a PMBT2907A, for instance, may be marked t2F.
To identify a salvaged transistor with a multimeter in diode mode:
- Put one probe on any pin and touch the other two in turn with the second probe. Look for the pin from which the meter reads 0.6–0.7 V to both of the others: that is the base.
- If the red probe was on the base, the transistor is NPN; if the black one was, it is PNP.
- Emitter and collector are best told apart with the multimeter's hFE socket or by looking the part up in its datasheet (which also lists the SMD code).
⚠ TO-92 pin order varies. Holding the transistor flat side towards you, legs down, a BC547 reads collector, base, emitter from left to right, while a 2N3904 or S9013 reads emitter, base, collector. Check your part before soldering.
SOT-23 (the PMBT2907A and most SMD transistors): lay it with the marking towards you and the single leg pointing up. The top leg is the collector (3), the bottom left is the base (1), the bottom right is the emitter (2). The package is tiny: glue it onto a scrap of board and solder thin wires to its legs.
Testing
First without the UPS:
- Wiring 2 or 3 only. Jumper on 5V, module in USB, UPS not connected. Black probe on ground: the wire to UPS pin 1 should read about 0 V. RXD should read about +5 V in wiring 2 and about 0 V in wiring 3: without the UPS, R5 keeps Q1 off.
- Loopback: connect the wires that go to UPS pins 1 and 2 to each other, and open a terminal (settings in step 3 of "Then with the UPS"). Whatever you type should come back on screen. If it does, both transmit and receive work. Same for wiring 1: join the MAX3232 module pins that go to pins 1 and 2.
Then with the UPS:
- FT232RL module in USB. Linux shows
/dev/ttyUSB0; Windows adds a new COM port in Device Manager. - Unplug the UPS USB cable and plug the bracket into the UPS COM socket.
- Terminal: 2400 bps, 8 data bits, no parity, 1 stop bit, no flow control. Linux:
screen /dev/ttyUSB0 2400; Windows: PuTTY, Serial, your COM port, 2400. - Press
Y(no Enter): the UPS should replySM. ThenBgives the battery voltage andfthe charge. - Nothing comes back? Swap the wires on pins 1 and 2: that is the most common mistake.
With NUT (Linux), in /etc/nut/ups.conf:
[ups1500]
driver = apcsmart
port = /dev/ttyUSB0
After restarting NUT, start the calibration:
upscmd -u admin ups1500 calibrate.start
The UPS starts a calibration only with a fully charged battery and a steady load. How we calibrated ours and what to watch is in the article about calibrating the APC Smart-UPS 1000 batteries.
Several UPSes and identical adapters
Two FT232RL adapters on one computer look identical, and after a reboot /dev/ttyUSB0 and /dev/ttyUSB1 may swap places. NUT then polls the wrong UPS. Tell them apart by the serial number of the FT232RL chip: every genuine FT232RL has its own, stored in the chip's memory.
Linux. Each adapter gets a permanent name that includes its serial number:
$ ls -l /dev/serial/by-id/
usb-FTDI_FT232R_USB_UART_XXXXXXXX-if00-port0 -> ../../ttyUSB0
usb-FTDI_FT232R_USB_UART_YYYYYYYY-if00-port0 -> ../../ttyUSB1
Put that name in ups.conf instead of /dev/ttyUSB0:
[ups1500]
driver = apcsmart
port = /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_XXXXXXXX-if00-port0
[ups1000]
driver = apcsmart
port = /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_YYYYYYYY-if00-port0
To see just the serial number: udevadm info -q property -n /dev/ttyUSB0 | grep ID_SERIAL_SHORT.
Windows. The FTDI driver remembers the COM port number by the adapter's serial number: the same adapter gets the same COM port in any USB socket. You can see the serial number in Device Manager: the port → Properties → Details → "Device instance path".
⚠ Cheap FT232RL clones often carry the same serial number on every unit. Then /dev/serial/by-id/ shows only one name for two adapters. What to do:
- give each one its own number with FTDI's FT_PROG (Windows) or
ftdi_eeprom(Linux); on clones this does not always work; - or tie each adapter to a USB socket: the
/dev/serial/by-path/…name depends on which socket the adapter is in, so keep them in the same sockets.
Make sure it really is the right UPS. Every UPS has its own serial number as well: the n command in a terminal, or ups.serial in NUT, next to ups.model. After setting things up, check that ups1500 really reports a Smart-UPS 1500 RM. Over USB, the usbhid-ups driver can pick a UPS by exactly that number: the serial = … line in ups.conf.
Do not publish the serial numbers of your UPSes or adapters: the examples above use XXXXXXXX and YYYYYYYY instead.
Part 2. Practice: building the adapter from old motherboard parts
Here is how we built wiring 2 (two NPN transistors) from what was at hand. The transistors, diodes, resistors and the DB9 connector were all salvaged from an old motherboard, so none of them had to be bought; only the FT232RL module did not come from the motherboard. How the circuit works and what can replace each part is in part 1.
Parts
| Part | What we used | How we checked it |
|---|---|---|
| Q1, Q2 | MMBT2222A (NPN) in a SOT-23 package, marking code 1P; there may be one more character next to it, a date code | transistor tester: both NPN, hFE 223 and 227, Vbe 0.62 and 0.58 V |
| D1, D2 | glass SMD diodes (MiniMELF): orange body, the black band is the cathode | multimeter in diode mode: 0.6 V forward |
| R1, R2, R3 | 10 kΩ SMD resistors | multimeter |
| R4 | 1 kΩ SMD resistor | multimeter |
| connector to the UPS | male DB9 from the rear panel of the same motherboard (right-angle, board-mount) | pin numbers are moulded into the plastic |
| FT232RL module | red board with a mini-USB socket, a 5V / 3.3V jumper and a 6-pin header | — |
- The numbers on the tester screen are the tester's own sockets. The single SOT-23 leg sits in socket 2, and the tester says that is the collector; the bottom left leg (socket 1) is the base, the bottom right leg (socket 3) the emitter. That matches the standard SOT-23 pinout (1 base, 2 emitter, 3 collector); only the numbers differ. Solder by leg position, not by the digits on the screen.
- The DB9 from the motherboard replaces the COM bracket: there are no header holes to trace, the wires go straight onto legs 1, 2 and 9. From the leg side the numbering is mirrored, so go by the numbers on the plastic.
- FT232RL module: of the 6-pin header you only need VCC, GND, TXD and RXD; leave DTR and CTS unconnected. Jumper on 5V.
The circuit with our parts
R4 must be 1 kΩ; the rest are 10 kΩ. R4 feeds the module's +5 V into the UPS input, and the RS-232 receiver loads the line itself, typically 3–7 kΩ to ground. With 1 kΩ, pin 1 sees about +3.5–4 V; with 10 kΩ only about 1.5 V, and the UPS may not recognise a "0". Anything from 680 Ω to 1.5 kΩ will do: with 2.2 kΩ and a weak UPS receiver there would be only about 2.5 V, right at the threshold.
Perfboard layout
To keep the adapter small, the parts sit close together on 2.54 mm perfboard: 10 × 5 holes, about 25 × 13 mm. The +5 V rail runs along the top, the ground rail along the bottom, with the two stages between them: receive (Q1) on the left, transmit (Q2) on the right.
- The transistors lie marking side up between the pads: the collector goes to the pad above the package, the base and emitter to the neighbouring pads at the bottom left and right. SOT-23 legs are tiny, so connect them to the pads with a blob of solder or a short piece of thin wire.
- Resistors and diodes sit between two neighbouring pads. If a small SMD resistor does not reach the second pad, extend it with a short piece of wire.
- The TXD wire passes over the ground rail, so use insulated wire.
- Before powering up for the first time, check with a multimeter that the +5 V rail is not shorted to the ground rail.
The finished adapter
The board with the parts is soldered straight onto the legs of the DB9, and the FT232RL module onto the other side of the board. The result is one compact block with no cables between the parts.
First power-up: "Driver not connected" at first, then it worked
Linux saw the adapter straight away:
$ lsusb
… ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC
$ ls -l /dev/serial/by-id/
usb-FTDI_FT232R_USB_UART_XXXXXXXX-if00-port0 -> ../../ttyUSB2
But NUT got no data from the UPS:
$ upsc apc1500
Error: Driver not connected
This message means the UPS driver is not running, but it does not say why. There are two possible causes: the driver never started because of the configuration, or it started, got no reply from the UPS and exited, in which case the adapter is to blame. As it turned out, the adapter was fine, and the cause was most likely the configuration.
1. We checked the configuration (on CentOS the file is in /etc/ups/, on Debian and Ubuntu in /etc/nut/):
$ grep -A4 apc1500 /etc/ups/ups.conf
[apc1500]
pollfreq = 5
##09-11-2026## driver = usbhid-ups
##09-11-2026## port = auto
…
The old USB lines were already commented out, but the new COM port lines were not there yet. The section had no driver left, so there was nothing to start.
2. We added the COM port driver and the port by the FT232RL serial number rather than ttyUSB2, because the ttyUSB number can change after a reboot:
[apc1500]
driver = apcsmart
port = /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_XXXXXXXX-if00-port0
pollinterval = 2
desc = "Smart-UPS 1500 RM"
3. We restarted the driver: systemctl restart nut-driver. A manual check, upsdrvctl -DD start apc1500, reported "Duplicate driver instance detected!". So the driver was already running, and the manual start stopped it and launched its own copy.
4. One more systemctl restart nut-driver, so that systemd manages the driver again, and the data came in:
$ upsc apc1500
battery.voltage: 27.67
device.model: Smart-UPS 1500 RM
driver.name: apcsmart
input.frequency: 50.00
input.voltage: 220.3
output.voltage: 220.3
ups.firmware: 617.3.I
ups.load: 022.7
ups.serial: ASXXXXXXXXXX(
ups.status: OL
ups.temperature: 026.5
While troubleshooting, the adapter was also unplugged from USB and plugged back in. So we cannot say for sure which step fixed it. Most likely it was the correct section in ups.conf plus restarting the driver after the edit.
What is worth remembering:
- "Driver not connected": check
ups.confand restart the driver first, and only then look for a fault in the soldering. - Restart the driver after every edit to
ups.conf:systemctl restart nut-driver. - "Duplicate driver instance detected!" means the driver is already running; it is not an adapter fault.
A bracket in the serial number. Over the COM port the UPS reported its serial number with an extra bracket at the end, ASXXXXXXXXXX(, although over USB the same UPS showed it without one. The value is the same on every poll, so it is not line noise: this is how the UPS answers, or how the driver reads it. If your software identifies a UPS by its serial number, compare letters and digits only. Otherwise it will decide the UPS has been replaced.
Article changelog
| Date | What changed |
|---|---|
| 2026-11-08 | First version: commands over COM, USB and the AP9617 network card, value precision, the FT232RL + MAX3232 adapter wiring, several UPSes on one computer. |
| 2026-11-08 | Two ways to wire it without a MAX3232: two NPN transistors or two PNP transistors; which transistors will do and how to identify them; a loopback test before connecting the UPS; why cables that "work directly" actually have a converter; how to confirm with a multimeter that the FT232RL cannot go straight to the UPS. |
| 2026-11-08 | "Our build" section: wiring 2 with parts from an old motherboard (MMBT2222A "1P", glass diodes, SMD resistors), a practical diagram with SOT-23 leg numbers, why R4 must be 1 kΩ, how to read the numbers on a transistor tester; a DB9 from the motherboard instead of a COM bracket. |
| 2026-11-08 | The article is split into two parts, theory and practice. Practice adds captioned photos of the parts from an old motherboard, the circuit with our parts and a perfboard layout. |
| 2026-11-09 | "The finished adapter": photos of the assembled adapter; first power-up: "Driver not connected" at first because of the NUT configuration, then the UPS answers after fixing ups.conf and restarting the driver; a bracket in the serial number over COM. |
| 2026-11-09 | The article is finished and published: the practice part proofread; clarified why "Driver not connected" happens (configuration or the adapter). |
| 2026-11-09 | Wirings 2 and 3: why the transistors are there and how a transistor switch works, "input → output" tables for both directions, what each part does; the voltage reaching the UPS (+3.5–4 V) and the R4 range (680 Ω – 1.5 kΩ) corrected. |