MC Protocol Serial C++ 0.2.3
MC protocol serial library for MCU-oriented environments
Loading...
Searching...
No Matches
platformio_rpipico_arduino_async.cpp
Go to the documentation of this file.
1#include <Arduino.h>
2
3#include <array>
4#include <cstddef>
5#include <cstdint>
6
9
10namespace {
11
23
24struct AppState {
25 MelsecSerialClient client;
26 std::array<std::uint16_t, 2> out_words {};
27 bool started = false;
28 bool tx_started = false;
29 bool tx_completed = false;
30 bool done = false;
31 bool reported = false;
32 Status completion_status {};
33};
34
35AppState g_app;
36
37ProtocolConfig make_protocol() {
38 ProtocolConfig config;
39 config.frame_kind = FrameKind::C4;
40 config.code_mode = CodeMode::Ascii;
41 config.ascii_format = AsciiFormat::Format4;
42 config.target_series = PlcSeries::Q_L;
43 config.sum_check_enabled = false;
44 config.route = RouteConfig {
45 .kind = RouteKind::HostStation,
46 .station_no = 0x00,
47 .network_no = 0x00,
48 .pc_no = 0xFF,
49 .request_destination_module_io_no = 0x03FF,
50 .request_destination_module_station_no = 0x00,
51 .self_station_enabled = false,
52 .self_station_no = 0x00,
53 };
54 return config;
55}
56
57void on_request_complete(void* user, Status status) {
58 auto* app = static_cast<AppState*>(user);
59 app->done = true;
60 app->completion_status = status;
61}
62
63void start_uart_tx(AppState& app, std::span<const std::byte> frame) {
64 (void)frame;
65 app.tx_started = true;
66}
67
68void simulate_response(AppState& app, std::uint32_t now_ms) {
69 const ProtocolConfig config = make_protocol();
70 const std::array<std::uint8_t, 8> response_data {'1', '2', '3', '4', '5', '6', '7', '8'};
71 std::array<std::uint8_t, mcprotocol::serial::kMaxResponseFrameBytes> response_frame {};
72 std::size_t response_frame_size = 0;
73 const Status status = FrameCodec::encode_success_response(
74 config,
75 std::span<const std::uint8_t>(response_data.data(), response_data.size()),
76 response_frame,
77 response_frame_size);
78 if (!status.ok()) {
79 app.done = true;
80 app.completion_status = status;
81 return;
82 }
83
84 app.client.on_rx_bytes(
85 now_ms,
87 reinterpret_cast<const std::byte*>(response_frame.data()),
88 response_frame_size));
89}
90
91void report_once(AppState& app) {
92 if (app.reported || !app.done) {
93 return;
94 }
95
96 app.reported = true;
97 if (!app.completion_status.ok()) {
98 Serial.print("rpipico async example failed: ");
99 Serial.println(app.completion_status.message);
100 return;
101 }
102
103 Serial.print("rpipico async example read ok: D100=0x");
104 Serial.print(app.out_words[0], HEX);
105 Serial.print(" D101=0x");
106 Serial.println(app.out_words[1], HEX);
107}
108
109} // namespace
110
111void setup() {
112 Serial.begin(115200);
113 const Status status = g_app.client.configure(make_protocol());
114 if (!status.ok()) {
115 g_app.done = true;
116 g_app.completion_status = status;
117 }
118}
119
120void loop() {
121 const std::uint32_t now = millis();
122
123 if (!g_app.done && !g_app.started) {
124 const Status status = g_app.client.async_batch_read_words(
125 now,
126 BatchReadWordsRequest {
127 .head_device = {.code = mcprotocol::serial::DeviceCode::D, .number = 100},
128 .points = static_cast<std::uint16_t>(g_app.out_words.size()),
129 },
130 std::span<std::uint16_t>(g_app.out_words.data(), g_app.out_words.size()),
131 on_request_complete,
132 &g_app);
133 if (status.ok()) {
134 start_uart_tx(g_app, g_app.client.pending_tx_frame());
135 g_app.started = true;
136 } else {
137 g_app.done = true;
138 g_app.completion_status = status;
139 }
140 }
141
142 if (!g_app.done && g_app.tx_started && !g_app.tx_completed) {
143 const Status status = g_app.client.notify_tx_complete(now);
144 if (status.ok()) {
145 g_app.tx_completed = true;
146 simulate_response(g_app, now);
147 } else {
148 g_app.done = true;
149 g_app.completion_status = status;
150 }
151 }
152
153 if (!g_app.done) {
154 g_app.client.poll(now);
155 }
156
157 report_once(g_app);
158}
Frame-level encode/decode helper for complete serial MC frames.
Definition codec.hpp:80
Asynchronous MC protocol client for UART / serial integrations.
Definition client.hpp:37
Single-include entry point for the public serial client API.
RouteKind
Route layout inside the request header.
Definition types.hpp:190
FrameKind
MC protocol frame family used on the serial link.
Definition types.hpp:147
CodeMode
Request/response payload encoding.
Definition types.hpp:161
AsciiFormat
ASCII formatting variant for C4 / C3 / C2 serial frames.
Definition types.hpp:169
PlcSeries
PLC family selection used for subcommand and device-layout differences.
Definition types.hpp:181
Top-level protocol configuration shared by codecs and client requests.
Definition types.hpp:323
Route header fields for serial MC requests.
Definition types.hpp:296
Result object returned by most public APIs.
Definition status.hpp:26