重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
用到的gomodbus包是坛友slzm40编写和共享的,感谢他的无私分享,本帖只是抛砖引玉,将我自己学习的一些经历分享给大家;有关modbus包可以直接向slzm40请教或一起讨论;
创新互联制作网站网页找三站合一网站制作公司,专注于网页设计,成都做网站、成都网站建设,网站设计,企业网站搭建,网站开发,建网站业务,680元做网站,已为近1000家服务,创新互联网站建设将一如既往的为我们的客户提供最优质的网站建设、网络营销推广服务!
包地址"github.com/thinkgos/gomodbus";
添加一对虚拟串口
打开modbus-slave从机软件,用来测试从机;
需要注意设置通信地址和读取寄存器的地址和数量;
查看可用串口,因为虚拟串口选择com1和com2,虚拟中我选择使用/dev/ttyS1
编译运行,会提示串口打开失败,这是因为linux对设备的权限做了限制
获取串口读写、运行等权限
我们已经能正确读取03寄存器的值;其他功能可以自行测试;
package main
import (
"fmt"
modbus "github.com/thinkgos/gomodbus"
"github.com/thinkgos/gomodbus/mb"
"time"
)
func main(){
//调用RTUClientProvider的构造函数,返回结构体指针
p := modbus.NewRTUClientProvider()
p.Address = "/dev/ttyS1"
p.BaudRate = 115200
p.DataBits = 8
p.Parity = "N"
p.StopBits = 1
p.Timeout = 100 * time.Millisecond
client := mb.NewClient(p)
client.LogMode(true)
err := client.Start()
if err != nil {
fmt.Println("start err,", err)
return
}
for {
value, err := client.ReadHoldingRegisters(1, 1, 3)
if err != nil {
fmt.Println("readHoldErr,", err)
} else {
fmt.Printf("%#v\n", value)
}
time.Sleep(time.Second * 3)
}
}
1、goroutine:在go语言中,每一个并发的执行单元叫做goroutine,如果一个程序中包含多个goroutine,对两个函数的调用则可能发生在同一时刻
2、main goroutine:当一个程序启动时,其主函数即在一个单独的goroutine中运行,我们叫他为main gorountine
3、go goroutine:新的goroutine会用go语句来创建,go+函数名,go语句会使其语句中的函数在一新创建的goroutine中运行,而go语句本身会迅速地完成
4、goroutine的退出:主函数返回时,所有的goroutine都会被直接打断,程序退出,除了从主函数退出或者终止程序之外,没有其他方法能够让一个goroutine来打断另一个的执行,但是可以通过另一种方式来实现这个目的,通过goroutine之间的通信来让一个goroutine请求其他的goroutine,并让请求的goroutine自行结束执行
//创建一个串口通讯 SerialPort CurrentPort = null; CurrentPort = new SerialPort(); CurrentPortReadBufferSize = 128; CurrentPortPortName = comName; //端口号 CurrentPortBaudRate = bandRate; //比特率 CurrentPortParity =parity;/go语言做串口通信,我应该从什么地方入手,IO是什
智能合约调用是实现一个 DApp 的关键,一个完整的 DApp 包括前端、后端、智能合约及区块 链系统,智能合约的调用是连接区块链与前后端的关键。
我们先来了解一下智能合约调用的基础原理。智能合约运行在以太坊节点的 EVM 中。因此要 想调用合约必须要访问某个节点。
以后端程序为例,后端服务若想连接节点有两种可能,一种是双 方在同一主机,此时后端连接节点可以采用 本地 IPC(Inter-Process Communication,进 程间通信)机制,也可以采用 RPC(Remote Procedure Call,远程过程调用)机制;另 一种情况是双方不在同一台主机,此时只能采用 RPC 机制进行通信。
提到 RPC, 读者应该对 Geth 启动参数有点印象,Geth 启动时可以选择开启 RPC 服务,对应的 默认服务端口是 8545。。
接着,我们来了解一下智能合约运行的过程。
智能合约的运行过程是后端服务连接某节点,将 智能合约的调用(交易)发送给节点,节点在验证了交易的合法性后进行全网广播,被矿工打包到 区块中代表此交易得到确认,至此交易才算完成。
就像数据库一样,每个区块链平台都会提供主流 开发语言的 SDK(Software Development Kit,软件开发工具包),由于 Geth 本身就是用 Go 语言 编写的,因此若想使用 Go 语言连接节点、发交易,直接在工程内导入 go-ethereum(Geth 源码) 包就可以了,剩下的问题就是流程和 API 的事情了。
总结一下,智能合约被调用的两个关键点是节点和 SDK。
由于 IPC 要求后端与节点必须在同一主机,所以很多时候开发者都会采用 RPC 模式。除了 RPC,以太坊也为开发者提供了 json- rpc 接口,本文就不展开讨论了。
接下来介绍如何使用 Go 语言,借助 go-ethereum 源码库来实现智能合约的调用。这是有固定 步骤的,我们先来说一下总体步骤,以下面的合约为例。
步骤 01:编译合约,获取合约 ABI(Application Binary Interface,应用二进制接口)。 单击【ABI】按钮拷贝合约 ABI 信息,将其粘贴到文件 calldemo.abi 中(可使用 Go 语言IDE 创建该文件,文件名可自定义,后缀最好使用 abi)。
最好能将 calldemo.abi 单独保存在一个目录下,输入“ls”命令只能看到 calldemo.abi 文件,参 考效果如下:
步骤 02:获得合约地址。注意要将合约部署到 Geth 节点。因此 Environment 选择为 Web3 Provider。
在【Environment】选项框中选择“Web3 Provider”,然后单击【Deploy】按钮。
部署后,获得合约地址为:0xa09209c28AEf59a4653b905792a9a910E78E7407。
步骤 03:利用 abigen 工具(Geth 工具包内的可执行程序)编译智能合约为 Go 代码。abigen 工具的作用是将 abi 文件转换为 Go 代码,命令如下:
其中各参数的含义如下。 (1)abi:是指定传入的 abi 文件。 (2)type:是指定输出文件中的基本结构类型。 (3)pkg:指定输出文件 package 名称。 (4)out:指定输出文件名。 执行后,将在代码目录下看到 funcdemo.go 文件,读者可以打开该文件欣赏一下,注意不要修改它。
步骤 04:创建 main.go,填入如下代码。 注意代码中 HexToAddress 函数内要传入该合约部署后的地址,此地址在步骤 01 中获得。
步骤 04:设置 go mod,以便工程自动识别。
前面有所提及,若要使用 Go 语言调用智能合约,需要下载 go-ethereum 工程,可以使用下面 的指令:
该指令会自动将 go-ethereum 下载到“$GOPATH/src/github.com/ethereum/go-ethereum”,这样还算 不错。不过,Go 语言自 1.11 版本后,增加了 module 管理工程的模式。只要设置好了 go mod,下载 依赖工程的事情就不必关心了。
接下来设置 module 生效和 GOPROXY,命令如下:
在项目工程内,执行初始化,calldemo 可以自定义名称。
步骤 05:运行代码。执行代码,将看到下面的效果,以及最终输出的 2020。
上述输出信息中,可以看到 Go 语言会自动下载依赖文件,这就是 go mod 的神奇之处。看到 2020,相信读者也知道运行结果是正确的了。