gobot.io/x/gobot@v1.16.0/drivers/i2c/mpl115a2_driver.go (about)

     1  package i2c
     2  
     3  import (
     4  	"gobot.io/x/gobot"
     5  
     6  	"bytes"
     7  	"encoding/binary"
     8  	"time"
     9  )
    10  
    11  const mpl115a2Address = 0x60
    12  
    13  const MPL115A2_REGISTER_PRESSURE_MSB = 0x00
    14  const MPL115A2_REGISTER_PRESSURE_LSB = 0x01
    15  const MPL115A2_REGISTER_TEMP_MSB = 0x02
    16  const MPL115A2_REGISTER_TEMP_LSB = 0x03
    17  const MPL115A2_REGISTER_A0_COEFF_MSB = 0x04
    18  const MPL115A2_REGISTER_A0_COEFF_LSB = 0x05
    19  const MPL115A2_REGISTER_B1_COEFF_MSB = 0x06
    20  const MPL115A2_REGISTER_B1_COEFF_LSB = 0x07
    21  const MPL115A2_REGISTER_B2_COEFF_MSB = 0x08
    22  const MPL115A2_REGISTER_B2_COEFF_LSB = 0x09
    23  const MPL115A2_REGISTER_C12_COEFF_MSB = 0x0A
    24  const MPL115A2_REGISTER_C12_COEFF_LSB = 0x0B
    25  const MPL115A2_REGISTER_STARTCONVERSION = 0x12
    26  
    27  // MPL115A2Driver is a Gobot Driver for the MPL115A2 I2C digitial pressure/temperature sensor.
    28  type MPL115A2Driver struct {
    29  	name       string
    30  	connector  Connector
    31  	connection Connection
    32  	Config
    33  	gobot.Eventer
    34  	A0  float32
    35  	B1  float32
    36  	B2  float32
    37  	C12 float32
    38  }
    39  
    40  // NewMPL115A2Driver creates a new Gobot Driver for an MPL115A2
    41  // I2C Pressure/Temperature sensor.
    42  //
    43  // Params:
    44  //		conn Connector - the Adaptor to use with this Driver
    45  //
    46  // Optional params:
    47  //		i2c.WithBus(int):	bus to use with this driver
    48  //		i2c.WithAddress(int):	address to use with this driver
    49  //
    50  func NewMPL115A2Driver(a Connector, options ...func(Config)) *MPL115A2Driver {
    51  	m := &MPL115A2Driver{
    52  		name:      gobot.DefaultName("MPL115A2"),
    53  		connector: a,
    54  		Config:    NewConfig(),
    55  		Eventer:   gobot.NewEventer(),
    56  	}
    57  
    58  	for _, option := range options {
    59  		option(m)
    60  	}
    61  
    62  	// TODO: add commands to API
    63  	m.AddEvent(Error)
    64  
    65  	return m
    66  }
    67  
    68  // Name returns the name of the device.
    69  func (h *MPL115A2Driver) Name() string { return h.name }
    70  
    71  // SetName sets the name of the device.
    72  func (h *MPL115A2Driver) SetName(n string) { h.name = n }
    73  
    74  // Connection returns the Connection of the device.
    75  func (h *MPL115A2Driver) Connection() gobot.Connection { return h.connector.(gobot.Connection) }
    76  
    77  // Start writes initialization bytes and reads from adaptor
    78  // using specified interval to accelerometer andtemperature data
    79  func (h *MPL115A2Driver) Start() (err error) {
    80  	if err := h.initialization(); err != nil {
    81  		return err
    82  	}
    83  
    84  	return
    85  }
    86  
    87  // Halt returns true if devices is halted successfully
    88  func (h *MPL115A2Driver) Halt() (err error) { return }
    89  
    90  // Pressure fetches the latest data from the MPL115A2, and returns the pressure
    91  func (h *MPL115A2Driver) Pressure() (p float32, err error) {
    92  	p, _, err = h.getData()
    93  	return
    94  }
    95  
    96  // Temperature fetches the latest data from the MPL115A2, and returns the temperature
    97  func (h *MPL115A2Driver) Temperature() (t float32, err error) {
    98  	_, t, err = h.getData()
    99  	return
   100  }
   101  
   102  func (h *MPL115A2Driver) initialization() (err error) {
   103  	var coA0 int16
   104  	var coB1 int16
   105  	var coB2 int16
   106  	var coC12 int16
   107  
   108  	bus := h.GetBusOrDefault(h.connector.GetDefaultBus())
   109  	address := h.GetAddressOrDefault(mpl115a2Address)
   110  
   111  	h.connection, err = h.connector.GetConnection(address, bus)
   112  	if err != nil {
   113  		return err
   114  	}
   115  
   116  	if _, err = h.connection.Write([]byte{MPL115A2_REGISTER_A0_COEFF_MSB}); err != nil {
   117  		return
   118  	}
   119  
   120  	data := make([]byte, 8)
   121  	if _, err = h.connection.Read(data); err != nil {
   122  		return
   123  	}
   124  	buf := bytes.NewBuffer(data)
   125  
   126  	binary.Read(buf, binary.BigEndian, &coA0)
   127  	binary.Read(buf, binary.BigEndian, &coB1)
   128  	binary.Read(buf, binary.BigEndian, &coB2)
   129  	binary.Read(buf, binary.BigEndian, &coC12)
   130  
   131  	coC12 = coC12 >> 2
   132  
   133  	h.A0 = float32(coA0) / 8.0
   134  	h.B1 = float32(coB1) / 8192.0
   135  	h.B2 = float32(coB2) / 16384.0
   136  	h.C12 = float32(coC12) / 4194304.0
   137  
   138  	return
   139  }
   140  
   141  // getData fetches the latest data from the MPL115A2
   142  func (h *MPL115A2Driver) getData() (p, t float32, err error) {
   143  	var temperature uint16
   144  	var pressure uint16
   145  	var pressureComp float32
   146  
   147  	if _, err = h.connection.Write([]byte{MPL115A2_REGISTER_STARTCONVERSION, 0}); err != nil {
   148  		return
   149  	}
   150  	time.Sleep(5 * time.Millisecond)
   151  
   152  	if _, err = h.connection.Write([]byte{MPL115A2_REGISTER_PRESSURE_MSB}); err != nil {
   153  		return
   154  	}
   155  
   156  	data := []byte{0, 0, 0, 0}
   157  	bytesRead, err1 := h.connection.Read(data)
   158  	if err1 != nil {
   159  		err = err1
   160  		return
   161  	}
   162  
   163  	if bytesRead == 4 {
   164  		buf := bytes.NewBuffer(data)
   165  		binary.Read(buf, binary.BigEndian, &pressure)
   166  		binary.Read(buf, binary.BigEndian, &temperature)
   167  
   168  		temperature = temperature >> 6
   169  		pressure = pressure >> 6
   170  
   171  		pressureComp = float32(h.A0) + (float32(h.B1)+float32(h.C12)*float32(temperature))*float32(pressure) + float32(h.B2)*float32(temperature)
   172  		p = (65.0/1023.0)*pressureComp + 50.0
   173  		t = ((float32(temperature) - 498.0) / -5.35) + 25.0
   174  	}
   175  
   176  	return
   177  }