First draft HMC5883 magnetometer sensor using physical quantities, outputting via serial port using std::cout on mbed os 5

Committer:
skyscraper
Date:
Tue Mar 24 15:21:34 2020 +0000
Revision:
2:9ffb2f18756b
Parent:
1:e11ab941748b
Child:
3:2834be4e10ef
move hmc5883 code to separate source and header file

Who changed what in which revision?

UserRevisionLine numberNew contents of line
skyscraper 0:37dbfb036586 1
skyscraper 0:37dbfb036586 2 #include "mbed.h"
skyscraper 2:9ffb2f18756b 3 #include "hmc5883.h"
skyscraper 0:37dbfb036586 4 #include <quan/max.hpp>
skyscraper 0:37dbfb036586 5 #include <quan/min.hpp>
skyscraper 0:37dbfb036586 6
skyscraper 2:9ffb2f18756b 7 namespace {
skyscraper 2:9ffb2f18756b 8
skyscraper 2:9ffb2f18756b 9 DigitalOut led2(LED2);
skyscraper 0:37dbfb036586 10
skyscraper 2:9ffb2f18756b 11 QUAN_QUANTITY_LITERAL(magnetic_flux_density,gauss);
skyscraper 2:9ffb2f18756b 12 QUAN_QUANTITY_LITERAL(magnetic_flux_density,milli_gauss);
skyscraper 2:9ffb2f18756b 13 QUAN_QUANTITY_LITERAL(magnetic_flux_density,uT);
skyscraper 0:37dbfb036586 14
skyscraper 2:9ffb2f18756b 15 // terminal loop, printing message periodically
skyscraper 2:9ffb2f18756b 16 void loop_forever(std::string const & str)
skyscraper 2:9ffb2f18756b 17 {
skyscraper 2:9ffb2f18756b 18 // stop but print error dynamically
skyscraper 2:9ffb2f18756b 19 int count = 0;
skyscraper 2:9ffb2f18756b 20 for (;;) {
skyscraper 2:9ffb2f18756b 21 led2 = 1;
skyscraper 2:9ffb2f18756b 22 std::cout << str << " " << count++ << '\n';
skyscraper 2:9ffb2f18756b 23 ThisThread::sleep_for(200U);
skyscraper 2:9ffb2f18756b 24 led2 = 0;
skyscraper 2:9ffb2f18756b 25 ThisThread::sleep_for(800U);
skyscraper 2:9ffb2f18756b 26 }
skyscraper 0:37dbfb036586 27 }
skyscraper 0:37dbfb036586 28 }// namespace
skyscraper 0:37dbfb036586 29
skyscraper 0:37dbfb036586 30 int main()
skyscraper 0:37dbfb036586 31 {
skyscraper 0:37dbfb036586 32 std::cout << "HMC5883 test\n";
skyscraper 0:37dbfb036586 33
skyscraper 0:37dbfb036586 34 //wait for mag to init
skyscraper 0:37dbfb036586 35 ThisThread::sleep_for(500U);
skyscraper 0:37dbfb036586 36
skyscraper 2:9ffb2f18756b 37 bool success = mag_detected();
skyscraper 2:9ffb2f18756b 38 if ( success ) {
skyscraper 0:37dbfb036586 39 std::cout << "Detected a HMC5883\n";
skyscraper 0:37dbfb036586 40 } else {
skyscraper 0:37dbfb036586 41 loop_forever("Failed to detect HMC5883");
skyscraper 0:37dbfb036586 42 }
skyscraper 0:37dbfb036586 43
skyscraper 0:37dbfb036586 44 // N.b after offsets removed mag was reading around 33.6 uT, so not bad!
skyscraper 0:37dbfb036586 45 constexpr auto earth_magnetic_field_flux_density = 31.869_uT;
skyscraper 0:37dbfb036586 46 success =
skyscraper 0:37dbfb036586 47 mag_set_samples_average(8) &&
skyscraper 0:37dbfb036586 48 mag_set_data_rate<3,4>() &&
skyscraper 0:37dbfb036586 49 // N.B if offsets are large then may need to set larger range
skyscraper 0:37dbfb036586 50 // prob need to cycle through looking for best range
skyscraper 0:37dbfb036586 51 // so this may not work
skyscraper 0:37dbfb036586 52 mag_set_range( earth_magnetic_field_flux_density * 2U);
skyscraper 0:37dbfb036586 53 if ( !success) {
skyscraper 0:37dbfb036586 54 loop_forever("HMC5883 setup failed");
skyscraper 0:37dbfb036586 55 }
skyscraper 2:9ffb2f18756b 56
skyscraper 2:9ffb2f18756b 57 std::cout << " mag range set to " << mag_get_range() << '\n';
skyscraper 0:37dbfb036586 58
skyscraper 0:37dbfb036586 59 // calculate the offsets dynamically by averaging
skyscraper 0:37dbfb036586 60 // the min and max over time
skyscraper 0:37dbfb036586 61 quan::three_d::vect<quan::magnetic_flux_density::uT> voffsets;
skyscraper 0:37dbfb036586 62 quan::three_d::vect<quan::magnetic_flux_density::uT> vmax;
skyscraper 0:37dbfb036586 63 quan::three_d::vect<quan::magnetic_flux_density::uT> vmin;
skyscraper 0:37dbfb036586 64
skyscraper 1:e11ab941748b 65 auto prev = Kernel::get_ms_count();
skyscraper 0:37dbfb036586 66 for (;;) {
skyscraper 0:37dbfb036586 67
skyscraper 0:37dbfb036586 68 quan::three_d::vect<quan::magnetic_flux_density::uT> values;
skyscraper 0:37dbfb036586 69 if(mag_do_single_measurement(values)) {
skyscraper 0:37dbfb036586 70
skyscraper 0:37dbfb036586 71 vmax.x = quan::max(vmax.x,values.x);
skyscraper 0:37dbfb036586 72 vmax.y = quan::max(vmax.y,values.y);
skyscraper 0:37dbfb036586 73 vmax.z = quan::max(vmax.z,values.z);
skyscraper 0:37dbfb036586 74
skyscraper 0:37dbfb036586 75 vmin.x = quan::min(vmin.x,values.x);
skyscraper 0:37dbfb036586 76 vmin.y = quan::min(vmin.y,values.y);
skyscraper 0:37dbfb036586 77 vmin.z = quan::min(vmin.z,values.z);
skyscraper 0:37dbfb036586 78
skyscraper 0:37dbfb036586 79 voffsets = (vmin + vmax)/2.f;
skyscraper 0:37dbfb036586 80
skyscraper 0:37dbfb036586 81 values -= voffsets;
skyscraper 0:37dbfb036586 82
skyscraper 0:37dbfb036586 83 std::cout << "val = " << values << '\n';
skyscraper 0:37dbfb036586 84 std::cout << "off = " << voffsets << "\n\n";
skyscraper 0:37dbfb036586 85 } else {
skyscraper 0:37dbfb036586 86 std::cout << "mag read failed\n";
skyscraper 0:37dbfb036586 87 }
skyscraper 0:37dbfb036586 88 ThisThread::sleep_for(10U);
skyscraper 1:e11ab941748b 89 auto now = Kernel::get_ms_count();
skyscraper 1:e11ab941748b 90 if (( now - prev)> 500){
skyscraper 1:e11ab941748b 91 prev = now;
skyscraper 1:e11ab941748b 92 led2 = ! led2;
skyscraper 1:e11ab941748b 93 }
skyscraper 0:37dbfb036586 94 }
skyscraper 0:37dbfb036586 95 }