Skip to content

Commit 82e9e4a

Browse files
authored
Add support for LPS22HB MEMS nano pressure sensor (#297)
lps22hb: add support for lps22hb
1 parent 76ff632 commit 82e9e4a

File tree

6 files changed

+171
-1
lines changed

6 files changed

+171
-1
lines changed

Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ smoke-test:
8181
@md5sum ./build/test.hex
8282
tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis3dh/main.go
8383
@md5sum ./build/test.hex
84+
tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/lps22hb/main.go
85+
@md5sum ./build/test.hex
8486
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/lsm303agr/main.go
8587
@md5sum ./build/test.hex
8688
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/lsm6ds3/main.go
@@ -214,7 +216,7 @@ DRIVERS = $(wildcard */)
214216
NOTESTS = build examples flash semihosting pcd8544 shiftregister st7789 microphone mcp3008 gps microbitmatrix \
215217
hcsr04 ssd1331 ws2812 thermistor apa102 easystepper ssd1351 ili9341 wifinina shifter hub75 \
216218
hd44780 buzzer ssd1306 espat l9110x st7735 bmi160 l293x dht keypad4x4 max72xx p1am tone tm1637 \
217-
pcf8563 mcp2515 servo sdcard rtl8720dn image cmd i2csoft hts221
219+
pcf8563 mcp2515 servo sdcard rtl8720dn image cmd i2csoft hts221 lps22hb
218220
TESTS = $(filter-out $(addsuffix /%,$(NOTESTS)),$(DRIVERS))
219221

220222
unit-test:

examples/lps22hb/main.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package main
2+
3+
import (
4+
"machine"
5+
"time"
6+
7+
"tinygo.org/x/drivers/lps22hb"
8+
)
9+
10+
func main() {
11+
12+
machine.I2C1.Configure(machine.I2CConfig{
13+
SCL: machine.P0_15, // SCL1 on Nano 33 BLE Sense
14+
SDA: machine.P0_14, // SDA1 on Nano 33 BLE Sense
15+
Frequency: machine.TWI_FREQ_400KHZ,
16+
})
17+
18+
sensor := lps22hb.New(machine.I2C1)
19+
20+
if !sensor.Connected() {
21+
println("LPS22HB not connected!")
22+
return
23+
}
24+
25+
sensor.Configure()
26+
27+
for {
28+
29+
p, _ := sensor.ReadPressure()
30+
t, _ := sensor.ReadTemperature()
31+
println("p =", float32(p)/1000.0, "hPa / t =", float32(t)/1000.0, "*C")
32+
time.Sleep(time.Second)
33+
// note: the device would power down itself after each query
34+
35+
}
36+
37+
}

lps22hb/lps22hb.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Package lps22hb implements a driver for LPS22HB, a MEMS nano pressure sensor.
2+
//
3+
// Datasheet: https://www.st.com/resource/en/datasheet/dm00140895.pdf
4+
//
5+
package lps22hb
6+
7+
import (
8+
"tinygo.org/x/drivers"
9+
)
10+
11+
// Device wraps an I2C connection to a HTS221 device.
12+
type Device struct {
13+
bus drivers.I2C
14+
Address uint8
15+
}
16+
17+
// Connected returns whether LPS22HB has been found.
18+
// It does a "who am I" request and checks the response.
19+
func (d *Device) Connected() bool {
20+
data := []byte{0}
21+
d.bus.ReadRegister(d.Address, LPS22HB_WHO_AM_I_REG, data)
22+
return data[0] == 0xB1
23+
}
24+
25+
// Configure sets up the LPS22HB device for communication.
26+
func (d *Device) Configure() {
27+
// set to block update mode
28+
d.bus.WriteRegister(d.Address, LPS22HB_CTRL1_REG, []byte{0x02})
29+
}
30+
31+
// ReadPressure returns the pressure in milli pascals (mPa).
32+
func (d *Device) ReadPressure() (pressure int32, err error) {
33+
d.waitForOneShot()
34+
35+
// read data
36+
data := []byte{0, 0, 0}
37+
d.bus.ReadRegister(d.Address, LPS22HB_PRESS_OUT_REG, data[:1])
38+
d.bus.ReadRegister(d.Address, LPS22HB_PRESS_OUT_REG+1, data[1:2])
39+
d.bus.ReadRegister(d.Address, LPS22HB_PRESS_OUT_REG+2, data[2:])
40+
pValue := float32(uint32(data[2])<<16|uint32(data[1])<<8|uint32(data[0])) / 4096.0
41+
42+
return int32(pValue * 1000), nil
43+
}
44+
45+
// ReadTemperature returns the temperature in celsius milli degrees (°C/1000).
46+
func (d *Device) ReadTemperature() (temperature int32, err error) {
47+
d.waitForOneShot()
48+
49+
// read data
50+
data := []byte{0, 0}
51+
d.bus.ReadRegister(d.Address, LPS22HB_TEMP_OUT_REG, data[:1])
52+
d.bus.ReadRegister(d.Address, LPS22HB_TEMP_OUT_REG+1, data[1:])
53+
tValue := float32(int16(uint16(data[1])<<8|uint16(data[0]))) / 100.0
54+
55+
return int32(tValue * 1000), nil
56+
}
57+
58+
// private functions
59+
60+
// wait and trigger one shot in block update
61+
func (d *Device) waitForOneShot() {
62+
// trigger one shot
63+
d.bus.WriteRegister(d.Address, LPS22HB_CTRL2_REG, []byte{0x01})
64+
65+
// wait until one shot is cleared
66+
data := []byte{1}
67+
for {
68+
d.bus.ReadRegister(d.Address, LPS22HB_CTRL2_REG, data)
69+
if data[0]&0x01 == 0 {
70+
break
71+
}
72+
}
73+
}

lps22hb/lps22hb_generic.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//go:build !nano_33_ble
2+
// +build !nano_33_ble
3+
4+
package lps22hb
5+
6+
import "tinygo.org/x/drivers"
7+
8+
// New creates a new LPS22HB connection. The I2C bus must already be
9+
// configured.
10+
//
11+
// This function only creates the Device object, it does not touch the device.
12+
func New(bus drivers.I2C) Device {
13+
return Device{bus: bus, Address: LPS22HB_ADDRESS}
14+
}

lps22hb/lps22hb_nano_33_ble.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//go:build nano_33_ble
2+
// +build nano_33_ble
3+
4+
package lps22hb
5+
6+
import (
7+
"machine"
8+
"time"
9+
10+
"tinygo.org/x/drivers"
11+
)
12+
13+
// New creates a new LPS22HB connection. The I2C bus must already be
14+
// configured.
15+
//
16+
// This function only creates the Device object, it does not touch the device.
17+
func New(bus drivers.I2C) Device {
18+
// turn on internal power pin (machine.P0_22) and I2C1 pullups power pin (machine.P1_00)
19+
// and wait a moment.
20+
ENV := machine.P0_22
21+
ENV.Configure(machine.PinConfig{Mode: machine.PinOutput})
22+
ENV.High()
23+
R := machine.P1_00
24+
R.Configure(machine.PinConfig{Mode: machine.PinOutput})
25+
R.High()
26+
time.Sleep(time.Millisecond * 10)
27+
28+
return Device{bus: bus, Address: LPS22HB_ADDRESS}
29+
}

lps22hb/registers.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package lps22hb
2+
3+
const (
4+
5+
// I2C address
6+
LPS22HB_ADDRESS = 0x5C
7+
8+
// control/status registers
9+
LPS22HB_WHO_AM_I_REG = 0x0F
10+
LPS22HB_CTRL1_REG = 0x10
11+
LPS22HB_CTRL2_REG = 0x11
12+
LPS22HB_STATUS_REG = 0x27
13+
LPS22HB_PRESS_OUT_REG = 0x28
14+
LPS22HB_TEMP_OUT_REG = 0x2B
15+
)

0 commit comments

Comments
 (0)