1. Overview
The Siemens MICROMASTER 4 family (MM420, MM430, MM440) supports the Universal Serial Interface (USS) protocol over RS-485 for point-to-point or multi-drop drive networks. Each drive periodically broadcasts or responds to a master poll with a fixed-length binary frame that contains a Parameter-Kennung-Wert (PKW) channel and a Prozessdaten (PZD) channel. The PKW channel exposes the full parameter set (read/write), while the PZD channel carries the cyclical process data — control word, status word, frequency setpoint, and actual frequency.
This reference decodes a captured MM4 frame recorded between an RS-232 tap (between an AOP operator panel and a PC) and the drive. The recorded values are 375 RPM motor speed, 12.50 Hz output frequency, and 102 V line-to-line output. The goal is to allow a host microcontroller (STM32) to extract the speed signal without relying on an intermediate PLC, so that a blower airflow calculation can be performed in real time.
2. MICROMASTER 4 Communication Architecture
The MM4 default USS telegram uses the PPO type 1 layout with 4 PKW words and 2 PZD words. The communication stack has three layers:
- Physical layer: RS-485 half-duplex, 9600–57600 bit/s, 8E1 (8 data, even parity, 1 stop) by default. The AOP panel exposes an RS-232-to-RS-485 bridge.
- Data link layer: USS — variable-length binary frame with STX delimiter, length byte, address byte, payload, and BCC XOR checksum. Bus access is master-driven; slaves respond only when polled.
- Application layer: Two parallel channels — PKW (acyclic parameter channel) and PZD (cyclic process-data channel). The PKW channel is optional on some PPO types but mandatory for parameter access via USS.
| PPO Type | PKW Words | PZD Words | Total Payload (words) | Typical Use |
|---|---|---|---|---|
| PPO 1 | 4 | 2 | 6 | MM420/430/440 default USS |
| PPO 2 | 4 | 6 | 10 | Extended PZD with multiple setpoints |
| PPO 3 | 0 | 2 | 2 | PZD-only (no parameter access) |
| PPO 4 | 0 | 6 | 6 | PZD-only extended |
| PPO 5 | 4 | 10 | 14 | Full feature set (rare on MM4) |
The frame captured in the field uses PPO 1, which is the default when an MM4 drive is set to USS control source (P0700 = 5) with the standard 2-PZD mapping (P2012[0] = 2, P2012[1] = 2).
3. USS Telegram Frame Structure
Every USS telegram has the following layout:
| Offset | Field | Size (bytes) | Description |
|---|---|---|---|
| 0 | STX | 1 | Start delimiter, always 0x02 |
| 1 | LGE | 1 | Length of payload after LGE, including ADR; for PPO 1 = 13 (0x0D), but MM4 frequently emits 12 (0x0C) when PWE2 is dropped or the PZD count is reduced. |
| 2 | ADR | 1 | Drive address (0–30 in MM4). Bit 7 = broadcast when set. |
| 3 | PKE | 2 | Parameter identifier (high nibble = AK, low 12 bits = PNU) |
| 5 | IND | 2 | Parameter index (used for array indexing on MM4) |
| 7 | PWE1 | 2 | Parameter value word 1 (high word for 32-bit parameters) |
| 9 | PWE2 | 2 | Parameter value word 2 (low word for 32-bit parameters; often 0 in MM4 read responses) |
| 11 | PZD1 | 2 | Process data word 1 — control word (master→drive) or status word (drive→master) |
| 13 | PZD2 | 2 | Process data word 2 — frequency setpoint (HSW) or actual frequency (HIW) |
| 15 | BCC | 1 | Block check character — XOR of all bytes from ADR through last PZD word |
For a PPO 1 frame with the full PKW block (8 bytes) and PZD block (4 bytes), the byte count after ADR is 12. Therefore LGE = 0x0C = 12 is consistent with the captured frame, indicating the frame is a master poll that omits PWE2 (typical when reading a 16-bit parameter or sending a write request with no value).
4. PKW Field Decode (PKE, IND, PWE)
The PKW channel gives parameter-by-parameter access to the MM4 parameter database. The Parameter-Kennung (PKE) field encodes both the request type and the parameter number:
| PKE Bit Range | Field | Description |
|---|---|---|
| 15–12 (high nibble) | AK | Auftrags-Kennung (request/response ID) |
| 11–10 | SPM | Toggle bit for read/write; not used by MM4 |
| 9–0 | PNU | Parameter Number (0–1999 user, 2000–3999 expert) |
Common AK values for the MM4 USS parameter channel:
| AK (hex) | Master Request | Drive Response |
|---|---|---|
| 0 | No request | No response |
| 1 | Read parameter value (single word) | Read response (single word) |
| 2 | Write parameter value (single word) | Write confirmation |
| 3 | Read parameter value (double word) | Read response (double word) |
| 6 | Read parameter value (array) | Read response (array) |
| 7 | Write parameter value (array) | Write confirmation |
The IND field is used for MM4 parameter indexing (e.g., for the BICO parameter set r2016[0]…r2016[7]). For non-indexed parameters, IND = 0x0000. The PWE1 / PWE2 pair carries the 32-bit parameter value, with PWE1 as the high word and PWE2 as the low word for 32-bit parameters.
5. PZD Field Decode (Control Word, Status Word, Setpoint, Actual)
The PZD area is the time-critical part of the USS frame. With two PZD words, the MM4 uses a fixed mapping:
| Direction | PZD1 | PZD2 |
|---|---|---|
| Master → Drive (setpoint) | Control Word 1 (STW1) | Main Setpoint (HSW) |
| Drive → Master (actual) | Status Word 1 (ZSW1) | Main Actual (HIW) |
Control Word 1 (STW1) bit assignments per Siemens MM4 specification:
| Bit | Name | Function |
|---|---|---|
| 0 | ON/OFF1 | 0 = OFF1 (ramp down to 0), 1 = ON |
| 1 | OFF2 | 0 = coast stop, 1 = OFF2 inactive |
| 2 | OFF3 | 0 = quick stop, 1 = OFF3 inactive |
| 3 | Inhibit Operation | 0 = enable pulse, 1 = inhibit |
| 4 | Ramp Generator Enable | 0 = freeze ramp, 1 = ramp enabled |
| 5 | Ramp Generator Start | 0 = stop ramp, 1 = start ramp |
| 6 | Setpoint Enable | 0 = disable setpoint, 1 = accept setpoint |
| 7 | Fault Acknowledge | 0→1 edge resets faults |
| 8 | JOG Right | 1 = jog in positive direction |
| 9 | JOG Left | 1 = jog in negative direction |
| 10 | Control From PLC | 1 = control by USS, 0 = local control |
| 11 | Reverse | 1 = negative setpoint direction |
| 12 | Reserved | Always 0 |
| 13 | Motor Pot UP | 1 = MOP up (digital) |
| 14 | Motor Pot DOWN | 1 = MOP down (digital) |
| 15 | Local/Remote | 1 = local (AOP), 0 = USS/fieldbus |
Status Word 1 (ZSW1) bit assignments:
| Bit | Name | Function |
|---|---|---|
| 0 | Ready To Switch On | 1 = power electronics ready |
| 1 | Ready To Operate | 1 = DC bus charged, no faults |
| 2 | Operation Enabled | 1 = drive running (pulses enabled) |
| 3 | Fault Present | 1 = drive faulted |
| 4 | OFF2 Active | 0 = OFF2 active, 1 = inactive |
| 5 | OFF3 Active | 0 = OFF3 active, 1 = inactive |
| 6 | Switch-On Inhibited | 1 = start inhibited (terminal logic) |
| 7 | Alarm Present | 1 = warning active |
| 8 | Setpoint/Actual Deviation | 0 = within tolerance |
| 9 | Control Requested | 1 = control requested from PLC |
| 10 | Frequency Reached | 1 = |f_act - f_set| ≤ P2163 threshold |
| 11 | Overload | 1 = motor overload alarm (I²t) |
| 12 | Motor Pull-Out | 1 = stall / pull-out detected |
| 13 | Motor Over-Temperature | 1 = PTC / KTY alarm |
| 14 | Motor Rotation Forward | 1 = actual rotation forward |
| 15 | CDP Active | 1 = CDS / DDS bit 1 active |
The frequency setpoint (HSW) and actual frequency (HIW) follow the standard Siemens normalization:
f_Hz = (raw_hex / 0x4000) × P2000
where P2000 is the reference frequency set on the drive (default 50.00 Hz on a 50 Hz mains system). The raw value is signed 16-bit, so negative setpoints (reverse) appear as two's-complement numbers. On older MM4 firmware (V1.05 and below), an alternative linear scaling of 0x1000 = 1 Hz was used, and some retrofit installations still emit that format; verify the actual scaling against a known setpoint before assuming the 0x4000 mapping.
6. Worked Example: Decoding the Captured Telegram
The captured frame is:
0x02 0x0C 0x00 0x1000 0x0025 0x04E7 0x0D76 0x04E2 [BCC]
| Byte # | Hex | Field | Interpretation |
|---|---|---|---|
| 0 | 0x02 | STX | Valid start delimiter |
| 1 | 0x0C | LGE | 12 bytes of payload after LGE (ADR + 5 data words) |
| 2 | 0x00 | ADR | Drive address 0 |
| 3–4 | 0x1000 | PKE | AK = 0x1 (read parameter), PNU = 0x000 |
| 5–6 | 0x0025 | IND | Index = 0x0025 = 37 (parameter array element) |
| 7–8 | 0x04E7 | PWE1 | 1255 dec — PKW high word |
| 9–10 | 0x0D76 | PZD1 | 3446 dec — control or status word |
| 11–12 | 0x04E2 | PZD2 | 1250 dec — setpoint or actual frequency |
| 13 | [BCC] | BCC | XOR of bytes 2–12 (exclusive) |
Decoding the PKW portion:
- PKE = 0x1000: high nibble 0x1 = request to read a parameter; PNU = 0x000 = parameter index 0 (PNU 0 in MM4 is the user's read of parameter r0000 — the drive's display value selector).
- IND = 0x0025 = 37: this selects the active parameter index. In MM4 firmware ≥ V1.10, IND 37 routes the read to r0755 or similar context-sensitive display value. The exact parameter routed depends on P0000 (parameter display filter).
- PWE1 = 0x04E7 = 1255 dec: high word of the parameter value. With PWE2 absent in this LGE-12 frame, the value is interpreted as a 16-bit single-word parameter = 1255.
Decoding the PZD portion:
- PZD1 = 0x0D76 = 3446 dec = 0b0000 1101 0111 0110. As a master→drive control word: bits 1, 2, 4, 5, 6, 8, 9, 10, 13 are set — i.e., OFF2 inactive, OFF3 inactive, ramp enabled, ramp start, setpoint enabled, JOG right+left (an inconsistent state — likely echo of a previous write), PLC control, MOP up. As a drive→master status word: bits 1, 2 (operation enabled), 4 (OFF2 inactive), 6 (switch-on inhibited — odd), 10 (frequency reached), 11 (overload). The bit pattern is more consistent with a status echo than an active control word.
- PZD2 = 0x04E2 = 1250 dec. Compare the linear scaling: if P2000 = 50 Hz, then 1250 / 16384 × 50 = 3.815 Hz — not 12.5 Hz. If P2000 = 163.84 Hz (an unusual non-default), 1250 / 16384 × 163.84 = 12.50 Hz exactly. The simplest explanation that matches the recorded 12.50 Hz is a direct 0.01 Hz resolution scaling: f = raw × 0.01 Hz. This scaling is used by the BOP/AOP display echo on some MM4 firmware revisions and is consistent with the field observation that the word returns to 0 when the motor stops.
7. Parameter Mapping and Frequency/RPM Scaling
To extract motor speed on a host, use the following MM4 parameters through the PKW channel:
| PNU | Parameter | Access | Format | Description |
|---|---|---|---|---|
| r0021 | Output frequency actual | Read | Float (Hz), scaled to 16384 = P2000 | Most accurate frequency source |
| r0022 | Motor speed actual | Read | Float (RPM), scaled to 16384 = P2000 × 60 / p | Direct motor RPM |
| r0024 | Output frequency smoothed | Read | Float (Hz) | Filtered for display |
| r0035 | Motor temperature | Read | Float (°C) | Thermal monitoring |
| r0039 | Energy consumed | Read | Float (kWh) | Power metering |
| P2000 | Reference frequency | R/W | Float (Hz) | Normalization base (default 50.0) |
| P1080 | Minimum frequency | R/W | Float (Hz) | Lower speed limit |
| P1082 | Maximum frequency | R/W | Float (Hz) | Upper speed limit |
The MM4 stores parameters as 32-bit IEEE 754 floats. When transmitting through the 16-bit PKW channel, the high word goes in PWE1 and the low word in PWE2. For a frequency read of 12.50 Hz, the IEEE 754 single-precision encoding is 0x41480000, which transmits as PWE1 = 0x4148 and PWE2 = 0x0000.
For an airflow calculation on a blower, the relevant derived quantity is volume flow Q (m³/s):
Q = A_eff × v_imp = A_eff × π × D × n / 60
where A_eff is the effective inlet area, D is the impeller diameter, and n is the motor RPM read from r0022. Read r0022 every 50–100 ms via a PKW poll cycle, scale to RPM, and apply the formula.
8. BCC Checksum Computation
The BCC is a single-byte XOR of all payload bytes from ADR through the last PZD word. For the captured frame:
BCC = ADR ^ PKE_lo ^ PKE_hi ^ IND_lo ^ IND_hi ^ PWE1_lo ^ PWE1_hi ^ PZD1_lo ^ PZD1_hi ^ PZD2_lo ^ PZD2_hi
Compute for the example:
0x00 ^ 0x00 ^ 0x10 ^ 0x25 ^ 0x00 ^ 0xE7 ^ 0x04 ^ 0x76 ^ 0x0D ^ 0xE2 ^ 0x04
= 0x73
The receiver must recompute the same XOR and compare to the received BCC byte. A mismatch indicates a bus collision or framing error and the frame must be discarded.
9. STM32 Microcontroller Implementation
Implement the USS parser as a state machine on a USART peripheral configured for 8E1 at 9600–19200 bit/s. The required receive buffer is 16 bytes minimum. Use a DMA-driven reception with idle-line interrupt to detect frame end.
typedef struct {
uint8_t stx;
uint8_t lge;
uint8_t adr;
uint16_t pke;
uint16_t ind;
uint16_t pwe1;
uint16_t pwe2;
uint16_t pzd1;
uint16_t pzd2;
uint8_t bcc;
} uss_ppo1_frame_t;
// Returns 1 on valid frame, 0 on BCC error or length error.
uint8_t uss_decode(const uint8_t *buf, uint16_t len, uss_ppo1_frame_t *out) {
if (len < 14 || buf[0] != 0x02) return 0;
if (buf[1] != 0x0C && buf[1] != 0x0D) return 0;
out->stx = buf[0];
out->lge = buf[1];
out->adr = buf[2] & 0x1F; // mask off broadcast bit
out->pke = (buf[3] << 8) | buf[4];
out->ind = (buf[5] << 8) | buf[6];
out->pwe1 = (buf[7] << 8) | buf[8];
if (buf[1] >= 0x0D) {
out->pwe2 = (buf[9] << 8) | buf[10];
out->pzd1 = (buf[11] << 8) | buf[12];
out->pzd2 = (buf[13] << 8) | buf[14];
out->bcc = buf[15];
} else {
out->pwe2 = 0;
out->pzd1 = (buf[9] << 8) | buf[10];
out->pzd2 = (buf[11] << 8) | buf[12];
out->bcc = buf[13];
}
uint8_t bcc_calc = 0;
uint16_t span = (buf[1] >= 0x0D) ? 13 : 11;
for (uint16_t i = 2; i <= span; i++) bcc_calc ^= buf[i];
return (bcc_calc == out->bcc);
}
// Convert raw PZD2 to Hz assuming 0.01 Hz resolution.
static inline float uss_pzd2_to_hz(uint16_t pzd2) {
if (pzd2 & 0x8000) {
// negative direction (two's complement)
int16_t s = (int16_t)pzd2;
return s * 0.01f;
}
return pzd2 * 0.01f;
}
// Convert raw PZD2 to Hz assuming 0x4000 = P2000 normalization.
static inline float uss_pzd2_to_hz_norm(uint16_t pzd2, float p2000) {
int16_t s = (int16_t)pzd2;
return ((float)s / 16384.0f) * p2000;
}
// Build and transmit a PKW read request (AK=6 array read).
uint16_t uss_build_read_req(uint8_t *out, uint8_t adr, uint16_t pnu, uint16_t ind) {
out[0] = 0x02;
out[1] = 0x0E; // LGE = 14 (PPO 1 full PKW)
out[2] = adr & 0x1F;
out[3] = 0x60 | ((pnu >> 8) & 0x0F); // AK=6 (read array)
out[4] = pnu & 0xFF;
out[5] = (ind >> 8) & 0xFF;
out[6] = ind & 0xFF;
out[7] = 0;
out[8] = 0;
out[9] = 0;
out[10] = 0;
out[11] = 0;
out[12] = 0;
uint8_t bcc = 0;
for (uint8_t i = 2; i <= 12; i++) bcc ^= out[i];
out[13] = bcc;
return 14;
}
On the STM32, place the receive buffer in a non-cacheable region if an MPU is in use, and ensure a 1.5-character idle detection on USART to bound the inter-byte gap. Use TIM6 or a hardware timer to enforce the USS character timeout (max 1.5 character times at the configured baud).
10. Troubleshooting and Field Verification
| Symptom | Likely Cause | Diagnostic | Resolution |
|---|---|---|---|
| BCC error on every frame | Baud-rate mismatch between AOP tap and drive | Verify USART configuration (9600/19200/38400/57600, 8E1) | Set P2010[0] to match host |
| LGE = 0x0C always, never 0x0D | PKW channel not enabled, or P2012[0] < 4 | Read P2012 from the drive via AOP | Set P2012[0] = 4 (PKW words), P2012[1] = 2 (PZD words) |
| Frequency reads as 0 even when motor runs | PZD direction reversed or control word not enabled | Inspect bit 10 of PZD1 — must be 1 (PLC control requested) | Set STW1 bit 10 in master transmission, or set P0700 = 5 |
| Speed value 375 RPM but r0022 read returns garbage | Float32 byte order wrong — MM4 is big-endian | Swap PWE1 and PWE2 on read | Reverse byte order in decoder |
| Frame collides with broadcast | ADR bit 7 set accidentally; multiple masters | Check ADR field, verify single-master wiring | Clear ADR bit 7; install bus termination 120 Ω at both ends |
| PZD2 returns negative values during reverse run | Two's-complement signed scaling | Cast PZD2 to int16_t before scaling | Apply (int16_t) cast in code |
| Setpoint scaling does not match 0x4000/P2000 | Drive firmware < V1.05, or P2000 altered | Read P2000 via PKW and compare against scaling math | Re-scale, or update firmware |
| PKW response returns AK = 7 (parameter not found) | PNU > 1999 without expert access (P0003 = 3) | Check P0003 access level | Set P0003 = 3, or use rxxxx read-only parameters |
| Checksum passes but data corrupted | Long stub on RS-485 cable causing reflections | Inspect termination, maximum cable length 1000 m at 9600 baud | Add 120 Ω termination, reduce stub length < 0.3 m |
11. Frequently Asked Questions
What is the difference between PKW and PZD in a MICROMASTER 4 USS telegram?
PKW is the parameter channel — 4 words that read or write any drive parameter (r0022 for RPM, P2000 for reference frequency). PZD is the process-data channel — 2 words that cyclically carry the control word, status word, frequency setpoint, and actual frequency at the bus cycle rate (typically 4–10 ms).
How is motor speed encoded in an MM4 USS frame if only 2 PZD words are used?
Motor speed (RPM) is not in the default 2-PZD PPO 1 frame. It must be read via the PKW channel as parameter r0022, returned as a 32-bit IEEE 754 float split across PWE1 (high word) and PWE2 (low word). Alternatively, PPO type 2 or 5 with 6 or 10 PZD words can be configured via P2012 to carry r0022 directly in an extra PZD slot.
Why does my PZD2 read 1250 decimal when the drive reports 12.50 Hz?
Two scaling modes are possible. The standard Siemens normalization is f_Hz = (PZD2 / 0x4000) × P2000, which gives 1250/16384 × 50 = 3.815 Hz at default P2000 = 50 Hz — not a match. The 0.01 Hz linear scaling (f_Hz = PZD2 × 0.01) gives 1250 × 0.01 = 12.50 Hz exactly and is used by some MM4 firmware revisions and certain retrofit installations. Verify which scaling applies by setting a known setpoint and observing the raw PZD2 value.
What is the BCC byte and how is it computed?
BCC is the block check character, a single-byte XOR of all payload bytes from ADR through the last PZD word. For the captured 14-byte frame, BCC = 0x00 ^ 0x10 ^ 0x00 ^ 0x25 ^ 0x00 ^ 0xE7 ^ 0x04 ^ 0x76 ^ 0x0D ^ 0xE2 ^ 0x04 = 0x73. The receiver recomputes the same XOR and compares against the received BCC; any mismatch means the frame is corrupt.
Can an STM32 host read MM4 parameters without a Siemens PLC?
Yes. Configure the STM32 USART for 8E1 at the drive's P2010[0] baud rate (default 9600), implement a state-machine USS decoder with BCC verification, and poll parameters via PKW write requests with AK=1 or AK=6. The MM4 responds within one telegram turnaround time (typically 2–5 ms at 19200 baud). For higher-speed polling, increase P2010[1] if RS-485 hardware supports it.