4.14 C99 Modbus
Overview
C99 Modbus has two layers: ArmHandle* represents the SDK session, and ArmModbusSlaveHandle* represents the context for one slave.
Recommended Call Order
| Step | API | Description |
|---|---|---|
| 1 | Arm_Connect | Establishes the robot session. |
| 2 | Arm_Modbus_GetParam | Reads serial parameters for the target channel as needed. |
| 3 | Arm_Modbus_GetSlave | Creates a slave handle. This only creates a local context and does not verify whether the remote slave exists. |
| 4 | Arm_ModbusSlave_Read* / Arm_ModbusSlave_Write* | Reads or writes coils, holding registers, discrete inputs, and input registers. |
| 5 | Arm_ModbusSlave_SerialSend / Arm_ModbusSlave_SerialReceive | Uses serial pass-through as needed. |
| 6 | Arm_ModbusSlave_Destroy | Destroys the slave handle. |
API Signatures
Arm_Modbus_GetSlave
c
int Arm_Modbus_GetSlave(ArmHandle* h, int channel, int32_t slaveId, int32_t masterId, ArmModbusSlaveHandle** outSlave);| Item | Description |
|---|---|
| Description | Creates a Modbus slave handle. |
| Request parameters | h : ArmHandle* , C99 session handle, usually created by Arm_Create() ; service APIs require a successful connection firstchannel : int , Modbus channel enum valueslaveId : int32_t , Modbus slave IDmasterId : int32_t , master parameter ID or channel-context IDoutSlave : ArmModbusSlaveHandle** , output Modbus slave handle; the caller must destroy it after success |
| Return value | Integer STATUS_CODE ; 0 means success, and other values should be handled according to the status-code definitions |
Arm_Modbus_GetParam
c
int Arm_Modbus_GetParam(ArmHandle* h, int channel, int32_t masterId, ArmSerialParams* outParams);| Item | Description |
|---|---|
| Description | Reads serial parameters for a Modbus channel. |
| Request parameters | h : ArmHandle* , C99 session handle, usually created by Arm_Create() ; service APIs require a successful connection firstchannel : int , Modbus channel enum valuemasterId : int32_t , master parameter ID or channel-context IDoutParams : ArmSerialParams* , serial-parameter output-structure pointer |
| Return value | Integer STATUS_CODE ; 0 means success, and other values should be handled according to the status-code definitions |
Arm_Modbus_SetParam
c
int Arm_Modbus_SetParam(ArmHandle* h, const ArmSerialParams* params, int32_t* outId);| Item | Description |
|---|---|
| Description | Sets serial parameters for a Modbus channel. |
| Request parameters | h : ArmHandle* , C99 session handle, usually created by Arm_Create() ; service APIs require a successful connection firstparams : const ArmSerialParams* , serial-parameter structure pointeroutId : int32_t* , parameter record ID output pointer |
| Return value | Integer STATUS_CODE ; 0 means success, and other values should be handled according to the status-code definitions |
Arm_ModbusSlave_Destroy
c
void Arm_ModbusSlave_Destroy(ArmModbusSlaveHandle* slave);| Item | Description |
|---|---|
| Description | Destroys a Modbus slave handle. |
| Request parameters | slave : ArmModbusSlaveHandle* , Modbus slave handle returned by Arm_Modbus_GetSlave() |
| Return value | No return value |
Arm_ModbusSlave_IsValid
c
int Arm_ModbusSlave_IsValid(ArmModbusSlaveHandle* slave);| Item | Description |
|---|---|
| Description | Checks whether a Modbus slave handle is valid. |
| Request parameters | slave : ArmModbusSlaveHandle* , Modbus slave handle returned by Arm_Modbus_GetSlave() |
| Return value | 1 means the handle is valid, 0 means the handle has become invalid; when slave == NULL or an exception occurs, an error code is returned |
Arm_ModbusSlave_GetParam
c
int Arm_ModbusSlave_GetParam(ArmModbusSlaveHandle* slave, ArmSerialParams* outParams);| Item | Description |
|---|---|
| Description | Reads serial parameters through the slave context. |
| Request parameters | slave : ArmModbusSlaveHandle* , Modbus slave handle returned by Arm_Modbus_GetSlave() outParams : ArmSerialParams* , serial-parameter output-structure pointer |
| Return value | Integer STATUS_CODE ; 0 means success, and other values should be handled according to the status-code definitions |
Arm_ModbusSlave_SetParam
c
int Arm_ModbusSlave_SetParam(ArmModbusSlaveHandle* slave, const ArmSerialParams* params, int32_t* outId);| Item | Description |
|---|---|
| Description | Sets serial parameters through the slave context. |
| Request parameters | slave : ArmModbusSlaveHandle* , Modbus slave handle returned by Arm_Modbus_GetSlave() params : const ArmSerialParams* , serial-parameter structure pointeroutId : int32_t* , parameter record ID output pointer |
| Return value | Integer STATUS_CODE ; 0 means success, and other values should be handled according to the status-code definitions |
Arm_ModbusSlave_ReadCoils
c
int Arm_ModbusSlave_ReadCoils(ArmModbusSlaveHandle* slave, int32_t addr, int32_t num, int32_t* outArray, size_t maxCount, size_t* outCount);| Item | Description |
|---|---|
| Description | Reads coils. |
| Request parameters | slave : ArmModbusSlaveHandle* , Modbus slave handle returned by Arm_Modbus_GetSlave() addr : int32_t , start addressnum : int32_t , number of values to readoutArray : int32_t* , output array allocated by the callermaxCount : size_t , output array capacity, expressed as the maximum number of elements the caller can receiveoutCount : size_t* , output-count pointer; on success, receives the actual number of elements |
| Return value | Integer STATUS_CODE ; 0 means success, and other values should be handled according to the status-code definitions |
| Notes | The array output is allocated by the caller. maxCount is the capacity, and outCount returns the actual count. |
Arm_ModbusSlave_WriteCoils
c
int Arm_ModbusSlave_WriteCoils(ArmModbusSlaveHandle* slave, int32_t addr, const int32_t* values, size_t count);| Item | Description |
|---|---|
| Description | Writes coils. |
| Request parameters | slave : ArmModbusSlaveHandle* , Modbus slave handle returned by Arm_Modbus_GetSlave() addr : int32_t , start addressvalues : const int32_t* , array of values to writecount : size_t , number of array elements |
| Return value | Integer STATUS_CODE ; 0 means success, and other values should be handled according to the status-code definitions |
Arm_ModbusSlave_ReadHoldingRegs
c
int Arm_ModbusSlave_ReadHoldingRegs(ArmModbusSlaveHandle* slave, int32_t addr, int32_t num, int32_t* outArray, size_t maxCount, size_t* outCount);| Item | Description |
|---|---|
| Description | Reads holding registers. |
| Request parameters | slave : ArmModbusSlaveHandle* , Modbus slave handle returned by Arm_Modbus_GetSlave() addr : int32_t , start addressnum : int32_t , number of values to readoutArray : int32_t* , output array allocated by the callermaxCount : size_t , output array capacity, expressed as the maximum number of elements the caller can receiveoutCount : size_t* , output-count pointer; on success, receives the actual number of elements |
| Return value | Integer STATUS_CODE ; 0 means success, and other values should be handled according to the status-code definitions |
| Notes | The array output is allocated by the caller. maxCount is the capacity, and outCount returns the actual count. |
Arm_ModbusSlave_WriteHoldingRegs
c
int Arm_ModbusSlave_WriteHoldingRegs(ArmModbusSlaveHandle* slave, int32_t addr, const int32_t* values, size_t count);| Item | Description |
|---|---|
| Description | Writes holding registers. |
| Request parameters | slave : ArmModbusSlaveHandle* , Modbus slave handle returned by Arm_Modbus_GetSlave() addr : int32_t , start addressvalues : const int32_t* , array of values to writecount : size_t , number of array elements |
| Return value | Integer STATUS_CODE ; 0 means success, and other values should be handled according to the status-code definitions |
Arm_ModbusSlave_ReadDiscreteInputs
c
int Arm_ModbusSlave_ReadDiscreteInputs(ArmModbusSlaveHandle* slave, int32_t addr, int32_t num, int32_t* outArray, size_t maxCount, size_t* outCount);| Item | Description |
|---|---|
| Description | Reads discrete inputs. |
| Request parameters | slave : ArmModbusSlaveHandle* , Modbus slave handle returned by Arm_Modbus_GetSlave() addr : int32_t , start addressnum : int32_t , number of values to readoutArray : int32_t* , output array allocated by the callermaxCount : size_t , output array capacity, expressed as the maximum number of elements the caller can receiveoutCount : size_t* , output-count pointer; on success, receives the actual number of elements |
| Return value | Integer STATUS_CODE ; 0 means success, and other values should be handled according to the status-code definitions |
| Notes | The array output is allocated by the caller. maxCount is the capacity, and outCount returns the actual count. |
Arm_ModbusSlave_ReadInputRegs
c
int Arm_ModbusSlave_ReadInputRegs(ArmModbusSlaveHandle* slave, int32_t addr, int32_t num, int32_t* outArray, size_t maxCount, size_t* outCount);| Item | Description |
|---|---|
| Description | Reads input registers. |
| Request parameters | slave : ArmModbusSlaveHandle* , Modbus slave handle returned by Arm_Modbus_GetSlave() addr : int32_t , start addressnum : int32_t , number of values to readoutArray : int32_t* , output array allocated by the callermaxCount : size_t , output array capacity, expressed as the maximum number of elements the caller can receiveoutCount : size_t* , output-count pointer; on success, receives the actual number of elements |
| Return value | Integer STATUS_CODE ; 0 means success, and other values should be handled according to the status-code definitions |
| Notes | The array output is allocated by the caller. maxCount is the capacity, and outCount returns the actual count. |
Arm_ModbusSlave_WriteInputRegs
c
int Arm_ModbusSlave_WriteInputRegs(ArmModbusSlaveHandle* slave, int32_t addr, const int32_t* values, size_t count);| Item | Description |
|---|---|
| Description | Writes input registers. |
| Request parameters | slave : ArmModbusSlaveHandle* , Modbus slave handle returned by Arm_Modbus_GetSlave() addr : int32_t , start addressvalues : const int32_t* , array of values to writecount : size_t , number of array elements |
| Return value | Integer STATUS_CODE ; 0 means success, and other values should be handled according to the status-code definitions |
Arm_ModbusSlave_SerialSend
c
int Arm_ModbusSlave_SerialSend(ArmModbusSlaveHandle* slave, const char* msg);| Item | Description |
|---|---|
| Description | Sends serial pass-through data. |
| Request parameters | slave : ArmModbusSlaveHandle* , Modbus slave handle returned by Arm_Modbus_GetSlave() msg : const char* , serial pass-through text to send |
| Return value | Integer STATUS_CODE ; 0 means success, and other values should be handled according to the status-code definitions |
Arm_ModbusSlave_SerialReceive
c
int Arm_ModbusSlave_SerialReceive(ArmModbusSlaveHandle* slave, char* outBuf, size_t bufSize);| Item | Description |
|---|---|
| Description | Receives serial pass-through data. |
| Request parameters | slave : ArmModbusSlaveHandle* , Modbus slave handle returned by Arm_Modbus_GetSlave() outBuf : char* , output string buffer allocated by the callerbufSize : size_t , output buffer size, including space for the trailing \0 |
| Return value | Integer STATUS_CODE ; 0 means success, and other values should be handled according to the status-code definitions |
| Notes | String output uses the caller-provided buffer. If the buffer is too small, the function reports that through the status code. |
Common Types
ArmModbusChannel
| Enum value | Value | Description |
|---|---|---|
ARM_MODBUS_CHANNEL_CONTROLLER_TCP_TO_485 | 2 | Controller TCP-to-485 channel |
ARM_MODBUS_CHANNEL_WRIST_485_0 | 3 | Wrist 485_0 channel |
ARM_MODBUS_CHANNEL_WRIST_485_1 | 4 | Wrist 485_1 channel |
ARM_MODBUS_CHANNEL_CONTROLLER_485 | 5 | Controller 485 channel |
ArmModbusParity
| Enum value | Value | Description |
|---|---|---|
ARM_MODBUS_PARITY_NONE | 78 | No parity, ASCII N |
ARM_MODBUS_PARITY_ODD | 79 | Odd parity, ASCII O |
ARM_MODBUS_PARITY_EVEN | 69 | Even parity, ASCII E |
ArmSerialParams
| Field | Type | Description |
|---|---|---|
id | int32_t | Parameter record ID |
channel | int32_t | ArmModbusChannel enum value |
ip | char[128] | Target IP |
port | int32_t | Port |
baud | int32_t | Baud rate |
dataBit | int32_t | Data bits |
stopBit | int32_t | Stop bits |
parity | int32_t | ArmModbusParity enum value |
timeout | int32_t | Timeout in milliseconds |
Pointer and Buffer Rules
| Scenario | Return |
|---|---|
h == NULL or slave == NULL | Returns an error code |
Required out pointer is NULL | Returns INVALID_PARAMETER |
Reading an array with outArray == NULL and outCount != NULL | Writes only the count |
| Read-array buffer too small | Returns BUFFER_TOO_SMALL and sets outCount to 0 |
bufSize == 0 for Arm_ModbusSlave_SerialReceive | Returns BUFFER_TOO_SMALL |
SerialReceive fails while outBuf is valid | Writes an empty string |
Parameters and Lifetime
| Item | Rule |
|---|---|
| Connection prerequisite | Arm_Connect() must succeed first |
addr | Start address must satisfy addr >= 0 |
| Read count | num must be 1..120 |
| Write count | count must be 1..1024 |
| Address upper bound | addr + count - 1 or addr + num - 1 must not exceed 65535 |
values | Must not be null when count > 0 |
| Slave handle | Depends on the ArmHandle* that created it and must not be reused across Arm_Disconnect() |
outId | On successful SetParam , receives the parameter record ID confirmed by the controller |
Behavior conventions:
Arm_Modbus_GetSlave()creates a local handle; the remote slave state is reflected by later read/write results.Arm_ModbusSlave_IsValid()checks whether the local handle is still bound to a valid session; remote online state is reflected by read/write results.- On the
ARM_MODBUS_CHANNEL_CONTROLLER_TCP_TO_485channel,Arm_Modbus_GetParam()sendsmasterIdto the controller; other channels usually ignoremasterId. - Serial pass-through works by channel and does not carry
slaveId/masterId. - Read APIs return integer arrays returned by the controller; coil values are presented as controller results.
- Write APIs validate address range and count; the business meaning of each
valueselement is handled by the controller.
Failure Conventions
| Scenario | Return |
|---|---|
| Invalid slave handle | INVALID_SESSION |
| Invalid channel enum or parity enum | INVALID_PARAMETER |
addr < 0 | INVALID_PARAMETER |
num < 1 or num > 120 | INVALID_PARAMETER |
count < 1 or count > 1024 | INVALID_PARAMETER |
addr + count - 1 > 65535 or addr + num - 1 > 65535 | INVALID_PARAMETER |
| Controller returns an unexpected data structure | OTHER_ERR |
Minimal Example
c
#include <stdio.h> // Provides printf for printing the Modbus query result.
#include "c_arm_api.h" // Includes the aggregate C99 SDK header.
int main(void) // Example program entry point.
{ // Enters the example main function.
ArmHandle* h = Arm_Create(); // Creates a C99 session handle.
ArmModbusSlaveHandle* slave = NULL; // Prepares the Modbus slave handle output.
int32_t coils[8] = {0}; // Prepares the buffer for coil values.
size_t outCount = 0U; // Prepares the variable for the actual read count.
if (h == NULL) { // Checks whether session handle creation failed.
return 1; // Exits when creation fails.
} // Ends the handle creation check.
if (Arm_Connect(h, "10.27.1.254", NULL) != 0) { // Connects to the controller or routed address.
Arm_Destroy(h); // Destroys the session handle after connection failure.
return 1; // Returns an error code.
} // Ends the connection check.
if (Arm_Modbus_GetSlave(h, ARM_MODBUS_CHANNEL_CONTROLLER_485, 1, 0, &slave) != 0) { // Creates a slave handle on the controller 485 channel.
Arm_Disconnect(h); // Disconnects the robot session after creation failure.
Arm_Destroy(h); // Destroys the session handle after creation failure.
return 1; // Returns an error code.
} // Ends the slave-handle creation check.
int ret = Arm_ModbusSlave_ReadCoils(slave, 0, 2, coils, 8, &outCount); // Reads 2 coil values from address 0.
if (ret == 0) { // Checks whether coil reading succeeded.
printf("coil_count=%zu\n", outCount); // Prints the actual read count.
} // Ends the coil-read check.
Arm_ModbusSlave_Destroy(slave); // Destroys the slave handle.
Arm_Disconnect(h); // Disconnects the robot session.
Arm_Destroy(h); // Destroys the session handle.
return ret == 0 ? 0 : 1; // Returns the example status according to the read result.
} // Ends the example main function.Scenario Examples
The following snippets assume that ArmHandle* h has already connected successfully. Setting parameters, writing registers, and serial pass-through affect field devices; execute them only after confirmation.
Query and Set Serial Parameters
c
ArmSerialParams params = {0}; // Prepares the serial-parameter output structure.
int32_t savedId = 0; // Prepares the parameter record ID confirmed by the controller.
int getRet = Arm_Modbus_GetParam(h, ARM_MODBUS_CHANNEL_CONTROLLER_485, 0, ¶ms); // Queries controller 485 channel parameters.
params.channel = ARM_MODBUS_CHANNEL_CONTROLLER_485; // Specifies the channel to set.
/* int setRet = Arm_Modbus_SetParam(h, ¶ms, &savedId); */ // Setting serial parameters changes controller configuration; execute only after confirmation.
(void)getRet; // Keeps the query status code in this example.
(void)savedId; // Keeps the set-output variable in this example.Slave Read/Write
c
int32_t values[4] = {0}; // Prepares the read output buffer.
int32_t writeValues[2] = {1, 0}; // Prepares values to write to coils.
size_t outCount = 0U; // Prepares the read-count output.
int coilsRet = Arm_ModbusSlave_ReadCoils(slave, 0, 2, values, 4, &outCount); // Reads coils.
int holdingRet = Arm_ModbusSlave_ReadHoldingRegs(slave, 0, 2, values, 4, &outCount); // Reads holding registers.
int discreteRet = Arm_ModbusSlave_ReadDiscreteInputs(slave, 0, 2, values, 4, &outCount); // Reads discrete inputs.
int inputRet = Arm_ModbusSlave_ReadInputRegs(slave, 0, 2, values, 4, &outCount); // Reads input registers.
/* int writeCoilsRet = Arm_ModbusSlave_WriteCoils(slave, 0, writeValues, 2); */ // Writing coils changes slave state; execute only after confirmation.
(void)coilsRet; // Keeps the coil-read status code in this example.
(void)holdingRet; // Keeps the holding-register read status code in this example.
(void)discreteRet; // Keeps the discrete-input read status code in this example.
(void)inputRet; // Keeps the input-register read status code in this example.Context Parameters and Serial Pass-through
c
ArmSerialParams params = {0}; // Prepares the serial-parameter output structure.
char recvBuf[1024] = {0}; // Prepares the serial pass-through receive buffer.
int valid = Arm_ModbusSlave_IsValid(slave); // Checks whether the slave handle is still valid.
int getRet = Arm_ModbusSlave_GetParam(slave, ¶ms); // Queries serial parameters through the slave context.
/* int sendRet = Arm_ModbusSlave_SerialSend(slave, "010300000002"); */ // Serial pass-through send accesses the field bus; execute only after confirmation.
/* int recvRet = Arm_ModbusSlave_SerialReceive(slave, recvBuf, sizeof(recvBuf)); */ // Serial pass-through receive waits for field data; execute only after confirmation.
(void)valid; // Keeps the validity-check result in this example.
(void)getRet; // Keeps the query status code in this example.Sample code
cpp
#include <stdio.h>
#include <string.h>
extern "C" {
#include "c_arm_api.h"
}
int main(void)
{
// [ZH] 本示例直接在源码中写死连接地址,不解析命令行参数。
// [EN] This example hard-codes the connection addresses in the source code and does not parse command-line arguments.
// [ZH] 创建并连接 SDK 句柄。
// [EN] Create the SDK handle and connect to the robot.
ArmHandle* handle = Arm_Create();
if (handle == NULL) {
printf("[c99_modbus] 创建句柄失败 / Failed to create the handle\n");
return 1;
}
int ret = Arm_Connect(handle, "10.27.1.2", "10.27.1.102");
if (ret != 0) {
printf("[c99_modbus] 连接失败 / Connect failed, 状态码 / Status code: %d\n", ret);
Arm_Destroy(handle);
return 1;
}
printf("[c99_modbus] 机器人连接成功 / Robot connected successfully\n");
// [ZH] 准备主站串口参数并读取当前值。
// [EN] Prepare master serial params and read the current values.
ArmSerialParams masterParams = {0};
int32_t paramId = 0;
snprintf(masterParams.ip, sizeof(masterParams.ip), "127.0.0.1");
masterParams.channel = ARM_MODBUS_CHANNEL_CONTROLLER_485;
masterParams.id = 1;
masterParams.port = 502;
masterParams.baud = 9600;
masterParams.dataBit = 8;
masterParams.stopBit = 1;
masterParams.parity = ARM_MODBUS_PARITY_NONE;
masterParams.timeout = 1000;
ret = Arm_Modbus_GetParam(handle, ARM_MODBUS_CHANNEL_CONTROLLER_485, 0, &masterParams);
printf("[c99_modbus] GetParam 状态码 / GetParam status code: %d, channel=%d, baud=%d\n", ret, masterParams.channel, masterParams.baud);
ret = Arm_Modbus_SetParam(handle, &masterParams, ¶mId);
printf("[c99_modbus] SetParam 状态码 / SetParam status code: %d, id=%d\n", ret, paramId);
// [ZH] 获取从站句柄并顺序执行全部从站接口。
// [EN] Acquire the slave handle and execute all slave APIs in sequence.
ArmModbusSlaveHandle* slave = NULL;
ret = Arm_Modbus_GetSlave(handle, ARM_MODBUS_CHANNEL_CONTROLLER_485, 1, 0, &slave);
printf("[c99_modbus] GetSlave 状态码 / GetSlave status code: %d\n", ret);
if (slave != NULL) {
int valid = Arm_ModbusSlave_IsValid(slave);
printf("[c99_modbus] Slave_IsValid / Slave_IsValid: %d\n", valid);
int32_t values[8] = {0};
size_t valueCount = 0U;
ret = Arm_ModbusSlave_ReadCoils(slave, 0, 2, values, 8U, &valueCount);
printf("[c99_modbus] ReadCoils 状态码 / ReadCoils status code: %d, count=%zu\n", ret, valueCount);
int32_t writeCoils[2] = {1, 0};
ret = Arm_ModbusSlave_WriteCoils(slave, 0, writeCoils, 2U);
printf("[c99_modbus] WriteCoils 状态码 / WriteCoils status code: %d\n", ret);
ret = Arm_ModbusSlave_ReadHoldingRegs(slave, 0, 2, values, 8U, &valueCount);
printf("[c99_modbus] ReadHoldingRegs 状态码 / ReadHoldingRegs status code: %d, count=%zu\n", ret, valueCount);
int32_t holdingRegs[2] = {1, 2};
ret = Arm_ModbusSlave_WriteHoldingRegs(slave, 0, holdingRegs, 2U);
printf("[c99_modbus] WriteHoldingRegs 状态码 / WriteHoldingRegs status code: %d\n", ret);
ret = Arm_ModbusSlave_ReadDiscreteInputs(slave, 0, 2, values, 8U, &valueCount);
printf("[c99_modbus] ReadDiscreteInputs 状态码 / ReadDiscreteInputs status code: %d, count=%zu\n", ret, valueCount);
ret = Arm_ModbusSlave_ReadInputRegs(slave, 0, 2, values, 8U, &valueCount);
printf("[c99_modbus] ReadInputRegs 状态码 / ReadInputRegs status code: %d, count=%zu\n", ret, valueCount);
int32_t inputRegs[2] = {3, 4};
ret = Arm_ModbusSlave_WriteInputRegs(slave, 0, inputRegs, 2U);
printf("[c99_modbus] WriteInputRegs 状态码 / WriteInputRegs status code: %d\n", ret);
ret = Arm_ModbusSlave_SetParam(slave, &masterParams, ¶mId);
printf("[c99_modbus] Slave_SetParam 状态码 / Slave_SetParam status code: %d, id=%d\n", ret, paramId);
ret = Arm_ModbusSlave_GetParam(slave, &masterParams);
printf("[c99_modbus] Slave_GetParam 状态码 / Slave_GetParam status code: %d, baud=%d\n", ret, masterParams.baud);
ret = Arm_ModbusSlave_SerialSend(slave, "hello from c99 example");
printf("[c99_modbus] SerialSend 状态码 / SerialSend status code: %d\n", ret);
char recvBuf[256] = {0};
ret = Arm_ModbusSlave_SerialReceive(slave, recvBuf, sizeof(recvBuf));
printf("[c99_modbus] SerialReceive 状态码 / SerialReceive status code: %d, 内容 / Text: %s\n", ret, recvBuf);
Arm_ModbusSlave_Destroy(slave);
printf("[c99_modbus] 从站句柄已释放 / Slave handle destroyed\n");
}
// [ZH] 断开连接并销毁句柄。
// [EN] Disconnect and destroy the handle.
Arm_Disconnect(handle);
Arm_Destroy(handle);
printf("[c99_modbus] 示例结束 / Example finished\n");
return 0;
}