使用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先生。请多关照。

广告
将在 10 秒后关闭
bannerAds