diff --git a/interfaces/serial_communication_hub.yaml b/interfaces/serial_communication_hub.yaml index cd3117cd2..6e98e4a0d 100644 --- a/interfaces/serial_communication_hub.yaml +++ b/interfaces/serial_communication_hub.yaml @@ -72,6 +72,30 @@ cmds: description: Status code of the transfer type: string $ref: /serial_comm_hub_requests#/StatusCodeEnum + modbus_write_signle_register: + description: >- + Send a Modbus RTU 'write single register' command via serial interface + to the target hardware. (return value: response) + arguments: + target_device_id: + description: ID (1 byte) of the device to send the commands to + type: integer + minimum: 0 + maximum: 255 + register_address: + description: Address of the register to write to (16 bit address) + type: integer + minimum: 0 + maximum: 65535 + data: + description: Data content to be written to the above selected register + type: integer + minimum: 0 + maximum: 65535 + result: + description: Status code of the transfer + type: string + $ref: /serial_comm_hub_requests#/StatusCodeEnum nonstd_write: description: >- Non standard mode to write registers in read discrete input mode diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 6b53d744a..185b8109f 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -10,8 +10,8 @@ ev_add_module(EvSlac) ev_add_module(GenericPowermeter) ev_add_module(JsTibber) ev_add_module(LemDCBM400600) -ev_add_module(OCPP) -ev_add_module(OCPP201) +# ev_add_module(OCPP) +# ev_add_module(OCPP201) ev_add_module(PacketSniffer) ev_add_module(PersistentStore) ev_add_module(PN532TokenProvider) diff --git a/modules/SerialCommHub/SerialCommHub.hpp b/modules/SerialCommHub/SerialCommHub.hpp index 529523f67..b8b8c63e2 100644 --- a/modules/SerialCommHub/SerialCommHub.hpp +++ b/modules/SerialCommHub/SerialCommHub.hpp @@ -27,8 +27,8 @@ class SerialCommHub : public Everest::ModuleBase { SerialCommHub(const ModuleInfo& info, std::unique_ptr p_main, Conf& config) : ModuleBase(info), p_main(std::move(p_main)), config(config){}; - const Conf& config; const std::unique_ptr p_main; + const Conf& config; // ev@1fce4c5e-0ab8-41bb-90f7-14277703d2ac:v1 // insert your public definitions here diff --git a/modules/SerialCommHub/main/serial_communication_hubImpl.cpp b/modules/SerialCommHub/main/serial_communication_hubImpl.cpp index e3145c1ba..6b5889cdc 100644 --- a/modules/SerialCommHub/main/serial_communication_hubImpl.cpp +++ b/modules/SerialCommHub/main/serial_communication_hubImpl.cpp @@ -158,6 +158,39 @@ types::serial_comm_hub_requests::StatusCodeEnum serial_communication_hubImpl::ha } } +types::serial_comm_hub_requests::StatusCodeEnum +serial_communication_hubImpl::handle_modbus_write_signle_register(int& target_device_id, int& register_address, int& data) +{ + types::serial_comm_hub_requests::Result result; + std::vector response; + + { + std::scoped_lock lock(serial_mutex); + + uint8_t retry_counter{this->num_resends_on_error}; + while (retry_counter-- > 0) { + + EVLOG_debug << fmt::format("Try {} Call modbus_client->write_single_register(id {} addr {} data {})", + (int)retry_counter, (uint8_t)target_device_id, (uint16_t)register_address, + (uint16_t)data); + + response = modbus.txrx(target_device_id, tiny_modbus::FunctionCode::WRITE_SINGLE_HOLDING_REGISTER, + register_address, 1, true, {static_cast(data)}); + if (response.size() > 0) { + break; + } + } + } + EVLOG_debug << fmt::format("Done writing"); + // process response + if (response.size() > 0) { + return types::serial_comm_hub_requests::StatusCodeEnum::Success; + } else { + return types::serial_comm_hub_requests::StatusCodeEnum::Error; + } +} + + void serial_communication_hubImpl::handle_nonstd_write(int& target_device_id, int& first_register_address, int& num_registers_to_read) { } diff --git a/modules/SerialCommHub/main/serial_communication_hubImpl.hpp b/modules/SerialCommHub/main/serial_communication_hubImpl.hpp index 32ac13ee5..00843562a 100644 --- a/modules/SerialCommHub/main/serial_communication_hubImpl.hpp +++ b/modules/SerialCommHub/main/serial_communication_hubImpl.hpp @@ -28,7 +28,6 @@ struct Conf { std::string serial_port; int baudrate; int parity; - int rs485_direction_gpio; bool ignore_echo; std::string rxtx_gpio_chip; int rxtx_gpio_line; @@ -60,6 +59,8 @@ class serial_communication_hubImpl : public serial_communication_hubImplBase { virtual types::serial_comm_hub_requests::StatusCodeEnum handle_modbus_write_multiple_registers(int& target_device_id, int& first_register_address, types::serial_comm_hub_requests::VectorUint16& data_raw) override; + virtual types::serial_comm_hub_requests::StatusCodeEnum + handle_modbus_write_signle_register(int& target_device_id, int& register_address, int& data) override; virtual void handle_nonstd_write(int& target_device_id, int& first_register_address, int& num_registers_to_read) override; virtual types::serial_comm_hub_requests::Result diff --git a/modules/SerialCommHub/tiny_modbus_rtu.cpp b/modules/SerialCommHub/tiny_modbus_rtu.cpp index f2904c0fc..fe6f28355 100644 --- a/modules/SerialCommHub/tiny_modbus_rtu.cpp +++ b/modules/SerialCommHub/tiny_modbus_rtu.cpp @@ -370,7 +370,10 @@ std::vector TinyModbusRTU::txrx_impl(uint8_t device_address, FunctionC first_register_address = htobe16(first_register_address); register_quantity = htobe16(register_quantity); memcpy(req.get() + REQ_TX_FIRST_REGISTER_ADDR_POS, &first_register_address, 2); - memcpy(req.get() + REQ_TX_QUANTITY_POS, ®ister_quantity, 2); + if (function != FunctionCode::WRITE_SINGLE_HOLDING_REGISTER) { + // For functioncode 6 we do not transmit quantity + memcpy(req.get() + REQ_TX_QUANTITY_POS, ®ister_quantity, 2); + } if (function == FunctionCode::WRITE_MULTIPLE_HOLDING_REGISTERS) { // write byte count @@ -383,6 +386,11 @@ std::vector TinyModbusRTU::txrx_impl(uint8_t device_address, FunctionC i += 2; } } + + if (function == FunctionCode::WRITE_SINGLE_HOLDING_REGISTER) { + memcmp(req.get() + REQ_TX_SINGLE_REG_PAYLOAD_POS, &request[0], 2); + } + // set checksum in the last 2 bytes append_checksum(req.get(), req_len); diff --git a/modules/SerialCommHub/tiny_modbus_rtu.hpp b/modules/SerialCommHub/tiny_modbus_rtu.hpp index bb4066a60..891cea9a1 100644 --- a/modules/SerialCommHub/tiny_modbus_rtu.hpp +++ b/modules/SerialCommHub/tiny_modbus_rtu.hpp @@ -21,9 +21,11 @@ constexpr int FUNCTION_CODE_POS = 0x01; constexpr int REQ_TX_FIRST_REGISTER_ADDR_POS = 0x02; constexpr int REQ_TX_QUANTITY_POS = 0x04; +constexpr int REQ_TX_SINGLE_REG_PAYLOAD_POS = 0x04; constexpr int REQ_TX_MULTIPLE_REG_BYTE_COUNT_POS = 0x06; + constexpr int RES_RX_LEN_POS = 0x02; constexpr int RES_RX_START_OF_PAYLOAD = 0x03; constexpr int RES_TX_START_OF_PAYLOAD = 0x02;