When programming in C to interface with the [Endress+Hauser Liquiline Compact CM82](https://bdih-download.endress.com/file/7c9f16356f738202d3d7c26bba3483a9/E+H%20Liquiline%20Compact%20LIT-18.pdf), you must transition from HART "Short Frames" (polling address) to HART "Long Frames" (5-byte unique device address) using HART Universal Command 0. [1] The CM82 requires a minimum of 5 preamble bytes (0xFF). Because HART utilizes an asynchronous serial byte stream, your C application must compute the Longitudinal Redundancy Check (LRC / BCC) by XORing every byte from the Start Delimiter down to the last Data byte. [2] ------------------------------ ## 1. C Implementation: HART Frame Builder & Checksum The code snippet below defines the structural buffer requirements and includes a function to calculate the mandatory XOR checksum (BCC) for the serial payload: #include #include #include #define MAX_HART_FRAME 50 // Calculates the essential Longitudinal Redundancy Check (LRC)uint8_t calculate_lrc(const uint8_t *frame, size_t start_idx, size_t end_idx) { uint8_t lrc = 0; for (size_t i = start_idx; i < end_idx; i++) { lrc ^= frame[i]; } return lrc; } // Helper to print hex frames for debugging serial loopsvoid print_hex(const char *label, const uint8_t *buf, size_t len) { printf("%s: ", label); for (size_t i = 0; i < len; i++) { printf("%02X ", buf[i]); } printf("\n"); } ------------------------------ ## 2. Phase 1: Generating Universal Command 0 (Short Frame) To find the CM82's master-specific long address, you must broad-call Command 0 using a standard Short Frame delimiter (0x02). [3] size_t build_cmd0_short_frame(uint8_t *buf) { size_t idx = 0; // 1. Preambles (CM82 requires min 5 bytes) for (int i = 0; i < 5; i++) buf[idx++] = 0xFF; size_t data_start = idx; // LRC starts here // 2. Start Delimiter (0x02 = Master-to-Slave Short Frame) buf[idx++] = 0x02; // 3. Short Address (0x00 for standard single-drop device loops) buf[idx++] = 0x00; // 4. Command 0 (Read Unique Identifier) buf[idx++] = 0x00; // 5. Byte Count (0 data bytes sent for request) buf[idx++] = 0x00; size_t data_end = idx; // 6. Append Checksum buf[idx++] = calculate_lrc(buf, data_start, data_end); return idx; } Generated Hex Output Stream: FF FF FF FF FF 02 00 00 00 02 ------------------------------ ## 3. Parsing Response & Extracting the CM82 Long Address When the CM82 responds, bytes 11, 12, and 13 inside the data section contain its 24-bit Unique Device ID. You combine these with the Endress+Hauser Manufacturer ID (0x11 or 17) and the CM82 Device Type Code (0x11CC or variant depending on firmware revision) to compose the 5-byte long address: [3] // Sample structure to hold the discovered device identifierstypedef struct { uint8_t long_addr[5]; } HartDevice; // Run this on your UART receive buffer after executing Command 0void parse_cmd0_response(const uint8_t *resp, HartDevice *dev) { // Standard response offset skipping preambles and headers // In a long frame header, E+H code is typically at index 11 dev->long_addr[0] = 0x11; // Endress+Hauser Manufacturer ID dev->long_addr[1] = resp[10]; // Expanded Device Type Byte 1 (from response) dev->long_addr[2] = resp[11]; // Expanded Device Type Byte 2 dev->long_addr[3] = resp[12]; // Device ID High Byte dev->long_addr[4] = resp[13]; // Device ID Low Byte } ------------------------------ ## 4. Phase 2: Generating Universal Command 1 (Read Primary Variable) Once you have populated HartDevice, switch to a Long Frame format. The Start Delimiter becomes 0x82 (Master-to-Slave Long Frame). Command 1 pulls the target measurement process value (e.g., pH, Conductivity, or Dissolved Oxygen, depending on which [Memosens sensor](https://www.endress.com/en/field-instruments-overview/liquid-analysis-product-overview/compact-transmitter-pH-conductivity-oxygen-orp-cm82) is plugged into the CM82 head). [3, 4] size_t build_cmd1_long_frame(uint8_t *buf, const HartDevice *dev) { size_t idx = 0; // 1. Preambles for (int i = 0; i < 5; i++) buf[idx++] = 0xFF; size_t data_start = idx; // 2. Start Delimiter (0x82 = Master-to-Slave Long Frame) buf[idx++] = 0x82; // 3. Move the 5-byte Unique Address into the stream memcpy(&buf[idx], dev->long_addr, 5); idx += 5; // 4. Command 1 (Read Primary Variable) buf[idx++] = 0x01; // 5. Byte Count (0 bytes for request payload) buf[idx++] = 0x00; size_t data_end = idx; // 6. Checksum calculation buf[idx++] = calculate_lrc(buf, data_start, data_end); return idx; } int main() { uint8_t tx_buffer[MAX_HART_FRAME]; HartDevice cm82; // Mocking an Endress+Hauser CM82 found ID profile cm82.long_addr[0] = 0x11; // E+H ID cm82.long_addr[1] = 0x9C; // Sample CM82 Profile ID cm82.long_addr[2] = 0x02; cm82.long_addr[3] = 0xAB; // Serial references cm82.long_addr[4] = 0xCD; size_t tx_len = build_cmd1_long_frame(tx_buffer, &cm82); print_hex("CM82 Command 1 TX Stream", tx_buffer, tx_len); return 0; } ## 5. Interpreting Process Value Data (Float-32) When reading the response packet for Command 1 or Command 3, the CM82 returns values in standard IEEE-754 Single-Precision Floating Point format. [3] * * Ensure your C parsing code accounts for endianness; HART streams network-byte order (Big-Endian). * If your MCU environment is Little-Endian (e.g., ARM Cortex-M or x86 architecture), you must swap the byte layout of the 4 data bytes before casting them into a float primitive. * Would you like assistance writing the byte-swapping code for the incoming float variables, or do you need the structures for HART Command 48 to pull diagnostics data from the CM82? [5] [1] [https://bdih-download.endress.com](https://bdih-download.endress.com/file/7c9f16356f738202d3d7c26bba3483a9/E+H%20Liquiline%20Compact%20LIT-18.pdf) [2] [https://bdih-download.endress.com](https://bdih-download.endress.com/file/7c9f16356f738202d3d7c26bba3483a9/E+H%20Liquiline%20Compact%20LIT-18.pdf) [3] [https://www.coulton.com](https://www.coulton.com/res/HART-COMMAND-TABLE_Rev1-20030519xls.pdf) [4] [https://www.endress.com](https://www.endress.com/en/field-instruments-overview/liquid-analysis-product-overview/compact-transmitter-pH-conductivity-oxygen-orp-cm82) [5] [https://bdih-download.endress.com](https://bdih-download.endress.com/file/7c9f16356f738202d3d7c26bba3483a9/E+H%20Liquiline%20Compact%20LIT-18.pdf)