gobot.io/x/gobot/v2@v2.1.0/drivers/i2c/mpl115a2_driver.go (about) 1 package i2c 2 3 import ( 4 "gobot.io/x/gobot/v2" 5 6 "bytes" 7 "encoding/binary" 8 "time" 9 ) 10 11 const mpl115a2DefaultAddress = 0x60 12 13 const ( 14 mpl115A2Reg_PressureMSB = 0x00 // first ADC register 15 mpl115A2Reg_PressureLSB = 0x01 16 mpl115A2Reg_TempMSB = 0x02 17 mpl115A2Reg_TempLSB = 0x03 18 19 mpl115A2Reg_A0_MSB = 0x04 // first coefficient register 20 mpl115A2Reg_A0_LSB = 0x05 21 mpl115A2Reg_B1_MSB = 0x06 22 mpl115A2Reg_B1_LSB = 0x07 23 mpl115A2Reg_B2_MSB = 0x08 24 mpl115A2Reg_B2_LSB = 0x09 25 mpl115A2Reg_C12_MSB = 0x0A 26 mpl115A2Reg_C12_LSB = 0x0B 27 28 mpl115A2Reg_StartConversion = 0x12 29 ) 30 31 // MPL115A2Driver is a Gobot Driver for the MPL115A2 I2C digital pressure/temperature sensor. 32 // datasheet: 33 // https://www.nxp.com/docs/en/data-sheet/MPL115A2.pdf 34 // 35 // reference implementations: 36 // * https://github.com/adafruit/Adafruit_MPL115A2 37 type MPL115A2Driver struct { 38 *Driver 39 gobot.Eventer 40 a0 float32 41 b1 float32 42 b2 float32 43 c12 float32 44 } 45 46 // NewMPL115A2Driver creates a new Gobot Driver for an MPL115A2 47 // I2C Pressure/Temperature sensor. 48 // 49 // Params: 50 // 51 // c Connector - the Adaptor to use with this Driver 52 // 53 // Optional params: 54 // 55 // i2c.WithBus(int): bus to use with this driver 56 // i2c.WithAddress(int): address to use with this driver 57 func NewMPL115A2Driver(c Connector, options ...func(Config)) *MPL115A2Driver { 58 d := &MPL115A2Driver{ 59 Driver: NewDriver(c, "MPL115A2", mpl115a2DefaultAddress), 60 Eventer: gobot.NewEventer(), 61 } 62 d.afterStart = d.initialization 63 64 for _, option := range options { 65 option(d) 66 } 67 68 // TODO: add commands to API 69 d.AddEvent(Error) 70 71 return d 72 } 73 74 // Pressure fetches the latest data from the MPL115A2, and returns the pressure in kPa 75 func (d *MPL115A2Driver) Pressure() (p float32, err error) { 76 d.mutex.Lock() 77 defer d.mutex.Unlock() 78 79 p, _, err = d.getData() 80 return 81 } 82 83 // Temperature fetches the latest data from the MPL115A2, and returns the temperature in °C 84 func (d *MPL115A2Driver) Temperature() (t float32, err error) { 85 d.mutex.Lock() 86 defer d.mutex.Unlock() 87 88 _, t, err = d.getData() 89 return 90 } 91 92 func (d *MPL115A2Driver) initialization() (err error) { 93 data := make([]byte, 8) 94 if err = d.connection.ReadBlockData(mpl115A2Reg_A0_MSB, data); err != nil { 95 return 96 } 97 98 var coA0 int16 99 var coB1 int16 100 var coB2 int16 101 var coC12 int16 102 103 buf := bytes.NewBuffer(data) 104 binary.Read(buf, binary.BigEndian, &coA0) 105 binary.Read(buf, binary.BigEndian, &coB1) 106 binary.Read(buf, binary.BigEndian, &coB2) 107 binary.Read(buf, binary.BigEndian, &coC12) 108 109 coC12 = coC12 >> 2 110 111 d.a0 = float32(coA0) / 8.0 112 d.b1 = float32(coB1) / 8192.0 113 d.b2 = float32(coB2) / 16384.0 114 d.c12 = float32(coC12) / 4194304.0 115 116 return 117 } 118 119 // getData fetches the latest data from the MPL115A2 120 func (d *MPL115A2Driver) getData() (p, t float32, err error) { 121 var temperature uint16 122 var pressure uint16 123 var pressureComp float32 124 125 if err = d.connection.WriteByteData(mpl115A2Reg_StartConversion, 0); err != nil { 126 return 127 } 128 time.Sleep(5 * time.Millisecond) 129 130 data := []byte{0, 0, 0, 0} 131 if err = d.connection.ReadBlockData(mpl115A2Reg_PressureMSB, data); err != nil { 132 return 133 } 134 135 buf := bytes.NewBuffer(data) 136 binary.Read(buf, binary.BigEndian, &pressure) 137 binary.Read(buf, binary.BigEndian, &temperature) 138 139 temperature = temperature >> 6 140 pressure = pressure >> 6 141 142 pressureComp = d.a0 + (d.b1+d.c12*float32(temperature))*float32(pressure) + d.b2*float32(temperature) 143 p = (65.0/1023.0)*pressureComp + 50.0 144 t = ((float32(temperature) - 498.0) / -5.35) + 25.0 145 146 return 147 }