tbrandon / mbserver Goto Github PK
View Code? Open in Web Editor NEWGolang Modbus Server (Slave)
License: MIT License
Golang Modbus Server (Slave)
License: MIT License
Most of the time serial did not read all the data frame and return error "bad serial frame error %v\n"
Line 39 in daf3c8c
Because it don't know when to start/stop reading
I have created a simple server and client apps:
https://github.com/simpleiot/simpleiot/blob/feature-modbus/cmd/modbus-client/main.go
https://github.com/simpleiot/simpleiot/blob/feature-modbus/cmd/modbus-server/main.go
When I send a packet to the server, it only ever receives one byte.
What causes the the Read() at this location:
https://github.com/tbrandon/mbserver/blob/master/servertu.go#L26
func (s *Server) acceptSerialRequests(port serial.Port) {
for {
buffer := make([]byte, 512)
bytesRead, err := port.Read(buffer)
if err != nil {
if err != io.EOF {
log.Printf("serial read error %v\n", err)
}
return
}
if bytesRead != 0 {
// Set the length of the packet to the number of read bytes.
packet := buffer[:bytesRead]
frame, err := NewRTUFrame(packet)
if err != nil {
log.Printf("bad serial frame error %v\n", err)
return
}
request := &Request{port, frame}
s.requestChan <- request
}
}
}
To read an entire packet, instead of just several bytes?
Thanks,
Cliff
Does anyone try starting server on their local ip address?
I start on localhost:1502 and have error.
But 127.0.0.1:1502 no error, and only able to connect it locally. Would like to automate install on my IOT device by automatically start the server with their respective IP Address.
Hello, I have both modbus slave and modbus master (implemented in GoLang) but I am not able to figure out how to get below list of exceptions when there a invalid operation read/write.
In modbus slave how to call func GetException(frame Framer) (exception Exception) ?
I am calling below function to read holding registers and handling err if any
result, err := client.ReadHoldingRegisters(req.StartAddress, req.Count)
client := mb.NewClient(handler.client)
result, err := client.ReadHoldingRegisters(req.StartAddress, req.Count)
if err != nil {
// Added close in since the keep alive will prevent it from ever reconnecting
level.Error(logger).Log("err: Modbus TCP Client Unavailable ", err.Error())
handler.client.Close()
go buildResponseRawData(*handler, req.Type, "", result, err, &req.ResultsChan)
} else {
go buildResponseRawData(*handler, req.Type, req.Endian, result, nil, &req.ResultsChan)
}
// Success operation successful.
Success Exception
// IllegalFunction function code received in the query is not recognized or allowed by slave.
IllegalFunction Exception = 1
// IllegalDataAddress data address of some or all the required entities are not allowed or do not exist in slave.
IllegalDataAddress Exception = 2
// IllegalDataValue value is not accepted by slave.
IllegalDataValue Exception = 3
// SlaveDeviceFailure Unrecoverable error occurred while slave was attempting to perform requested action.
SlaveDeviceFailure Exception = 4
// AcknowledgeSlave has accepted request and is processing it, but a long duration of time is required. This response is returned to prevent a timeout error from occurring in the master. Master can next issue a Poll Program Complete message to determine whether processing is completed.
AcknowledgeSlave Exception = 5
// SlaveDeviceBusy is engaged in processing a long-duration command. Master should retry later.
SlaveDeviceBusy Exception = 6
// NegativeAcknowledge Slave cannot perform the programming functions. Master should request diagnostic or error information from slave.
NegativeAcknowledge Exception = 7
// MemoryParityError Slave detected a parity error in memory. Master can retry the request, but service may be required on the slave device.
MemoryParityError Exception = 8
// GatewayPathUnavailable Specialized for Modbus gateways. Indicates a misconfigured gateway.
GatewayPathUnavailable Exception = 10
// GatewayTargetDeviceFailedtoRespond Specialized for Modbus gateways. Sent when slave fails to respond.
GatewayTargetDeviceFailedtoRespond Exception = 11
When I set some registers value and modbus client write registers at same time, should it add some lock to avoid conflict?
Hi!
How write multiple registers in server?
E.G.: server.WriteMultipleRegisters(1, 2, []byte{0, 3, 0, 4})
I am willing to put a handler on my Modbus connection and everything was going fine until the moment I tried to implement server customization as it's written in the documentation.
import (
"errors"
"fmt"
"time"
"github.com/goburrow/serial"
. "github.com/tbrandon/mbserver"
)
var server *Server
func ModbusInit() {
server = NewServer()
server.RegisterFunctionHandler(2,
func(s *Server, frame Framer) ([]byte, *Exception) {
register, numRegs, endRegister := frame.registerAddressAndNumber()
// Check the request is within the allocated memory
if endRegister > 65535 {
return []byte{}, &IllegalDataAddress
}
dataSize := numRegs / 8
if (numRegs % 8) != 0 {
dataSize++
}
data := make([]byte, 1+dataSize)
data[0] = byte(dataSize)
for i := range s.DiscreteInputs[register:endRegister] {
// Return all 1s, regardless of the value in the DiscreteInputs array.
shift := uint(i) % 8
data[1+i/8] |= byte(1 << shift)
}
return data, &Success
})
}
And when I'm trying to build it with my script:
#!/bin/bash
export GOPATH=pwd
go get github.com/tbrandon/mbserver
go get github.com/goburrow/serial
go build modbus.go
It appears with a message(the one and the only):
frame.registerAddressAndNumber undefined (type mbserver.Framer has no field or method registerAddressAndNumber)
This comes from the fact that registerAddressAndNumber(frame Framer) is a private function and we can't call it from outside of the package. And how do we deal with that if by documentation we are meant to call it from another package? Was it actually meant to be a private function? Do we need to override all structures and functions from that package to make it work as it was meant to work?
Hope there is a way of correctly implementing a customized server without changing function privacy status by ourselves something like this.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.