-
-
Notifications
You must be signed in to change notification settings - Fork 238
Mpu6050 rewrite #556
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mpu6050 rewrite #556
Changes from 5 commits
8c80439
44b049c
ae9ac8a
a2124d3
c4c9bdb
d675bd4
6288ba5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,12 +11,27 @@ import ( | |
| func main() { | ||
| machine.I2C0.Configure(machine.I2CConfig{}) | ||
|
|
||
| accel := mpu6050.New(machine.I2C0) | ||
| accel.Configure() | ||
| mpuDevice := mpu6050.New(machine.I2C0, mpu6050.DefaultAddress) | ||
|
|
||
| err := mpuDevice.Configure(mpu6050.Config{ | ||
| AccRange: mpu6050.ACCEL_RANGE_16, | ||
| GyroRange: mpu6050.GYRO_RANGE_2000, | ||
| }) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ...and here we have another breaking change, that I think is actually really useful. |
||
| if err != nil { | ||
| panic(err.Error()) | ||
| } | ||
| for { | ||
| x, y, z := accel.ReadAcceleration() | ||
| println(x, y, z) | ||
| time.Sleep(time.Millisecond * 100) | ||
| err := mpuDevice.Update() | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, we should probably solve #345 before merging
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #345 has been merged, so this can be updated.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd leave this for last since I still don't have a good rebase methodology. As soon as everything else is reviewed and OK I'll try my hand at rebasing one more time |
||
| if err != nil { | ||
| println("error reading from mpu6050:", err.Error()) | ||
| continue | ||
| } | ||
| print("acceleration: ") | ||
| println(mpuDevice.Acceleration()) | ||
| print("angular velocity:") | ||
| println(mpuDevice.AngularVelocity()) | ||
| print("temperature centigrade:") | ||
| println(mpuDevice.Temperature() / 1000) | ||
|
soypat marked this conversation as resolved.
Outdated
|
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,95 +1,232 @@ | ||||||||||||||||||||
| // Package mpu6050 provides a driver for the MPU6050 accelerometer and gyroscope | ||||||||||||||||||||
| // made by InvenSense. | ||||||||||||||||||||
| // | ||||||||||||||||||||
| // Datasheets: | ||||||||||||||||||||
| // https://store.invensense.com/datasheets/invensense/MPU-6050_DataSheet_V3%204.pdf | ||||||||||||||||||||
| // https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf | ||||||||||||||||||||
| package mpu6050 // import "tinygo.org/x/drivers/mpu6050" | ||||||||||||||||||||
|
soypat marked this conversation as resolved.
|
||||||||||||||||||||
| package mpu6050 | ||||||||||||||||||||
|
|
||||||||||||||||||||
| import ( | ||||||||||||||||||||
| "encoding/binary" | ||||||||||||||||||||
| "errors" | ||||||||||||||||||||
|
|
||||||||||||||||||||
| "tinygo.org/x/drivers" | ||||||||||||||||||||
| ) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| import "tinygo.org/x/drivers" | ||||||||||||||||||||
| const DefaultAddress = 0x68 | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Device wraps an I2C connection to a MPU6050 device. | ||||||||||||||||||||
| type Config struct { | ||||||||||||||||||||
| // Use ACCEL_RANGE_2 through ACCEL_RANGE_16. | ||||||||||||||||||||
| AccRange byte | ||||||||||||||||||||
|
soypat marked this conversation as resolved.
Outdated
|
||||||||||||||||||||
| // Use GYRO_RANGE_250 through GYRO_RANGE_2000 | ||||||||||||||||||||
| GyroRange byte | ||||||||||||||||||||
| sampleRatio byte // TODO(soypat): expose these as configurable. | ||||||||||||||||||||
| clkSel byte | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Device contains MPU board abstraction for usage | ||||||||||||||||||||
| type Device struct { | ||||||||||||||||||||
| bus drivers.I2C | ||||||||||||||||||||
| Address uint16 | ||||||||||||||||||||
| conn drivers.I2C | ||||||||||||||||||||
| aRange int32 //Gyroscope FSR acording to SetAccelRange input | ||||||||||||||||||||
| gRange int32 //Gyroscope FSR acording to SetGyroRange input | ||||||||||||||||||||
|
Comment on lines
+43
to
+44
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FSR? |
||||||||||||||||||||
| // RawData contains the accelerometer, gyroscope and temperature RawData read | ||||||||||||||||||||
| // in the last call via the Update method. | ||||||||||||||||||||
| RawData [14]byte | ||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still don't agree with exposing these. They are implementation details of the driver. Exposing these would make the mpu6050 a leaky abstraction. |
||||||||||||||||||||
| address byte | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // New creates a new MPU6050 connection. The I2C bus must already be | ||||||||||||||||||||
| // configured. | ||||||||||||||||||||
| // | ||||||||||||||||||||
| // This function only creates the Device object, it does not touch the device. | ||||||||||||||||||||
| func New(bus drivers.I2C) Device { | ||||||||||||||||||||
| return Device{bus, Address} | ||||||||||||||||||||
| // New instantiates and initializes a MPU6050 struct without writing/reading | ||||||||||||||||||||
| // i2c bus. Typical I2C MPU6050 address is 0x68. | ||||||||||||||||||||
| func New(bus drivers.I2C, addr uint16) *Device { | ||||||||||||||||||||
| p := &Device{} | ||||||||||||||||||||
| p.address = uint8(addr) | ||||||||||||||||||||
| p.conn = bus | ||||||||||||||||||||
| return p | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Connected returns whether a MPU6050 has been found. | ||||||||||||||||||||
| // It does a "who am I" request and checks the response. | ||||||||||||||||||||
| func (d Device) Connected() bool { | ||||||||||||||||||||
| data := []byte{0} | ||||||||||||||||||||
| d.bus.ReadRegister(uint8(d.Address), WHO_AM_I, data) | ||||||||||||||||||||
| return data[0] == 0x68 | ||||||||||||||||||||
|
Comment on lines
-27
to
-30
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why did you remove this method? |
||||||||||||||||||||
| // Init configures the necessary registers for using the | ||||||||||||||||||||
| // MPU6050. It sets the range of both the accelerometer | ||||||||||||||||||||
| // and the gyroscope, the sample rate, the clock source | ||||||||||||||||||||
| // and wakes up the peripheral. | ||||||||||||||||||||
| func (p *Device) Configure(data Config) (err error) { | ||||||||||||||||||||
| if err = p.Sleep(false); err != nil { | ||||||||||||||||||||
| return errors.New("set sleep: " + err.Error()) | ||||||||||||||||||||
| } | ||||||||||||||||||||
| if err = p.SetClockSource(data.clkSel); err != nil { | ||||||||||||||||||||
| return errors.New("set clksrc: " + err.Error()) | ||||||||||||||||||||
| } | ||||||||||||||||||||
| if err = p.SetSampleRate(data.sampleRatio); err != nil { | ||||||||||||||||||||
| return errors.New("set sampleratio: " + err.Error()) | ||||||||||||||||||||
| } | ||||||||||||||||||||
| if err = p.SetRangeGyro(data.GyroRange); err != nil { | ||||||||||||||||||||
| return errors.New("set gyrorange: " + err.Error()) | ||||||||||||||||||||
| } | ||||||||||||||||||||
| if err = p.SetRangeAccel(data.AccRange); err != nil { | ||||||||||||||||||||
| return errors.New("set accelrange: " + err.Error()) | ||||||||||||||||||||
| } | ||||||||||||||||||||
| return nil | ||||||||||||||||||||
|
Comment on lines
+46
to
+83
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Configure sets up the device for communication. | ||||||||||||||||||||
| func (d Device) Configure() error { | ||||||||||||||||||||
| return d.SetClockSource(CLOCK_INTERNAL) | ||||||||||||||||||||
| // Update fetches the latest data from the MPU6050 | ||||||||||||||||||||
| func (p *Device) Update() (err error) { | ||||||||||||||||||||
| if err = p.read(_ACCEL_XOUT_H, p.RawData[:]); err != nil { | ||||||||||||||||||||
| return err | ||||||||||||||||||||
| } | ||||||||||||||||||||
| return nil | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // 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 | ||||||||||||||||||||
| // Acceleration returns last read acceleration 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) { | ||||||||||||||||||||
| data := make([]byte, 6) | ||||||||||||||||||||
| d.bus.ReadRegister(uint8(d.Address), ACCEL_XOUT_H, data) | ||||||||||||||||||||
| // Now do two things: | ||||||||||||||||||||
| // 1. merge the two values to a 16-bit number (and cast to a 32-bit integer) | ||||||||||||||||||||
| // 2. scale the value to bring it in the -1000000..1000000 range. | ||||||||||||||||||||
| // This is done with a trick. What we do here is essentially multiply by | ||||||||||||||||||||
| // 1000000 and divide by 16384 to get the original scale, but to avoid | ||||||||||||||||||||
| // overflow we do it at 1/64 of the value: | ||||||||||||||||||||
| // 1000000 / 64 = 15625 | ||||||||||||||||||||
| // 16384 / 64 = 256 | ||||||||||||||||||||
| x = int32(int16((uint16(data[0])<<8)|uint16(data[1]))) * 15625 / 256 | ||||||||||||||||||||
| y = int32(int16((uint16(data[2])<<8)|uint16(data[3]))) * 15625 / 256 | ||||||||||||||||||||
| z = int32(int16((uint16(data[4])<<8)|uint16(data[5]))) * 15625 / 256 | ||||||||||||||||||||
| return | ||||||||||||||||||||
| func (d *Device) Acceleration() (ax, ay, az int32) { | ||||||||||||||||||||
| const accelOffset = 0 | ||||||||||||||||||||
| ax = int32(convertWord(d.RawData[accelOffset+0:])) * 15625 / 512 * d.aRange | ||||||||||||||||||||
| ay = int32(convertWord(d.RawData[accelOffset+2:])) * 15625 / 512 * d.aRange | ||||||||||||||||||||
| az = int32(convertWord(d.RawData[accelOffset+4:])) * 15625 / 512 * d.aRange | ||||||||||||||||||||
| return ax, ay, az | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // ReadRotation reads the current rotation from the device and returns it in | ||||||||||||||||||||
| // µ°/s (micro-degrees/sec). This means that if you were to do a complete | ||||||||||||||||||||
| // Rotations reads the current rotation from the device and returns it in | ||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||||||||||
| // µ°/rad (micro-radians/sec). This means that if you were to do a complete | ||||||||||||||||||||
| // rotation along one axis and while doing so integrate all values over time, | ||||||||||||||||||||
| // you would get a value close to 360000000. | ||||||||||||||||||||
| func (d Device) ReadRotation() (x int32, y int32, z int32) { | ||||||||||||||||||||
| data := make([]byte, 6) | ||||||||||||||||||||
| d.bus.ReadRegister(uint8(d.Address), GYRO_XOUT_H, data) | ||||||||||||||||||||
| // First the value is converted from a pair of bytes to a signed 16-bit | ||||||||||||||||||||
| // value and then to a signed 32-bit value to avoid integer overflow. | ||||||||||||||||||||
| // Then the value is scaled to µ°/s (micro-degrees per second). | ||||||||||||||||||||
| // This is done in the following steps: | ||||||||||||||||||||
| // 1. Multiply by 250 * 1000_000 | ||||||||||||||||||||
| // 2. Divide by 32768 | ||||||||||||||||||||
| // The following calculation (x * 15625 / 2048 * 1000) is essentially the | ||||||||||||||||||||
| // same but avoids overflow. First both operations are divided by 16 leading | ||||||||||||||||||||
| // to multiply by 15625000 and divide by 2048, and then part of the multiply | ||||||||||||||||||||
| // is done after the divide instead of before. | ||||||||||||||||||||
| x = int32(int16((uint16(data[0])<<8)|uint16(data[1]))) * 15625 / 2048 * 1000 | ||||||||||||||||||||
| y = int32(int16((uint16(data[2])<<8)|uint16(data[3]))) * 15625 / 2048 * 1000 | ||||||||||||||||||||
| z = int32(int16((uint16(data[4])<<8)|uint16(data[5]))) * 15625 / 2048 * 1000 | ||||||||||||||||||||
| return | ||||||||||||||||||||
| // you would get a value close to 6.3 radians (360 degrees). | ||||||||||||||||||||
| func (d *Device) AngularVelocity() (gx, gy, gz int32) { | ||||||||||||||||||||
| const angvelOffset = 8 | ||||||||||||||||||||
| _ = d.RawData[angvelOffset+5] // This line fails to compile if RawData is too short. | ||||||||||||||||||||
| gx = int32(convertWord(d.RawData[angvelOffset+0:])) * 4363 / 8192 * d.gRange | ||||||||||||||||||||
| gy = int32(convertWord(d.RawData[angvelOffset+2:])) * 4363 / 8192 * d.gRange | ||||||||||||||||||||
| gz = int32(convertWord(d.RawData[angvelOffset+4:])) * 4363 / 8192 * d.gRange | ||||||||||||||||||||
| return gx, gy, gz | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // SetClockSource allows the user to configure the clock source. | ||||||||||||||||||||
| func (d Device) SetClockSource(source uint8) error { | ||||||||||||||||||||
| return d.bus.WriteRegister(uint8(d.Address), PWR_MGMT_1, []uint8{source}) | ||||||||||||||||||||
| // Temperature returns the temperature of the device in milli-centigrade. | ||||||||||||||||||||
| func (d *Device) Temperature() (Celsius int32) { | ||||||||||||||||||||
| const tempOffset = 6 | ||||||||||||||||||||
| return 1506*int32(convertWord(d.RawData[tempOffset:]))/512 + 37*1000 | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| func convertWord(buf []byte) int16 { | ||||||||||||||||||||
| return int16(binary.BigEndian.Uint16(buf)) | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // SetSampleRate sets the sample rate for the FIFO, | ||||||||||||||||||||
| // register ouput and DMP. The sample rate is determined | ||||||||||||||||||||
| // by: | ||||||||||||||||||||
| // | ||||||||||||||||||||
| // SR = Gyroscope Output Rate / (1 + srDiv) | ||||||||||||||||||||
| // | ||||||||||||||||||||
| // The Gyroscope Output Rate is 8kHz when the DLPF is | ||||||||||||||||||||
| // disabled and 1kHz otherwise. The maximum sample rate | ||||||||||||||||||||
| // for the accelerometer is 1kHz, if a higher sample rate | ||||||||||||||||||||
| // is chosen, the same accelerometer sample will be output. | ||||||||||||||||||||
| func (p *Device) SetSampleRate(srDiv byte) (err error) { | ||||||||||||||||||||
| // setSampleRate | ||||||||||||||||||||
| var sr [1]byte | ||||||||||||||||||||
| sr[0] = srDiv | ||||||||||||||||||||
| if err = p.write8(_SMPRT_DIV, sr[0]); err != nil { | ||||||||||||||||||||
| return err | ||||||||||||||||||||
| } | ||||||||||||||||||||
| return nil | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a new API. |
||||||||||||||||||||
|
|
||||||||||||||||||||
| // SetClockSource configures the source of the clock | ||||||||||||||||||||
| // for the peripheral. | ||||||||||||||||||||
| func (p *Device) SetClockSource(clkSel byte) (err error) { | ||||||||||||||||||||
| // setClockSource | ||||||||||||||||||||
| var pwrMgt [1]byte | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if err = p.read(_PWR_MGMT_1, pwrMgt[:]); err != nil { | ||||||||||||||||||||
| return err | ||||||||||||||||||||
| } | ||||||||||||||||||||
| pwrMgt[0] = (pwrMgt[0] & (^_CLK_SEL_MASK)) | clkSel // Escribo solo el campo de clk_sel | ||||||||||||||||||||
| if err = p.write8(_PWR_MGMT_1, pwrMgt[0]); err != nil { | ||||||||||||||||||||
| return err | ||||||||||||||||||||
| } | ||||||||||||||||||||
| return nil | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this actually useful? Can you give me an example where this would be used in practice? If not, I suggest removing it to declutter the API. (Also, it contains a Spanish comment?) |
||||||||||||||||||||
|
|
||||||||||||||||||||
| // SetRangeGyro configures the full scale range of the gyroscope. | ||||||||||||||||||||
| // It has four possible values +- 250°/s, 500°/s, 1000°/s, 2000°/s. | ||||||||||||||||||||
| // The function takes values of gyroRange from 0-3 where 0 means the | ||||||||||||||||||||
| // lowest FSR (250°/s) and 3 is the highest FSR (2000°/s). | ||||||||||||||||||||
| func (p *Device) SetRangeGyro(gyroRange byte) (err error) { | ||||||||||||||||||||
| switch gyroRange { | ||||||||||||||||||||
| case GYRO_RANGE_250: | ||||||||||||||||||||
| p.gRange = 250 | ||||||||||||||||||||
| case GYRO_RANGE_500: | ||||||||||||||||||||
| p.gRange = 500 | ||||||||||||||||||||
| case GYRO_RANGE_1000: | ||||||||||||||||||||
| p.gRange = 1000 | ||||||||||||||||||||
| case GYRO_RANGE_2000: | ||||||||||||||||||||
| p.gRange = 2000 | ||||||||||||||||||||
| default: | ||||||||||||||||||||
| return errors.New("invalid gyroscope FSR input") | ||||||||||||||||||||
| } | ||||||||||||||||||||
| // setFullScaleGyroRange | ||||||||||||||||||||
| var gConfig [1]byte | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if err = p.read(_GYRO_CONFIG, gConfig[:]); err != nil { | ||||||||||||||||||||
| return err | ||||||||||||||||||||
| } | ||||||||||||||||||||
| gConfig[0] = (gConfig[0] & (^_G_FS_SEL)) | (gyroRange << _G_FS_SHIFT) // Escribo solo el campo de FS_sel | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if err = p.write8(_GYRO_CONFIG, gConfig[0]); err != nil { | ||||||||||||||||||||
| return err | ||||||||||||||||||||
| } | ||||||||||||||||||||
| return nil | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you make Line 62 in 820298b
Lines 54 to 61 in 820298b
This makes it possible to easily change the type at a later time, if needed. |
||||||||||||||||||||
|
|
||||||||||||||||||||
| // SetRangeAccel configures the full scale range of the accelerometer. | ||||||||||||||||||||
| // It has four possible values +- 2g, 4g, 8g, 16g. | ||||||||||||||||||||
| // The function takes values of accRange from 0-3 where 0 means the | ||||||||||||||||||||
| // lowest FSR (2g) and 3 is the highest FSR (16g) | ||||||||||||||||||||
| func (p *Device) SetRangeAccel(accRange byte) (err error) { | ||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. Please don't use magic constants (0, 1, 2, 3) and instead instruct users to use named constants. |
||||||||||||||||||||
| switch accRange { | ||||||||||||||||||||
| case ACCEL_RANGE_2: | ||||||||||||||||||||
| p.aRange = 2 | ||||||||||||||||||||
| case ACCEL_RANGE_4: | ||||||||||||||||||||
| p.aRange = 4 | ||||||||||||||||||||
| case ACCEL_RANGE_8: | ||||||||||||||||||||
| p.aRange = 8 | ||||||||||||||||||||
| case ACCEL_RANGE_16: | ||||||||||||||||||||
| p.aRange = 16 | ||||||||||||||||||||
| default: | ||||||||||||||||||||
| return errors.New("invalid accelerometer FSR input") | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| var aConfig [1]byte | ||||||||||||||||||||
| if err = p.read(_ACCEL_CONFIG, aConfig[:]); err != nil { | ||||||||||||||||||||
| return err | ||||||||||||||||||||
| } | ||||||||||||||||||||
| aConfig[0] = (aConfig[0] & (^_AFS_SEL)) | (accRange << _AFS_SHIFT) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if err = p.write8(_ACCEL_CONFIG, aConfig[0]); err != nil { | ||||||||||||||||||||
| return err | ||||||||||||||||||||
| } | ||||||||||||||||||||
| return nil | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // SetFullScaleGyroRange allows the user to configure the scale range for the gyroscope. | ||||||||||||||||||||
| func (d Device) SetFullScaleGyroRange(rng uint8) error { | ||||||||||||||||||||
| return d.bus.WriteRegister(uint8(d.Address), GYRO_CONFIG, []uint8{rng}) | ||||||||||||||||||||
| // Sleep sets the sleep bit on the power managment 1 field. | ||||||||||||||||||||
| // When the recieved bool is true, it sets the bit to 1 thus putting | ||||||||||||||||||||
| // the peripheral in sleep mode. | ||||||||||||||||||||
| // When false is recieved the bit is set to 0 and the peripheral wakes up. | ||||||||||||||||||||
| func (p *Device) Sleep(sleepEnabled bool) (err error) { | ||||||||||||||||||||
| // setSleepBit | ||||||||||||||||||||
| var pwrMgt [1]byte | ||||||||||||||||||||
| if err = p.read(_PWR_MGMT_1, pwrMgt[:]); err != nil { | ||||||||||||||||||||
| return err | ||||||||||||||||||||
| } | ||||||||||||||||||||
| if sleepEnabled { | ||||||||||||||||||||
| pwrMgt[0] = (pwrMgt[0] & (^_SLEEP_MASK)) | (1 << _SLEEP_SHIFT) // Overwrite only Sleep | ||||||||||||||||||||
| } else { | ||||||||||||||||||||
| pwrMgt[0] = (pwrMgt[0] & (^_SLEEP_MASK)) | ||||||||||||||||||||
| } | ||||||||||||||||||||
| if err = p.write8(_PWR_MGMT_1, pwrMgt[0]); err != nil { | ||||||||||||||||||||
| return err | ||||||||||||||||||||
| } | ||||||||||||||||||||
| return nil | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // SetFullScaleAccelRange allows the user to configure the scale range for the accelerometer. | ||||||||||||||||||||
| func (d Device) SetFullScaleAccelRange(rng uint8) error { | ||||||||||||||||||||
| return d.bus.WriteRegister(uint8(d.Address), ACCEL_CONFIG, []uint8{rng}) | ||||||||||||||||||||
| func DefaultConfig() Config { | ||||||||||||||||||||
| return Config{ | ||||||||||||||||||||
| AccRange: ACCEL_RANGE_16, | ||||||||||||||||||||
| GyroRange: GYRO_RANGE_2000, | ||||||||||||||||||||
| sampleRatio: 0, // TODO add const values. | ||||||||||||||||||||
| clkSel: 0, | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of DefaultConfig, have you considered making the zero value the default config?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have pushed changes that make the zero value useful in latest commit! |
||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other drivers, this has been solved by exporting
Addressand then just setting it before callingConfigure. That way we do not have to break the existing API and all of the many projects that use this driver. I have several such projects myself 😺There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With Go modules, I'm not too worried about breakage. Yes, it will break once you do a
go get -u tinygo.org/x/drivers, but before that it will keep working just fine (and if you're doing ago get -u tinygo.org/x/drivers, you might as well add the default address).I'm fine either way.