Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

TinyGoを使用したAE-BMX055の動作プログラムの作成

1.はじめに

 今までAruduinoやルネサス系のマイコンを利用してC言語でプログラムを書くことが多かったのですが、最近の言語を学習したいと思い、Micropythonに取り組んでいました。MicroPythonは結構色々な人が取り組んでネット上での資料も多くあったので、私がやっていることが少しでも利用できる人がいたら良いと思い、またGo言語にも少し興味があったのでTinyGoに取り組んでみることにしました。

2. ハードウェアについて

 今回はとりあえず手元にあった9軸センサモジュールのAE-BMX055とSeeed XIAOを使って製作しました。Seeed XIAOはTinyGoをサポートしているので開発しやすいと思います。
 下の図は今回の製作した回路図です。
AE-BMX055.png

3.プログラムについて

 AE-BMX055はI2Cを使用するので、TinyGo Driversをインストールして開発しました。
 プログラムはTinyGo Driversを利用してI2Cで加速度、角速度、地磁気のデータを取得しています。
 下のプログラムはAE-BMX055の制御関係のプログラムです。

bmx055.go
package bmx055

import (
    "time"
    "tinygo.org/x/drivers"
)

type bmx055_data struct {
    // Acc
    XAcc float64
    YAcc float64
    ZAcc float64

    // Gyaro
    XGyro float64
    YGyro float64
    ZGyro float64

    // Mag
    XMag int32
    YMag int32
    ZMag int32
}

type Device struct {
    bus         drivers.I2C
    AccAddress  uint8
    GyroAddress uint8
    MagAddress  uint8
    Dat         bmx055_data
}

func New(bus drivers.I2C) Device {
    return Device{
        bus:         bus,
        AccAddress:  ACCAddress,
        GyroAddress: GyroAddress,
        MagAddress:  MagAddress,
    }
}

/* Init*/
func (d *Device) Configture() {
    /* Acc*/
    _ = d.bus.WriteRegister(d.AccAddress, AccPmuRangeReg, []byte{0x03})
    _ = d.bus.WriteRegister(d.AccAddress, AccPmuBwReg, []byte{0x08})
    _ = d.bus.WriteRegister(d.AccAddress, AccPmuLpwReg, []byte{0x00})
    time.Sleep(100 * time.Millisecond)

    /* Gyro*/
    _ = d.bus.WriteRegister(d.GyroAddress, GyroRangeReg, []byte{0x04})
    _ = d.bus.WriteRegister(d.GyroAddress, GyroBwReg, []byte{0x07})
    _ = d.bus.WriteRegister(d.GyroAddress, GyroLpm1Reg, []byte{0x00})
    time.Sleep(100 * time.Millisecond)

    /* Mag */
    _ = d.bus.WriteRegister(d.MagAddress, MagPowCtlReg, []byte{0x83})
    time.Sleep(100 * time.Millisecond)
    _ = d.bus.WriteRegister(d.MagAddress, MagPowCtlReg, []byte{0x01})
    time.Sleep(100 * time.Millisecond)

    _ = d.bus.WriteRegister(d.MagAddress, MagAdvOpOutputReg, []byte{0x00})
    _ = d.bus.WriteRegister(d.MagAddress, MagAxesReg, []byte{0x84})
    _ = d.bus.WriteRegister(d.MagAddress, MagRepXyReg, []byte{0x04})
    _ = d.bus.WriteRegister(d.MagAddress, MagRepZReg, []byte{0x16})

}

//isConnected
func (d *Device) IsConnected() bool {
    data := make([]byte, 1)
    _ = d.bus.ReadRegister(d.AccAddress, BGW_CHIPID, data)
    return data[0] == 0xfa
}

/* Get Acceralater Data Function */
func (d *Device) GetAcc() error {
    data := make([]byte, 6)
    err := d.bus.ReadRegister(d.AccAddress, AccDataStartReg, data)
    if err != nil {
        println(err)
        return err
    }
    // Get ACC Data

    x := int32(uint16(data[1])*256|uint16(data[0]&0xf0)) >> 4
    if x > 2047 {
        x -= 4096
    }
    y := int32(uint16(data[3])*256|uint16(data[2]&0xf0)) >> 4
    if y > 2047 {
        y -= 4096
    }
    z := int32(uint16(data[5])*256|uint16(data[4]&0xf0)) >> 4
    if z > 2047 {
        z -= 4096
    }

    d.Dat.XAcc = float64(x) * 0.0196
    d.Dat.YAcc = float64(y) * 0.0196
    d.Dat.ZAcc = float64(z) * 0.0196

    return nil
}

