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

[WIP] QMC5883 Magnetometer Driver #11140

Merged
merged 27 commits into from
Mar 9, 2019
Merged

[WIP] QMC5883 Magnetometer Driver #11140

merged 27 commits into from
Mar 9, 2019

Conversation

dlwalter
Copy link
Contributor

@dlwalter dlwalter commented Jan 3, 2019

Please use PX4 Discuss or Slack to align on pull requests if necessary.

Test data / coverage
sensors status
listener sensor_mag -i 0
tests sensors

Magnetometer plots - QMC5883 External mag is sensor_mag_1
X axis plot comparison
Y axis plot comparison
Z axis plot comparison

Describe problem solved by the proposed pull request
A driver for the QMC5883 is required as many manufacturers have moved away from the now obsolete HMC5883.

Describe your preferred solution
The QMC5883 driver is implemented with basic functionality. Currently runs at a fixed range (+/- 2Gauss), oversampling (512) and bitrate (200hz). The next steps are to implement functionality to change these configuration options and implement a self-test. Doesn't work with current stable branch dues to the use of MAGIOSELFTEST, will result in preflight check errors.

Describe possible alternatives
Write another driver

Additional context

@@ -43,6 +43,7 @@ fi

# External I2C bus
hmc5883 -C -T -X start
qmc5883 -C -T -X start
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This command fails to start the driver. Still have to manually start at the command line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed this issue in the probe() command for i2c. Have to read 0x00 once first before you can read the ID registers reliably.

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 also added a while loop to check a number of retries.

return ret;
}

int QMC5883::calibrate(struct file *filp, unsigned enable)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Need to confirm that QMC5883::calibrate does anything

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Calibrate is removed. The QMC5883 does not have a self-test mode with an induced field to calibrate against.


if (range_bits_in != _range_bits << 4) {
perf_count(_range_errors);
ret = write_reg(QMC5883_ADDR_CONTROL_1, (_range_bits << 4));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@dagar I think this is why it was going STALE. The first 2 bits of the control address (0x09) are the data rate which are getting written over here and putting it back into standby mode.

// apply user specified rotation
rotate_3f(_rotation, xraw_f, yraw_f, zraw_f);

new_report.x = ((xraw_f * _range_scale) - _scale.x_offset) * _scale.x_scale;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

_range_scale always seems to just equal 0, (when I try printf or PX4_INFO). Getting ok values on the console though, but typing "listener sensor_mag -I 1" always shows scale = 0.0001

check that the configuration register has the right value. This is
done periodically to cope with I2C bus noise causing the
configuration of the compass to change.
*/
Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed get and check range and just hardcoded the +/-2G range

@@ -43,6 +43,7 @@ fi

# External I2C bus
hmc5883 -C -T -X start
qmc5883 -X start
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the calibration option on this command.

* change
*/
void check_conf(void);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the calibration function - QMC5883 doesn't have a self-test function with an induced magnetic field like the HMC5983 has.

/* Set Register */
#define QMC5883_SET_DEFAULT (1 << 0)

#define QMC5883_TEMP_OFFSET 50 /* deg celsius */
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Temp offset is not calibrated on sensor at the factory so this is a pretty rough estimate to get ballpark sensor temp. All temp calibration is happening on chip by default.

@jinger26
Copy link
Contributor

jinger26 commented Jan 24, 2019

There are several GPS on the market that is pending this driver. @dagar @DanielePettenuzzo could you review?

@Antiheavy
Copy link
Contributor

We are considering this part for an upcoming board design. Will be interested to evaluate once this PR goes through.

bool read_valid = false;
bool id_valid = false;

while(count > 0){
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 added a number of retries to probe for in cases of poor wiring or i2c interference. This has helped with the driver not starting on boot.

*/

/* Max measurement rate is 200Hz */
#define QMC5883_CONVERSION_INTERVAL (1000000 / 150) /* microseconds */
Copy link
Contributor Author

@dlwalter dlwalter Feb 19, 2019

Choose a reason for hiding this comment

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

@dagar I made the denominator 150 to match the HMC driver, but I recently noticed that the HMC5883 driver is actually polling at 50hz (measuring on a logic analyzer). I think this is due to the HMC5883:calibrate function here setting the polling rate to 50hz and never getting corrected.

@dagar
Copy link
Member

dagar commented Mar 9, 2019

I think this could use a bit more work, but it looks safe to merge. I've updated with latest master and disabled the autostart for now. Let's test it a bit more before enabling by default. Nice work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants