Reading MM440 VFD Data via USS Protocol on 8051 Microcontroller

David Krause12 min read
SiemensTutorial / How-toVFD / Drives
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

1. Problem Overview

Reading process variables (motor voltage, current, RPM) out of a Siemens MICROMASTER 440 (MM440) drive into an external 8-bit controller is a routine requirement in retrofit panels, laboratory drives, and educational projects. The MM440 exposes a serial interface on terminals 29 (+) and 30 (−) that speaks the USS (Universal Serial Interface) protocol on RS-485. Any microcontroller with a UART and an RS-485 transceiver (e.g., MAX485, SN75176) can be wired to these two terminals and used as either a master (issuing setpoints and reading back) or a pure monitor (only reading).

This article consolidates the field-proven configuration for a read-only USS link from an 8051-class MCU to an MM440. It covers the parameter set (P0700, P1000, P2010–P2014, P2016), the exact binary telegram layout (STX, LGE, ADR, PZD, BCC), checksum computation, and a complete C-language transmit routine that can be pasted into Keil µVision or SDCC.

2. USS Protocol Fundamentals

USS is a Siemens-defined, half-duplex, master-slave serial protocol sitting on top of RS-485 at selectable baud rates (1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200 bit/s). One master addresses one of up to 31 slaves; slaves never transmit without being polled. Each telegram is a single contiguous frame, and the bus must be silent for at least the start delay (parameter P2012, default 0 ms) before a new frame is sent.

Property USS value
Topology RS-485, half-duplex, 2-wire plus ground
Max slaves per bus 31 (address 1–31; 0 reserved for broadcast)
Frame integrity 1 start bit, 8 data bits, 1 even parity bit, 1 stop bit (8E1) — required for MM4xx
Frame timeout Configurable, default 10 character times
PKW area Parameter access (read/write parameter numbers)
PZD area Process data (control word, setpoint, status word, actual values)
The MM440 must see even parity on its COM link. A UART configured for 8N1 will silently drop every frame. Confirm 8E1 on the 8051 side (SCON = 0xD0, TMOD configured for the correct Timer 1 reload for 9600 bps with an 11.0592 MHz crystal).

3. MM440 Hardware: Terminals 29 and 30

On the MM440 control board, the bottom row of the terminal block carries the RS-485 link:

Terminal Signal Notes
29 P+ (RS-485 non-inverting) Connect to MAX485 pin 6 (RO) and pin 4 (DI) through the direction logic
30 N− (RS-485 inverting) Connect to MAX485 pin 7
2 0 V reference Mandatory common ground between MM440 and MCU

Use a twisted pair for 29/30 and keep the cable under 100 m at 9600 bps for the MM440's built-in RS-485 transceiver. A 120 Ω termination resistor is recommended at each physical end of the bus, switchable in by setting bit 0 of P2014 if the drive is the last node.

4. Parameter Configuration for Monitor-Only USS

To leave the existing terminal command source intact and only read data over USS, drive control must come from the digital/analog terminals (P0700 = 2) and the setpoint from analog input 1 (P1000 = 3). The USS channel is enabled for monitoring by leaving P2000 enabled and configuring the PZD length.

Parameter Field value Meaning in monitor-only mode
P0700 2 Command source = terminal strip (digital inputs)
P1000 3 Setpoint source = analog input 1 (terminals 3/4)
P2000 50.00 (Hz default) Reference frequency for 100 % scaling of USS setpoint
P2010[0] 6 USS baud rate = 9600 bit/s
P2011[0] 3 USS slave address of this drive (master uses 0)
P2012[0] 2 or 4 Length of PZD area in words; 2 = status + speed, 4 adds current and torque
P2013[0] 0 Length of PKW area in words. Set to 0 (no parameter read/write from the bus)
P2014[0] 0 or 1 0 = no telegram break, 1 = enable, 2 = ctrl+en, 3 = diag, plus bit 0 for termination
P2016[0..3] see table below Selects which actual value is placed in PZD word N of the response

Critical PZD mapping for the read-back (configured by P2016):

