使用Golang + Raspberry Pi + LPS331AP 测量了气压和温度
我是Go Advent Calendar第23天的负责人@yanolab。这是我在Qiita上的第一篇发文。
我想在第23天的文章中介绍一下如何使用Golang + Raspberry Pi + LPS331AP(I2C气压传感器模块)来测量气压和温度。
Golang 的一个个人喜好之处在于跨平台编译非常容易。作为一个经常编写多平台工具的人,这一点对我来说非常方便。此外,Golang 还支持为 ARM 输出二进制文件,因此可以在通用的 IA 设备上进行开发。而且,通过 Golang 编译的程序甚至不依赖于 libc,所以部署只需将其复制到目标机器上。简单得令人难以置信。
最近,购买Raspberry Pi相对容易。在亚马逊上也能买到。LPS331AP能在秋月购买到。虽然有各种各样的传感器模块,但推荐选用能够进行I2C通信的模块,因为在Raspberry Pi上操作较为容易。
为了在Raspberry Pi上与传感器模块进行交互,使用I2C是简单的。有关Raspberry Pi与LPS331AP模块的连接方法等,请参考此处等资料。由于有很多相关文章,请努力查找。只要传感器和Raspberry Pi能通过I2C进行交互,准备工作就完成了。
The given question (本題)
因为这是一篇关于Golang的文章,所以这次我们将通过Golang进行I2C通信。我立刻向谷歌老师询问,果然有前辈做过类似的工作,但很遗憾引用的文章已经消失在404页面……不过,好在代码库还存在,所以开发应该没问题。
首先,我们来为使用go进行交叉编译做准备。请转到安装go的文件夹中的src目录,并执行以下命令。
请运行以下命令来进行交叉编译:
sudo GOARCH=arm ./make.bash
通过运行构建,可以准备用于ARM的交叉编译环境。非常简单呢。
接下来,让我们将库安装在GOPATH目录下。可以使用以下命令进行库的安装。
按原生中文将以下句子改写,只需提供一种选择:
使用“GOARCH=arm“命令获取“bitbucket.org/gmcbay/i2c“库。
请确保设置 GOARCH=arm。如果忘记设置,将为主机的 CPU 进行构建。
然后,只需要编写一个通过 I2C 通信从 Raspberry Pi 读取 LPS331AP 传感器数据的程序即可。传感器的规格说明书可以在秋月电子的网页上找到,并且可以参考该说明书进行实现。基本上,只需向控制寄存器 (0x20) 写入要读取数据的指示,然后从专用寄存器 (0x28-0x2a, 0x2b-0x2c) 中读取数据即可。我将附上一个从 Golang 中使用 lps331ap 的代码作为参考。
package main
import (
"bitbucket.org/gmcbay/i2c"
"errors"
)
type LPS331AP struct {
bus *i2c.I2CBus
addr byte
active bool
}
func newDevice() *LPS331AP {
return &LPS331AP{}
}
func (l *LPS331AP) Init(busNumber byte, addr byte) error {
var err error
l.bus, err = i2c.Bus(busNumber)
l.addr = addr
return err
}
func (l *LPS331AP) Read(reg byte) (byte, error) {
buf, err := l.bus.ReadByteBlock(l.addr, reg, 1)
if err != nil {
return 0, err
}
return buf[0], nil
}
func (l *LPS331AP) ReadPressure() (float32, error) {
buf := make([]byte, 3)
for idx := 0x28; idx <= 0x2a; idx++ {
var err error
buf[idx-0x28], err = l.Read(byte(idx))
if err != nil {
return 0, err
}
}
return float32(int(buf[2])<<16|int(buf[1])<<8|int(buf[0])) / 4096.0, nil
}
func (l *LPS331AP) ReadTemperature() (float32, error) {
buf := make([]byte, 2)
for idx := 0x2b; idx <= 0x2c; idx++ {
var err error
buf[idx-0x2b], err = l.Read(byte(idx))
if err != nil {
return 0, err
}
}
return 42.5 + float32(^(int16(buf[1])<<8|int16(buf[0]))+1)*-1.0/480.0, nil
}
func (l *LPS331AP) Active() error {
id, err := l.Read(0x0f)
if err != nil {
return err
}
if id != 0xbb {
return errors.New("Invalid device.")
}
if err := l.bus.WriteByte(l.addr, 0x20, 0x90); err != nil {
return err
}
l.active = true
return nil
}
func (l *LPS331AP) Deactive() error {
if !l.active {
return nil
}
if err := l.bus.WriteByte(l.addr, 0x20, 0x0); err != nil {
return err
}
l.active = false
return nil
}
只需在主函数中使用上述结构体,并将读取的数据写入控制台。
package main
import (
"fmt"
)
func execOrDie(f func() error) {
if err := f(); err != nil {
panic(err)
}
}
func main() {
device := newDevice()
execOrDie(func() error { return device.Init(1, 0x5d) })
execOrDie(device.Active)
defer device.Deactive()
pressure, _ := device.ReadPressure()
temperature, _ := device.ReadTemperature()
fmt.Printf("%.2f\t%.2f\n", pressure, temperature)
}
请如下进行构建。
使用原生的中文进行改述:用 `GOARCH=arm go build *.go` 进行编译。
只需使用SCP或其他方式将生成的二进制文件进行复制,即可执行。
结束了
非常抱歉备感到准备不足,但是如果您使用 Golang 和树莓派,可以轻松制作一个简单的传感器设备。此外,Golang 还可以轻松创建 Web 应用程序,可以实时发布获取到的数据,或使用标准库的远程过程调用(RPC)构建传感器网络,这也很有趣。您也可以将数据收集到 Google webapps 中。Golang 真棒!!!
接下来是明天的Moriyoshi先生。请多关照。