Getting started
This library speaks MELSEC serial MC Protocol from host tools and MCU firmware. The core client is transport-agnostic, so you can drive it from a blocking host serial port or from your board UART layer.
Prerequisites
| Requirement | Notes |
|---|---|
| C++ standard | Strict ISO C++17 for PlatformIO packages, the repository CMake build, tests, CLI, and examples. |
| Build system | PlatformIO for MCU projects, or CMake for host examples and local integration. |
| Supported MCU targets | ESP32 and RP2040. Arduino Mega 2560 and other AVR/8-bit targets are not supported. |
| Serial interface | RS-232C or RS-485 hardware that matches your PLC serial module. |
| PLC settings | Baud rate, parity, stop bits, frame type, and station number must match the PLC module settings. |
Install
For PlatformIO, add the library package:
[env:your-board]
lib_deps =
fa-yoshinobu/mcprotocol-serial-cpp
build_unflags =
-std=gnu++11
-std=gnu++14
build_flags =
-std=c++17
This package is the MCU-oriented, transport-agnostic core. It compiles client.cpp and
codec.cpp; it does not compile host_sync.cpp or a Windows/POSIX serial backend. Use
MelsecSerialClient with your UART or simulated transport in PlatformIO.
For the host-only PosixSyncClient, vendor the source repository in a CMake project and link the
host-enabled target:
add_subdirectory(external/plc-comm-mcprotocol-serial-cpp)
target_link_libraries(your_app PRIVATE mcprotocol_serial)
PlatformIO examples
Run the maintained PlatformIO environments with pio run -e <env>.
| Purpose | Environments |
|---|---|
| Host / simulated examples | native-example, native-example-ultra-minimal |
| RP2040 / Raspberry Pi Pico | rpipico-arduino-example, rpipico-arduino-uart-example, rpipico-arduino-example-ultra-minimal |
| ESP32-C3 DevKitM-1 | esp32-c3-devkitm-1-example, esp32-c3-devkitm-1-uart-example, esp32-c3-devkitm-1-example-ultra-minimal |
The normal MCU examples use a reduced footprint profile. The ultra-minimal examples keep only the smallest batch read/write path and reduce fixed buffers for small firmware builds. Existing Mega/AVR projects must migrate to a supported ESP32 target or carry an unsupported downstream port; the distributed package and CI do not validate AVR builds.
Choose your PLC profile
PlcProfile is required. There is no default profile for live communication.
Use plc_profile_display_name(profile) when you need a UI label.
| Canonical profile | Display name | Hardware | API selector |
|---|---|---|---|
melsec:iq-r |
MELSEC iQ-R | MELSEC iQ-R serial modules | PlcProfile::MelsecIqR |
melsec:iq-l |
MELSEC iQ-L | MELSEC iQ-L serial modules | PlcProfile::MelsecIqL |
melsec:iq-f |
MELSEC iQ-F | MELSEC iQ-F / FX5 serial paths | PlcProfile::MelsecIqF |
melsec:qcpu |
MELSEC-Q | MELSEC-Q serial modules | PlcProfile::MelsecQ |
melsec:lcpu |
MELSEC-L | MELSEC-L serial modules | PlcProfile::MelsecL |
melsec:qna |
MELSEC QnA | MELSEC QnA-compatible targets | PlcProfile::MelsecQnA |
melsec:ana-anu |
MELSEC AnA/AnU | MELSEC AnA / AnU-compatible targets | PlcProfile::MelsecAnAAnU |
melsec:a |
MELSEC-A | MELSEC-A-compatible targets | PlcProfile::MelsecA |
auto protocol = mcprotocol::serial::highlevel::make_c4_ascii_format4_protocol(
mcprotocol::serial::PlcProfile::MelsecQ,
mcprotocol::serial::SumCheckMode::Disabled,
mcprotocol::serial::RouteConfig {mcprotocol::serial::HostStationRoute {}});
First read on a host
This CMake/source-tree example uses PosixSyncClient, explicit serial settings,
make_c4_ascii_format4_protocol(..., RouteConfig {HostStationRoute {}}), and
read_words("D100", words). The PlatformIO package does not contain the host facade implementation.
#include <array>
#include <cstdint>
#include <cstdio>
#include "mcprotocol_serial.hpp"
int main() {
using mcprotocol::serial::HardwareFlowControl;
using mcprotocol::serial::PlcProfile;
using mcprotocol::serial::PosixSerialConfig;
using mcprotocol::serial::PosixSyncClient;
using mcprotocol::serial::SerialParity;
using mcprotocol::serial::Status;
using mcprotocol::serial::SumCheckMode;
using mcprotocol::serial::highlevel::make_c4_ascii_format4_protocol;
const PosixSerialConfig serial(
#if defined(_WIN32)
"COM3",
#else
"/dev/ttyUSB0",
#endif
19200,
8,
1,
SerialParity::Even,
HardwareFlowControl::None);
auto protocol = make_c4_ascii_format4_protocol(
PlcProfile::MelsecQ,
SumCheckMode::Disabled,
mcprotocol::serial::RouteConfig {mcprotocol::serial::HostStationRoute {}});
PosixSyncClient plc;
Status status = plc.open(serial, protocol);
if (!status.ok()) {
std::fprintf(stderr, "open failed: %s\n", status.message);
return 1;
}
std::array<std::uint16_t, 1> words {};
status = plc.read_words("D100", words);
if (!status.ok()) {
std::fprintf(stderr, "read_words failed: %s\n", status.message);
return 1;
}
std::printf("D100=0x%04X\n", words[0]);
return 0;
}
Expected output shape:
D100=0x0000
The value depends on your PLC memory.
First read on an MCU
Start from the real-UART PlatformIO examples:
| Board | Example | Default PLC UART |
|---|---|---|
| RP2040 / Raspberry Pi Pico | platformio_rpipico_arduino_uart | Serial1, TX 0, RX 1, 19200 / 8E1 |
| ESP32-C3 DevKitM-1 | platformio_esp32c3_arduino_uart | Serial1, TX 7, RX 6, 19200 / 8E1 |
The pin numbers are sample defaults. Change them to match your actual board wiring and level shifter. The serial values in examples are also sample defaults. Match the actual PLC serial-module frame, baud rate, parity, stop bits, and station number before using them as validation settings.
Confirm success
- Your PLC serial module settings match the host or MCU serial settings exactly.
- The profile selected in code matches the target PLC family.
- The frame type configured in the PLC matches the helper you selected.
- The first read returns a
Statuswherestatus.ok()is true. - The returned word values match a memory range you can safely inspect.
If it does not work
| Symptom | Check |
|---|---|
| No response from the PLC | Baud rate, parity, and stop bits must all match the PLC serial module DIP switch or parameter settings. |
| PLC error or framing error | Check that the PLC module is configured for the same frame type and code mode. |
| RS-485 multi-drop does not answer | Select the frame-specific route and the actual topology. Use a *StandardMultidropRoute for normal/1:n or a *MnMultidropRoute with the assigned SelfStationNo for m:n. Ensure station—and for 3C/4C, network and PC target—matches the serial module. For 4C, also verify the mandatory destination-module target. Use the explicit 1E PC target when 1E is selected. |
| MCU sample prints zeros or no values | Verify the UART TX/RX pins and the TTL-to-RS-232C or RS-485 interface. |
| Wiring uncertainty | See the shared MC Protocol Serial setup guide before changing software settings. |