Skip to content

Commit

Permalink
i2c: add bmp280 driver, then encapsulate it with bme280 and add Humidity
Browse files Browse the repository at this point in the history
Signed-off-by: deadprogram <[email protected]>
  • Loading branch information
deadprogram committed Mar 31, 2017
1 parent 8940824 commit c9b992a
Show file tree
Hide file tree
Showing 3 changed files with 237 additions and 118 deletions.
123 changes: 5 additions & 118 deletions drivers/i2c/bme280_driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,11 @@ package i2c
import (
"bytes"
"encoding/binary"

"gobot.io/x/gobot"
)

const bme280RegisterHumidityMSB = 0xFD
const bme280RegisterCalibDigH1 = 0xa1
const bme280RegisterCalibDigH2LSB = 0xe1
const bmp280RegisterCalib00 = 0x88

type bmp280CalibrationCoefficients struct {
t1 uint16
t2 int16
t3 int16
p1 uint16
p2 int16
p3 int16
p4 int16
p5 int16
p6 int16
p7 int16
p8 int16
p9 int16
}

type bmeHumidityCalibrationCoefficients struct {
h1 uint8
Expand All @@ -38,13 +20,8 @@ type bmeHumidityCalibrationCoefficients struct {

// BME280Driver is a driver for the BME280 temperature/humidity sensor
type BME280Driver struct {
name string
connector Connector
connection Connection
Config

tpc *bmp280CalibrationCoefficients
hc *bmeHumidityCalibrationCoefficients
*BMP280Driver
hc *bmeHumidityCalibrationCoefficients
}

// NewBME280Driver creates a new driver with specified i2c interface.
Expand All @@ -57,11 +34,8 @@ type BME280Driver struct {
//
func NewBME280Driver(c Connector, options ...func(Config)) *BME280Driver {
b := &BME280Driver{
name: gobot.DefaultName("BME280"),
connector: c,
Config: NewConfig(),
tpc: &bmp280CalibrationCoefficients{},
hc: &bmeHumidityCalibrationCoefficients{},
BMP280Driver: NewBMP280Driver(c),
hc: &bmeHumidityCalibrationCoefficients{},
}

for _, option := range options {
Expand All @@ -72,21 +46,6 @@ func NewBME280Driver(c Connector, options ...func(Config)) *BME280Driver {
return b
}

// Name returns the name of the device.
func (d *BME280Driver) Name() string {
return d.name
}

// SetName sets the name of the device.
func (d *BME280Driver) SetName(n string) {
d.name = n
}

// Connection returns the connection of the device.
func (d *BME280Driver) Connection() gobot.Connection {
return d.connector.(gobot.Connection)
}

// Start initializes the BME280 and loads the calibration coefficients.
func (d *BME280Driver) Start() (err error) {
bus := d.GetBusOrDefault(d.connector.GetDefaultBus())
Expand All @@ -96,68 +55,23 @@ func (d *BME280Driver) Start() (err error) {
return err
}

// TODO: set sleep mode here...

if err := d.initialization(); err != nil {
return err
}

if err := d.initHumidity(); err != nil {
return err
}

// TODO: set usage mode here...

// TODO: set default sea level here

return nil
}

// Halt halts the device.
func (d *BME280Driver) Halt() (err error) {
return nil
}

// Temperature returns the current temperature, in celsius degrees.
func (d *BME280Driver) Temperature() (temp float32, err error) {
// TODO: implement this
return 0, nil
}

// Pressure returns the current barometric pressure, in Pa
func (d *BME280Driver) Pressure() (press float32, err error) {
// TODO: implement this
return 0, nil
}

// Humidity returns the current humidity in percentage of relative humidity
func (d *BME280Driver) Humidity() (humidity float32, err error) {
// TODO: implement this
return 0, nil
}

// initialization reads the calibration coefficients.
func (d *BME280Driver) initialization() (err error) {
var coefficients []byte
if coefficients, err = d.read(bmp280RegisterCalib00, 26); err != nil {
return err
}
buf := bytes.NewBuffer(coefficients)
binary.Read(buf, binary.LittleEndian, &d.tpc.t1)
binary.Read(buf, binary.LittleEndian, &d.tpc.t2)
binary.Read(buf, binary.LittleEndian, &d.tpc.t3)
binary.Read(buf, binary.LittleEndian, &d.tpc.p1)
binary.Read(buf, binary.LittleEndian, &d.tpc.p2)
binary.Read(buf, binary.LittleEndian, &d.tpc.p3)
binary.Read(buf, binary.LittleEndian, &d.tpc.p4)
binary.Read(buf, binary.LittleEndian, &d.tpc.p5)
binary.Read(buf, binary.LittleEndian, &d.tpc.p6)
binary.Read(buf, binary.LittleEndian, &d.tpc.p7)
binary.Read(buf, binary.LittleEndian, &d.tpc.p8)
binary.Read(buf, binary.LittleEndian, &d.tpc.p9)

return nil
}

// read the humidity calibration coefficients.
func (d *BME280Driver) initHumidity() (err error) {
var coefficients []byte
Expand Down Expand Up @@ -190,21 +104,6 @@ func (d *BME280Driver) initHumidity() (err error) {
return nil
}

// TODO: implement
func (d *BME280Driver) rawTempPress() (temp int16, press int16, err error) {
return 0, 0, nil
}

// TODO: implement
func (d *BME280Driver) calculateTemp(rawTemp int16) float32 {
return 0
}

// TODO: implement
func (d *BME280Driver) calculatePress(rawPress int16) float32 {
return 0
}

func (d *BME280Driver) rawHumidity() (int16, error) {
ret, err := d.read(bme280RegisterHumidityMSB, 2)
if err != nil {
Expand Down Expand Up @@ -247,15 +146,3 @@ func (d *BME280Driver) calculateHumidity(rawH int16) float32 {

return h * y
}

func (d *BME280Driver) read(address byte, n int) ([]byte, error) {
if _, err := d.connection.Write([]byte{address}); err != nil {
return nil, err
}
buf := make([]byte, n)
bytesRead, err := d.connection.Read(buf)
if bytesRead != n || err != nil {
return nil, err
}
return buf, nil
}
168 changes: 168 additions & 0 deletions drivers/i2c/bmp280_driver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package i2c

import (
"bytes"
"encoding/binary"

"gobot.io/x/gobot"
)

const bmp280RegisterCalib00 = 0x88

type bmp280CalibrationCoefficients struct {
t1 uint16
t2 int16
t3 int16
p1 uint16
p2 int16
p3 int16
p4 int16
p5 int16
p6 int16
p7 int16
p8 int16
p9 int16
}

// BMP280Driver is a driver for the BMP280 temperature/pressure sensor
type BMP280Driver struct {
name string
connector Connector
connection Connection
Config

tpc *bmp280CalibrationCoefficients
}

// NewBMP280Driver creates a new driver with specified i2c interface.
// Params:
// conn Connector - the Adaptor to use with this Driver
//
// Optional params:
// i2c.WithBus(int): bus to use with this driver
// i2c.WithAddress(int): address to use with this driver
//
func NewBMP280Driver(c Connector, options ...func(Config)) *BMP280Driver {
b := &BMP280Driver{
name: gobot.DefaultName("BMP280"),
connector: c,
Config: NewConfig(),
tpc: &bmp280CalibrationCoefficients{},
}

for _, option := range options {
option(b)
}

// TODO: expose commands to API
return b
}

// Name returns the name of the device.
func (d *BMP280Driver) Name() string {
return d.name
}

// SetName sets the name of the device.
func (d *BMP280Driver) SetName(n string) {
d.name = n
}

// Connection returns the connection of the device.
func (d *BMP280Driver) Connection() gobot.Connection {
return d.connector.(gobot.Connection)
}

// Start initializes the BMP280 and loads the calibration coefficients.
func (d *BMP280Driver) Start() (err error) {
bus := d.GetBusOrDefault(d.connector.GetDefaultBus())
address := d.GetAddressOrDefault(bmp180Address)

if d.connection, err = d.connector.GetConnection(address, bus); err != nil {
return err
}

// TODO: set sleep mode here...

if err := d.initialization(); err != nil {
return err
}

// TODO: set usage mode here...

// TODO: set default sea level here

return nil
}

// Halt halts the device.
func (d *BMP280Driver) Halt() (err error) {
return nil
}

// Temperature returns the current temperature, in celsius degrees.
func (d *BMP280Driver) Temperature() (temp float32, err error) {
// TODO: implement this
return 0, nil
}

// Pressure returns the current barometric pressure, in Pa
func (d *BMP280Driver) Pressure() (press float32, err error) {
// TODO: implement this
return 0, nil
}

// initialization reads the calibration coefficients.
func (d *BMP280Driver) initialization() (err error) {
// TODO: set sleep mode here...

var coefficients []byte
if coefficients, err = d.read(bmp280RegisterCalib00, 26); err != nil {
return err
}
buf := bytes.NewBuffer(coefficients)
binary.Read(buf, binary.LittleEndian, &d.tpc.t1)
binary.Read(buf, binary.LittleEndian, &d.tpc.t2)
binary.Read(buf, binary.LittleEndian, &d.tpc.t3)
binary.Read(buf, binary.LittleEndian, &d.tpc.p1)
binary.Read(buf, binary.LittleEndian, &d.tpc.p2)
binary.Read(buf, binary.LittleEndian, &d.tpc.p3)
binary.Read(buf, binary.LittleEndian, &d.tpc.p4)
binary.Read(buf, binary.LittleEndian, &d.tpc.p5)
binary.Read(buf, binary.LittleEndian, &d.tpc.p6)
binary.Read(buf, binary.LittleEndian, &d.tpc.p7)
binary.Read(buf, binary.LittleEndian, &d.tpc.p8)
binary.Read(buf, binary.LittleEndian, &d.tpc.p9)

// TODO: set usage mode here...
// TODO: set default sea level here

return nil
}

// TODO: implement
func (d *BMP280Driver) rawTempPress() (temp int16, press int16, err error) {
return 0, 0, nil
}

// TODO: implement
func (d *BMP280Driver) calculateTemp(rawTemp int16) float32 {
return 0
}

// TODO: implement
func (d *BMP280Driver) calculatePress(rawPress int16) float32 {
return 0
}

func (d *BMP280Driver) read(address byte, n int) ([]byte, error) {
if _, err := d.connection.Write([]byte{address}); err != nil {
return nil, err
}
buf := make([]byte, n)
bytesRead, err := d.connection.Read(buf)
if bytesRead != n || err != nil {
return nil, err
}
return buf, nil
}
Loading

0 comments on commit c9b992a

Please sign in to comment.