/* Get Gyro Data Function */
func (d *Device) GetGyro() error {
    data := make([]byte, 6)
    err := d.bus.ReadRegister(d.GyroAddress, GyroDataStartReg, data)
    if err != nil {
        println(err)
        return err
    }

    // Get Gyro Data
    x := int32(uint16(data[1])<<8 | uint16(data[0]))
    if x > 32767 {
        x -= 65536
    }
    y := int32(uint16(data[3])<<8 | uint16(data[2]))
    if y > 32767 {
        y -= 65536
    }
    z := int32(uint16(data[5])<<8 | uint16(data[4]))
    if z > 32767 {
        z -= 65536
    }

    //
    d.Dat.XGyro = float64(x) * 0.0038
    d.Dat.YGyro = float64(y) * 0.0038
    d.Dat.ZGyro = float64(z) * 0.0038

    return nil
}

/* Get Magnetic Filed Data Function */
func (d *Device) GetMag() error {

    data := make([]byte, 6)

    err := d.bus.ReadRegister(d.MagAddress, MagDataStartReg, data)
    if err != nil {
        println(err)
        return err
    }
    // Get ACC Data
    d.Dat.XMag = int32(uint16(data[1])<<8|uint16(data[0]&0xf8)) / 8
    if d.Dat.XMag > 4095 {
        d.Dat.XMag -= 8192
    }
    d.Dat.YMag = int32(uint16(data[3])<<8|uint16(data[2]&0xf8)) / 8
    if d.Dat.YMag > 4095 {
        d.Dat.YMag -= 8192
    }
    d.Dat.ZMag = int32(uint16(data[5])<<8|uint16(data[4]&0xfe)) / 2
    if d.Dat.ZMag > 16383 {
        d.Dat.ZMag -= 32768
    }
    return nil
}

下のプログラムは動作確認用のプログラムです。

main.go
package bmx055

import (
    "fmt"
    "machine"
    "time"
)

func main() {

    var err error

    machine.I2C0.Configure(machine.I2CConfig{})
    d := New(machine.I2C0)

    conected := d.IsConnected()

    // BMX055 is Conenect ?
    if !conected {
        // Not Connected
        println("Not Connected!")
        for {
        }
    }

    // Initilaize For BMX055
    d.Configture()

    for {

        /* Get Accelerometer Data */
        err = d.GetGyro()
        if err == nil {
            fmt.Printf("Gyro : x=%5.2f y=%5.2f z=%5.2f\n", d.Dat.XGyro, d.Dat.YGyro, d.Dat.ZGyro)
        }

        /* Get Gyro Data */
        err = d.GetAcc()
        if err == nil {
            fmt.Printf("Acc  : x=%5.2f y=%5.2f z=%5.2f\n", d.Dat.XAcc, d.Dat.YAcc, d.Dat.ZAcc)
        }

        /* Get Geomagnetic sensor Data*/
        err = d.GetMag()
        if err == nil {
            fmt.Printf("Mag  : x=%4d y=%4d z=%4d\n", d.Dat.XMag, d.Dat.YMag, d.Dat.ZMag)
        }

        fmt.Println()

        time.Sleep(100 * time.Millisecond)
    }
}

4. 動作の様子

 下の図のようにシリアルポート経由で角速度、加速度、地磁気のデータが出力されます。
Terminal.png

5. 最後に

 今回のTinyGoのプログラムを作ってみて、Go言語の楽しさがわかってきました。Go言語をやり始めて3週間ぐらいですが、何とか本などを見ながら、サンプルプログラムを作ることができました。まだまだ、未完成ですがとりあえずはデータを取得できるので何かに活用できると思います。
 もし、良かったらここに公開していますので、自由に使ってください。
 次は色々なセンサを組み合わせて実際に役立つものをに取り組みたいと思います。

Keisuke-Hongyo
某県で工業高校の教員をしています。遊びでマイコンのプログラムを作成してます。色々と教えて頂けるとうれしいです。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away