mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-06 16:03:41 +00:00
8665d44e0f
ADXL345: fix: use int16 for ADXL345 readings
196 lines
5.3 KiB
Go
196 lines
5.3 KiB
Go
// Package adxl345 provides a driver for the ADXL345 digital accelerometer.
|
|
//
|
|
// Datasheet EN: http://www.analog.com/media/en/technical-documentation/data-sheets/ADXL345.pdf
|
|
//
|
|
// Datasheet JP: http://www.analog.com/media/jp/technical-documentation/data-sheets/ADXL345_jp.pdf
|
|
package adxl345 // import "tinygo.org/x/drivers/adxl345"
|
|
|
|
import (
|
|
"tinygo.org/x/drivers"
|
|
"tinygo.org/x/drivers/internal/legacy"
|
|
)
|
|
|
|
type Range uint8
|
|
type Rate uint8
|
|
|
|
// Internal structure for the power configuration
|
|
type powerCtl struct {
|
|
link uint8
|
|
autoSleep uint8
|
|
measure uint8
|
|
sleep uint8
|
|
wakeUp uint8
|
|
}
|
|
|
|
// Internal structure for the sensor's data format configuration
|
|
type dataFormat struct {
|
|
selfTest uint8
|
|
spi uint8
|
|
intInvert uint8
|
|
fullRes uint8
|
|
justify uint8
|
|
sensorRange Range
|
|
}
|
|
|
|
// Internal structure for the sampling rate configuration
|
|
type bwRate struct {
|
|
lowPower uint8
|
|
rate Rate
|
|
}
|
|
|
|
// Device wraps an I2C connection to a ADXL345 device.
|
|
type Device struct {
|
|
bus drivers.I2C
|
|
Address uint16
|
|
powerCtl powerCtl
|
|
dataFormat dataFormat
|
|
bwRate bwRate
|
|
}
|
|
|
|
// New creates a new ADXL345 connection. The I2C bus must already be
|
|
// configured.
|
|
//
|
|
// This function only creates the Device object, it does not init the device.
|
|
// To do that you must call the Configure() method on the Device before using it.
|
|
func New(bus drivers.I2C) Device {
|
|
return Device{
|
|
bus: bus,
|
|
powerCtl: powerCtl{
|
|
measure: 1,
|
|
},
|
|
dataFormat: dataFormat{
|
|
sensorRange: RANGE_2G,
|
|
},
|
|
bwRate: bwRate{
|
|
lowPower: 1,
|
|
rate: RATE_100HZ,
|
|
},
|
|
Address: AddressLow,
|
|
}
|
|
}
|
|
|
|
// Configure sets up the device for communication
|
|
func (d *Device) Configure() {
|
|
legacy.WriteRegister(d.bus, uint8(d.Address), REG_BW_RATE, []byte{d.bwRate.toByte()})
|
|
legacy.WriteRegister(d.bus, uint8(d.Address), REG_POWER_CTL, []byte{d.powerCtl.toByte()})
|
|
legacy.WriteRegister(d.bus, uint8(d.Address), REG_DATA_FORMAT, []byte{d.dataFormat.toByte()})
|
|
}
|
|
|
|
// Halt stops the sensor, values will not updated
|
|
func (d *Device) Halt() {
|
|
d.powerCtl.measure = 0
|
|
legacy.WriteRegister(d.bus, uint8(d.Address), REG_POWER_CTL, []byte{d.powerCtl.toByte()})
|
|
}
|
|
|
|
// Restart makes reading the sensor working again after a halt
|
|
func (d *Device) Restart() {
|
|
d.powerCtl.measure = 1
|
|
legacy.WriteRegister(d.bus, uint8(d.Address), REG_POWER_CTL, []byte{d.powerCtl.toByte()})
|
|
}
|
|
|
|
// ReadAcceleration reads the current acceleration from the device and returns
|
|
// it in µg (micro-gravity). When one of the axes is pointing straight to Earth
|
|
// and the sensor is not moving the returned value will be around 1000000 or
|
|
// -1000000.
|
|
func (d *Device) ReadAcceleration() (x int32, y int32, z int32, err error) {
|
|
rx, ry, rz := d.ReadRawAcceleration()
|
|
|
|
x = int32(d.dataFormat.convertToIS(rx))
|
|
y = int32(d.dataFormat.convertToIS(ry))
|
|
z = int32(d.dataFormat.convertToIS(rz))
|
|
|
|
return
|
|
}
|
|
|
|
// ReadRawAcceleration reads the sensor values and returns the raw x, y and z axis
|
|
// from the adxl345.
|
|
func (d *Device) ReadRawAcceleration() (x int16, y int16, z int16) {
|
|
data := []byte{0, 0, 0, 0, 0, 0}
|
|
legacy.ReadRegister(d.bus, uint8(d.Address), REG_DATAX0, data)
|
|
|
|
x = readIntLE(data[0], data[1])
|
|
y = readIntLE(data[2], data[3])
|
|
z = readIntLE(data[4], data[5])
|
|
|
|
return
|
|
}
|
|
|
|
// UseLowPower sets the ADXL345 to use the low power mode.
|
|
func (d *Device) UseLowPower(power bool) {
|
|
if power {
|
|
d.bwRate.lowPower = 1
|
|
} else {
|
|
d.bwRate.lowPower = 0
|
|
}
|
|
legacy.WriteRegister(d.bus, uint8(d.Address), REG_BW_RATE, []byte{d.bwRate.toByte()})
|
|
}
|
|
|
|
// SetRate change the current rate of the sensor
|
|
func (d *Device) SetRate(rate Rate) bool {
|
|
d.bwRate.rate = rate & 0x0F
|
|
legacy.WriteRegister(d.bus, uint8(d.Address), REG_BW_RATE, []byte{d.bwRate.toByte()})
|
|
return true
|
|
}
|
|
|
|
// SetRange change the current range of the sensor
|
|
func (d *Device) SetRange(sensorRange Range) bool {
|
|
d.dataFormat.sensorRange = sensorRange & 0x03
|
|
legacy.WriteRegister(d.bus, uint8(d.Address), REG_DATA_FORMAT, []byte{d.dataFormat.toByte()})
|
|
return true
|
|
}
|
|
|
|
// convertToIS adjusts the raw values from the adxl345 with the range configuration
|
|
func (d *dataFormat) convertToIS(rawValue int16) int16 {
|
|
switch d.sensorRange {
|
|
case RANGE_2G:
|
|
return rawValue * 4 // rawValue * 2 * 1000 / 512
|
|
case RANGE_4G:
|
|
return rawValue * 8 // rawValue * 4 * 1000 / 512
|
|
case RANGE_8G:
|
|
return rawValue * 16 // rawValue * 8 * 1000 / 512
|
|
case RANGE_16G:
|
|
return rawValue * 32 // rawValue * 16 * 1000 / 512
|
|
default:
|
|
return 0
|
|
}
|
|
}
|
|
|
|
// toByte returns a byte from the powerCtl configuration
|
|
func (p *powerCtl) toByte() (bits uint8) {
|
|
bits = 0x00
|
|
bits = bits | (p.link << 5)
|
|
bits = bits | (p.autoSleep << 4)
|
|
bits = bits | (p.measure << 3)
|
|
bits = bits | (p.sleep << 2)
|
|
bits = bits | p.wakeUp
|
|
|
|
return bits
|
|
}
|
|
|
|
// toByte returns a byte from the dataFormat configuration
|
|
func (d *dataFormat) toByte() (bits uint8) {
|
|
bits = 0x00
|
|
bits = bits | (d.selfTest << 7)
|
|
bits = bits | (d.spi << 6)
|
|
bits = bits | (d.intInvert << 5)
|
|
bits = bits | (d.fullRes << 3)
|
|
bits = bits | (d.justify << 2)
|
|
bits = bits | uint8(d.sensorRange)
|
|
|
|
return bits
|
|
}
|
|
|
|
// toByte returns a byte from the bwRate configuration
|
|
func (b *bwRate) toByte() (bits uint8) {
|
|
bits = 0x00
|
|
bits = bits | (b.lowPower << 4)
|
|
bits = bits | uint8(b.rate)
|
|
|
|
return bits
|
|
}
|
|
|
|
// readInt converts two bytes to int16
|
|
func readIntLE(msb byte, lsb byte) int16 {
|
|
return int16(uint16(msb) | uint16(lsb)<<8)
|
|
}
|