Add support for reading input registers

This commit was merged in pull request #7.
This commit is contained in:
2023-07-04 17:48:10 +02:00
parent 8fbead4274
commit f16b9dd009
2 changed files with 73 additions and 28 deletions

View File

@@ -19,9 +19,10 @@ type Mbclient struct {
keepAliveDuration time.Duration
timeOut time.Duration
wg sync.WaitGroup
registerOffset uint16
}
func New(Address string, Unit uint8, KeepAlive, TimeOut time.Duration) (*Mbclient, error) {
func New(Address string, Unit uint8, KeepAlive, TimeOut time.Duration, registerOffset uint16) (*Mbclient, error) {
c := new(Mbclient)
c.address = Address
@@ -30,6 +31,7 @@ func New(Address string, Unit uint8, KeepAlive, TimeOut time.Duration) (*Mbclien
<-c.t.C
c.keepAliveDuration = KeepAlive
c.timeOut = TimeOut
c.registerOffset = registerOffset
return c, nil
}
@@ -49,7 +51,17 @@ func (m *Mbclient) closeConn() {
m.wg.Wait()
}
func (m *Mbclient) ReadRegisters(first uint16, numRegs uint16) ([]uint16, error) {
// Reads one or many holding registers (Function code 03)
func (m *Mbclient) ReadHoldingRegisters(first uint16, numRegs uint16) ([]uint16, error) {
return m.readRegisters(3, first, numRegs)
}
// Reads one or many input registers (Function code 04)
func (m *Mbclient) ReadInputRegisters(first uint16, numRegs uint16) ([]uint16, error) {
return m.readRegisters(4, first, numRegs)
}
func (m *Mbclient) readRegisters(functionCode uint8, first uint16, numRegs uint16) ([]uint16, error) {
var err error
// If The timer is expired, conn is closed and needs to be reopened
if !m.t.Stop() {
@@ -71,11 +83,11 @@ func (m *Mbclient) ReadRegisters(first uint16, numRegs uint16) ([]uint16, error)
var mbpayload mbPDU
binary.BigEndian.PutUint16(req[0:2], m.transactionCounter)
binary.BigEndian.PutUint16(req[2:4], 0)
binary.BigEndian.PutUint16(req[2:4], 0) // Protocol identifier
binary.BigEndian.PutUint16(req[4:6], 6) // Length
req[6] = m.unit
req[7] = 3 //FunctionCode
binary.BigEndian.PutUint16(req[8:10], first-1)
req[7] = functionCode
binary.BigEndian.PutUint16(req[8:10], first-m.registerOffset)
binary.BigEndian.PutUint16(req[10:12], numRegs)
m.conn.SetDeadline(time.Now().Add(5 * time.Second))
@@ -114,7 +126,7 @@ func (m *Mbclient) ReadRegisters(first uint16, numRegs uint16) ([]uint16, error)
}
err = mbpayload.unMarshal(response)
if mbpayload.functionCode != 3 {
if mbpayload.functionCode != functionCode {
m.t.Reset(m.keepAliveDuration)
return nil, fmt.Errorf("modbus exception %v req: %x", mbpayload.functionCode&0x7F, req)
}