Skip to content
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

Closed
wants to merge 7 commits into from
Closed

Mpu6050 rewrite #556

wants to merge 7 commits into from

Conversation

soypat
Copy link
Contributor

@soypat soypat commented Apr 29, 2023

Resolves #544.

I have published the mpu6050 driver I've used independently for years now.

It has greatly increased functionality and is much faster and efficient than the existing implementation. I have broken API compatibility since the existing implementation was extremely limited. In doing so I've taken the liberty of implementing patterns from the RFC #310.

New Features:

  • Configurable acceleration range
  • Configurable angular velocity range
  • Extensible configuration type added for future non-breaking changes
  • Efficient sensor reading using one-shot methodology
  • Expose raw data for even more efficient algorithms for power users.

@soypat soypat changed the base branch from release to dev April 29, 2023 15:42
@soypat soypat requested a review from deadprogram April 29, 2023 15:43
@soypat soypat mentioned this pull request Apr 29, 2023
time.Sleep(time.Millisecond * 100)
err := mpuDevice.Update()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe Update should have a parameter with the sensor values it should update?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we should probably solve #345 before merging

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#345 has been merged, so this can be updated.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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

mpu6050/mpu6050.go Outdated Show resolved Hide resolved
mpu6050/mpu6050.go Outdated Show resolved Hide resolved
mpu6050/mpu6050.go Outdated Show resolved Hide resolved
mpu6050/mpu6050.go Outdated Show resolved Hide resolved
mpu6050/mpu6050.go Outdated Show resolved Hide resolved
mpu6050/mpu6050.go Outdated Show resolved Hide resolved
Comment on lines 244 to 250
func DefaultConfig() IMUConfig {
return IMUConfig{
AccRange: ACCEL_RANGE_16,
GyroRange: GYRO_RANGE_2000,
sampleRatio: 0, // TODO add const values.
clkSel: 0,
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to use the zero value for these options as the default value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand- I've added them here redundantly just so I can mark it with a TODO

mpu6050/registers.go Outdated Show resolved Hide resolved
mpu6050/registers.go Outdated Show resolved Hide resolved
@@ -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)
Copy link
Member

@deadprogram deadprogram May 20, 2023

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 Address and then just setting it before calling Configure. 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 😺

mpuDevice := mpu6050.New(machine.I2C0)
mpuDevice.Address = 0x66 // overrides default

// now do everything else

Copy link
Member

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 a go get -u tinygo.org/x/drivers, you might as well add the default address).

I'm fine either way.

@@ -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)
Copy link
Member

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 a go get -u tinygo.org/x/drivers, you might as well add the default address).

I'm fine either way.

Comment on lines 16 to 19
err := mpuDevice.Configure(mpu6050.Config{
AccRange: mpu6050.ACCEL_RANGE_16,
GyroRange: mpu6050.GYRO_RANGE_2000,
})
Copy link
Member

Choose a reason for hiding this comment

The 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.

time.Sleep(time.Millisecond * 100)
err := mpuDevice.Update()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#345 has been merged, so this can be updated.

examples/mpu6050/main.go Outdated Show resolved Hide resolved
mpu6050/mpu6050.go Outdated Show resolved Hide resolved
Comment on lines 117 to 125
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
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a new API.
Why not use time.Duration as an input? Or a sample rate in Hz, as an uint32? (Similar to machine.CPUFrequency() for example). The parameter that you're using here looks like a mpu6050-specific value.

Comment on lines 127 to 141
// 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
}
Copy link
Member

Choose a reason for hiding this comment

The 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?)

Comment on lines 143 to 172
// 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
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make gyroRange a type? Like is done in the LIS3DH driver:

func (d *Device) SetRange(r Range) {

type Range uint8
const (
RANGE_16_G Range = 3 // +/- 16g
RANGE_8_G = 2 // +/- 8g
RANGE_4_G = 1 // +/- 4g
RANGE_2_G = 0 // +/- 2g (default value)
)

This makes it possible to easily change the type at a later time, if needed.

// 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) {
Copy link
Member

Choose a reason for hiding this comment

The 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.

Comment on lines 225 to 232
func DefaultConfig() Config {
return Config{
AccRange: ACCEL_RANGE_16,
GyroRange: GYRO_RANGE_2000,
sampleRatio: 0, // TODO add const values.
clkSel: 0,
}
}
Copy link
Member

Choose a reason for hiding this comment

The 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?
That way, users can just do Configure(mpu6050.Config{GyroRange: ...}) and know that the acceleration range is also set to some reasonable default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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!

@soypat
Copy link
Contributor Author

soypat commented May 27, 2023

Closing this PR in favor of #577

@soypat soypat closed this May 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MPU6050 ReadRotation not working
4 participants