我拿到一台冷链设备,是浙港智能的无线测温监控系统,带了一个windows上的二进制程序,可以使用。但是我们的目标是,windows和linux都能使用啊,联系厂家也没能拿到芯片手册,坑爹呀。 无奈之下,反编译之,顺利搞定。正确拿到了温度的起始地址。初始条件已经具备,可以开发了。
我们采用已有的modbus库来实现。 目前modbus有三种实现方式:RTU/ASCII/TCP 我根据我的设备情况选择了RTU方式,即串口连接方式。 golang的modbus库提供了底层api的支持,我们只需要做好下面几件事: 1,因为要支持文件配置,定义了如下:
// 定义了EnvMap,其目的是存放各个配置项,便于程序随时使用,下面紧跟的是每个具体的配置项的key
var EnvMap = make(map[string]string)
var RtuDevice = "rtudevice"
var BaudRate = "baudrate"
var DataBits = "databits"
var Parity = "parity"
var StopBits = "stopbits"
var SlaveId = "slaveid"
var SerialTimeout = "serialtimeout"
var Address = "address"
var Len = "len"
// 定义上面每个key的初始化值
const(
DefaultRtuDevcie = "/dev/ttyUSB0"
DefaultBaudRate = "19200"
DefaultDataBits = "8"
DefaultParity = "N"
DefaultStopBits = "1"
DefaultSlaveId = "1"
DefaultSerialTimeout = "5"
DefaultAddress = "1105"
DefaultLen = "20"
)
// 定义配置文件的名称
const (
workerConf = "modbus.conf"
)
2,初始化配置项,如果配置文件存在,就读取,按照文件内容配置,如果不存在使用我们配置的默认值。
func initConfMap() {
strs := ReadFile(workerConf)
if strs != "" {
result := []string{}
for _, lineStr := range strings.Split(strs, "\n") {
lineStr = strings.TrimSpace(lineStr)
if lineStr == "" {
continue
}
result = strings.Split(lineStr, "=")
k := result[0]
v := result[1]
EnvMap[k] = v
}
}
// give a default value
if EnvMap[RtuDevice] == "" {
EnvMap[RtuDevice] = DefaultRtuDevcie
}
if EnvMap[BaudRate] == "" {
EnvMap[BaudRate] = DefaultBaudRate
}
if EnvMap[DataBits] == "" {
EnvMap[DataBits] = DefaultDataBits
}
if EnvMap[Parity] == "" {
EnvMap[Parity] = DefaultParity
}
if EnvMap[StopBits] == "" {
EnvMap[StopBits] = DefaultStopBits
}
if EnvMap[SlaveId] == "" {
EnvMap[SlaveId] = DefaultSlaveId
}
if EnvMap[SerialTimeout] == "" {
EnvMap[SerialTimeout] = DefaultSerialTimeout
}
if EnvMap[Address] == "" {
EnvMap[Address] = DefaultAddress
}
if EnvMap[Len] == "" {
EnvMap[Len] = DefaultLen
}
}
3,串口的配置
// 根据串口设备初始化一个handler
handler := modbus.NewRTUClientHandler(EnvMap[RtuDevice])
// 配置handler的波特率
baudRate, _ := strconv.Atoi(EnvMap[BaudRate])
handler.BaudRate = baudRate
// 数据位
dataBits, _ := strconv.Atoi(EnvMap[DataBits])
handler.DataBits = dataBits
// 校验位
handler.Parity = EnvMap[Parity]
// 停止位
stopBits, _ := strconv.Atoi(EnvMap[StopBits])
handler.StopBits = stopBits
// modbus SlaveId
slaveId, _ := strconv.Atoi(EnvMap[SlaveId])
handler.SlaveId = byte(slaveId)
// 超时时间
serialTimeout, _ := strconv.Atoi(EnvMap[SerialTimeout])
handler.Timeout = time.Duration(serialTimeout) * time.Second
4,串口连接
err := handler.Connect()
defer handler.Close()
5,根据handler创建client
client := modbus.NewClient(handler)
6,读取冷链设备的20个无线温度标签的温度值
var i uint16
inputLen, _ := strconv.ParseInt(EnvMap[Len], 10, 16)
len := uint16(inputLen)
inputAddr, _ := strconv.Atoi(EnvMap[Address])
address := uint16(inputAddr)
//log.Println("len: ", len)
myS1 := make([]string, len)
for i=0; i
至此,我们得到了一个关于温度的string数组,在此数组上可以架构我们的业务了。
有不清楚的地方随时可以咨询我,此外,闲来没事,还实现了一版java版的代码,篇幅关系就不多介绍了,有兴趣的可以私信我。
mail:[email protected]