Word in response P2016 index Default Siemens value Coefficient to engineering units
PZD1 (always) − ZSW1 (status word) Bit decoded per MM440 status word map
PZD2 (if P2012 ≥ 2) 0 Actual frequency (r0024) × 0.01 → Hz; × 60 → RPM only after P2000 = motor rated frequency
PZD3 (if P2012 ≥ 3) 1 Actual current (r0027) × 0.01 → A (with P2002 scaling)
PZD4 (if P2012 = 4) 2 Actual torque (r0031) × 0.01 → Nm (with P2003 scaling)
For the classic 4-PZD configuration requested in the field report, set P2012[0] = 4 and accept the default P2016 mapping. This puts status word + speed + current + torque in the response, which is the minimum needed to compute voltage, current, and RPM on the 8051.

5. USS Telegram Structure

Every USS frame has the following fixed layout. All multi-byte fields are transmitted low byte first on the wire (little-endian).

Byte offset Field Size (bytes) Content for 4-PZD request
0 STX 1 0x02 (start of text)
1 LGE 1 Total payload length after LGE = 0x0A for 4 PZD + 1 ADR + 1 BCC
2 ADR 1 0x03 (slave address from P2011[0])
3..4 PZD1 (control word) 2 0x0400 low-byte-first → wire 0x00, 0x04. Bit 10 must be set for the drive to accept the telegram in monitor mode
5..6 PZD2 (setpoint) 2 0x0000 (no setpoint needed; command source is terminals)
7..8 PZD3 2 0x0000 (not used by us)
9..10 PZD4 2 0x0000 (not used by us)
11 BCC 1 EXOR of all bytes from ADR through last PZD byte

For 4 PZD words: LGE = (1 ADR + 8 PZD + 1 BCC) = 0x0A. For 2 PZD: LGE = 0x06. The total frame on the wire is therefore 12 bytes (4 PZD) or 8 bytes (2 PZD).

6. Checksum (BCC) Calculation

The block check character is the byte-wise exclusive-OR of every payload byte after LGE and including BCC's own position. Concretely, for the 4-PZD frame:

BCC = ADR ^ PZD1_LO ^ PZD1_HI ^ PZD2_LO ^ PZD2_HI
         ^ PZD3_LO ^ PZD3_HI ^ PZD4_LO ^ PZD4_HI ^ 0xFF

The trailing 0xFF is a constant recommended by Siemens and is included in the XOR. For the canonical 4-PZD request telegram with ADR=0x03, control word 0x0400 (wire order 0x00, 0x04), and three zero PZD words, the checksum evaluates to 0x0F.

7. 8051 Implementation

7.1 UART and Timer Setup (11.0592 MHz crystal)

// 9600 bps, 8E1
SCON  = 0xD0;     // Mode 3, 9-bit, REN enabled
TMOD  = 0x20;     // Timer 1, mode 2 (auto-reload)
TH1   = 0xFD;     // Reload for 9600 bps @ 11.0592 MHz
TR1   = 1;
// TB8 holds the even parity bit, computed per byte
// Set SM2=0 to ignore the 9th bit on receive

7.2 Building the 4-PZD Request Frame

unsigned char uss_request[12];

void build_uss_request(void)
{
    uss_request[0]  = 0x02;            // STX
    uss_request[1]  = 0x0A;            // LGE for 4 PZD
    uss_request[2]  = 0x03;            // ADR = slave 3 (P2011[0])
    // PZD1 control word = 0x0400, low byte first
    uss_request[3]  = 0x00;
    uss_request[4]  = 0x04;
    // PZD2 setpoint = 0 (monitor-only)
    uss_request[5]  = 0x00;
    uss_request[6]  = 0x00;
    // PZD3 = 0
    uss_request[7]  = 0x00;
    uss_request[8]  = 0x00;
    // PZD4 = 0
    uss_request[9]  = 0x00;
    uss_request[10] = 0x00;
    // BCC
    uss_request[11] = compute_bcc(&uss_request[2], 9);
}

