diff --git a/client.go b/client.go index ed1302f..9599246 100644 --- a/client.go +++ b/client.go @@ -773,6 +773,62 @@ func (mc *ModbusClient) WriteRegister(addr uint16, value uint16) (err error) { return } +// Writes a single 16-bit register (function code 06). +func (mc *ModbusClient) WriteRegisterWithRes(addr uint16, value uint16) (bytes []byte, err error) { + var req *pdu + var res *pdu + + mc.lock.Lock() + defer mc.lock.Unlock() + + // create and fill in the request object + req = &pdu{ + unitId: mc.unitId, + functionCode: fcWriteSingleRegister, + } + + // register address + req.payload = uint16ToBytes(BIG_ENDIAN, addr) + // register value + req.payload = append(req.payload, uint16ToBytes(mc.endianness, value)...) + + // run the request across the transport and wait for a response + res, err = mc.executeRequest(req) + if err != nil { + return + } + + // validate the response code + switch { + case res.functionCode == req.functionCode: + // expect 4 bytes (2 byte of address + 2 bytes of value) + if len(res.payload) != 4 || + // bytes 1-2 should be the register address + bytesToUint16(BIG_ENDIAN, res.payload[0:2]) != addr || + // bytes 3-4 should be the value + bytesToUint16(mc.endianness, res.payload[2:4]) != value { + err = ErrProtocolError + return + } + + bytes = req.payload[1:] + + case res.functionCode == (req.functionCode | 0x80): + if len(res.payload) != 1 { + err = ErrProtocolError + return + } + + err = mapExceptionCodeToError(res.payload[0]) + + default: + err = ErrProtocolError + mc.logger.Warningf("unexpected response code (%v)", res.functionCode) + } + + return +} + // Writes multiple 16-bit registers (function code 16). func (mc *ModbusClient) WriteRegisters(addr uint16, values []uint16) (err error) { var payload []byte