unsigned char compute_bcc(unsigned char *p, unsigned char n)
{
    unsigned char bcc = 0xFF;
    unsigned char i;
    for (i = 0; i < n; i++) bcc ^= p[i];
    return bcc;
}

7.3 Transmit and Receive Half-Duplex Sequence

void uss_poll(void)
{
    unsigned char i, c;
    // Drive DE/RE high to transmit
    RS485_DIR = 1;
    for (i = 0; i < 12; i++) tx_byte(uss_request[i]);
    while (!TI_flag);              // wait last byte shifted out
    RS485_DIR = 0;                 // switch to receive
    // 12 byte response expected for 4-PZD echo
    for (i = 0; i < 12; i++) {
        rx_byte(&c, 50);           // 50 ms timeout per byte
        uss_response[i] = c;
    }
    if (uss_response[11] != compute_bcc(&uss_response[2], 9)) {
        // checksum mismatch – discard
        return;
    }
    // Extract engineering values
    //   frequency = (PZD2) * 0.01 Hz  (PZD2 = uss_response[5] | (uss_response[6]<<8))
    //   current   = (PZD3) * 0.01 A   (scaled by P2002)
    //   torque    = (PZD4) * 0.01 Nm  (scaled by P2003)
    display_freq = ((unsigned int)uss_response[5])
                 | ((unsigned int)uss_response[6] << 8);
    display_current = ((unsigned int)uss_response[7])
                    | ((unsigned int)uss_response[8] << 8);
    lcd_update();
}

8. Realterm Validation Procedure

Before porting to the 8051, validate the telegram from a PC. This catches wiring, baud rate, and parameter issues in minutes.

  1. Open Realterm. Set Port to the COM port of the USB-to-RS485 adapter. Set Baud to 9600, Parity to Even, Data to 8, Stop to 1.
  2. Click Send. Switch the hex tab and enter the 12-byte frame: 02 0A 03 00 04 00 00 00 00 00 00 0F.
  3. Within ~5–10 ms, the MM440 will echo an identical-length frame containing the ZSW1 status word and three actual-value PZD words.
  4. If nothing returns, swap 29/30 (the bus is polarity-sensitive), confirm the green COM LED on the MM440 blinks, and check that P2010[0] reads 6 on the drive keypad.

9. Common Failure Modes and Fixes

Symptom Likely cause Corrective action
No response, COM LED off Wrong baud, wrong parity (8N1 instead of 8E1) Set even parity in PC tool; verify P2010[0] = 6 on drive
No response, COM LED flickers A/B polarity swapped or 0 V missing Swap 29/30, tie terminal 2 of MM440 to MCU GND
Response, but bit 10 of ZSW1 = 0 Control word not equal to 0x0400 Re-check byte order: 0x0400 transmits as 0x00, 0x04
Response, BCC mismatch PKW area left at 4 (P2013 = 4) – response is 14 bytes, not 12 Set P2013[0] = 0; use 2- or 4-PZD length only
Frequency reads 0 at 50 Hz line Setpoint not enabled – P1000 = 5 expected in some firmware For monitor-only leave P1000 = 3; PZD setpoint word is ignored
Garbled PZD values Termination missing on long bus Enable termination in P2014 bit 0 of the last node

10. Reading Voltage, Current, and RPM in Practice

The 4-PZD response carries:

  • ZSW1 – status word, bits 0/1/2/3/4/5/6/10 indicate ready, run, fault, no OFF2, no OFF3, inhibit, fault present, controller inhibit.
  • Actual frequency in 0.01 Hz steps (P2016 default = 0 → r0024). Convert to RPM with: RPM = freq_Hz × 60 / motor_pole_pairs.
  • Actual current in 0.01 A steps (P2016 default = 1 → r0027, scaled by P2002). Already in amps once the 0.01 multiplier is applied.

Output voltage is not in the default 4-PZD mapping. To get DC-link or output voltage, add a fifth actual value by using the PKW area: P2013[0] = 4 (3 PKW words, the standard "parameter channel"). Then issue parameter read requests using the PKW protocol. For monitor-only simplicity, the more common path is to enable P2016[3] = 5 to map r0025 (output voltage) to PZD4, and to leave the torque on the bus via a 5th PZD (P2012 = 5, P2013 = 0).

If your application needs the RMS output voltage in real time and you do not want to handle the PKW protocol on the 8051, set P2012[0] = 5 and P2016[0..3] = {0, 5, 1, 2} so the four response PZD words are ZSW1, frequency, voltage, current. Torque can be re-claimed by enabling a fifth PZD with P2016[4] = 3 (r0031).

11. Engineering Scaling Reference

Parameter Default Effect on USS scaling
P2000 50.00 Reference frequency for 100 % setpoint; also the base for the frequency PZD scaling when 4000 hex = 100 %
P2001 0.0 Reference voltage; base for 0x4000 = 100 % voltage in PZD (used in vector control)
P2002 0.10 Reference current; actual current PZD = 0x4000 when current = P2002
P2003 0.12 Reference torque; torque PZD = 0x4000 when torque = P2003

For an MM440 set to 400 V / 50 Hz / 5 A with P2000 = 50, P2001 = 400, P2002 = 5, P2003 = 12:

  • Frequency PZD 0x4000 = 50 Hz
  • Voltage PZD 0x4000 = 400 V
  • Current PZD 0x4000 = 5 A
  • Torque PZD 0x4000 = 12 Nm

12. Verification Checklist

  1. Realterm echoes a 12-byte frame containing the ZSW1 bit pattern 0x0631 or 0x0231 (depending on run state) when a 0x0400 control word is sent.
  2. 8051 firmware latches the same PZD values into RAM within 20 ms of each poll.
  3. LCD displays frequency in Hz that matches the BOP/AOP readout to within ±0.1 Hz.
  4. No fault F0070 (COM link) is logged in r0947 after 30 minutes of operation.
  5. Removing the 120 Ω termination introduces a slow climb in read errors, confirming the bus is wired correctly when the error count is zero.

13. FAQ

What is the minimum parameter set to read MM440 data over USS without changing the command source?

Set P0700 = 2, P1000 = 3, P2010[0] = 6 (9600 bps), P2011[0] = 3 (slave address), P2012[0] = 4 (4 PZD words), and P2013[0] = 0 (no PKW). The drive still takes commands from the digital inputs and analog input 1; USS becomes a read-only channel.

Do I need even parity on the 8051 UART for USS to work?

Yes. The MM440 always uses 8E1 on its COM port. Configure the 8051 in UART mode 3 (9-bit) with TB8 set to the even-parity bit for every byte transmitted, and discard the 9th bit on receive (SM2 = 0). Failure to set even parity results in silent frame rejection and no response from the drive.

Why is there no response even though the parameters look correct?

The most common cause is the 8051 transmitting in 8N1 instead of 8E1, or the A/B polarity of the RS-485 pair being swapped. The second most common cause is the PKW area left enabled (P2013 = 4), which makes the drive expect a 14-byte frame and reject the 12-byte 4-PZD telegram. Set P2013[0] = 0 and re-test with Realterm before debugging the firmware.

How do I get the output voltage into the PZD area if the default mapping only returns frequency, current, and torque?

Set P2016[1] = 5 to place r0025 (output voltage) into PZD2, then re-scale. With P2001 set to the motor rated voltage (e.g., 400 V), the PZD value 0x4000 corresponds to 400 V, so divide the 16-bit PZD by 163.84 to get engineering volts. Alternatively, enable the PKW area and issue a parameter read for r0025 each cycle.

What is the maximum cable length between the 8051 board and the MM440?

At 9600 bps, the Siemens USS specification allows up to 100 m of shielded twisted pair without repeaters. Keep the cable away from VFD output wiring to avoid common-mode noise. If the run exceeds 100 m or runs next to motor cables, insert a USS repeater (e.g., 6SE7090-0XX84-1AB0) or drop the baud to 19200 only if the cable is short and well-shielded.

Back to blog