PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

154 lines
3.4KB

  1. #include <NXPMotionSense.h>
  2. #include <Wire.h>
  3. #include <EEPROM.h>
  4. #include <util/crc16.h>
  5. NXPMotionSense imu;
  6. const int ledPin = 13;
  7. int ledState = LOW;
  8. int ledFastblinks = 0;
  9. elapsedMillis ledMillis = 0;
  10. int loopcount = 0;
  11. void receiveCalibration();
  12. void setup() {
  13. Serial.begin(115200);
  14. while (!Serial) ; // wait for serial port open
  15. imu.begin();
  16. pinMode(ledPin, OUTPUT);
  17. }
  18. void loop() {
  19. int ax, ay, az;
  20. int gx, gy, gz;
  21. int mx, my, mz;
  22. // get and print uncalibrated data
  23. if (imu.available()) {
  24. imu.readMotionSensor(ax, ay, az, gx, gy, gz, mx, my, mz);
  25. Serial.print("Raw:");
  26. Serial.print(ax);
  27. Serial.print(',');
  28. Serial.print(ay);
  29. Serial.print(',');
  30. Serial.print(az);
  31. Serial.print(',');
  32. Serial.print(gx);
  33. Serial.print(',');
  34. Serial.print(gy);
  35. Serial.print(',');
  36. Serial.print(gz);
  37. Serial.print(',');
  38. Serial.print(mx);
  39. Serial.print(',');
  40. Serial.print(my);
  41. Serial.print(',');
  42. Serial.print(mz);
  43. Serial.println();
  44. loopcount = loopcount + 1;
  45. }
  46. // check for incoming calibration
  47. receiveCalibration();
  48. // occasionally print calibration
  49. if (loopcount == 50 || loopcount > 100) {
  50. Serial.print("Cal1:");
  51. float caloffsets[9], calmag;
  52. imu.getCalibration(caloffsets, NULL, &calmag);
  53. for (int i=0; i<9; i++) {
  54. Serial.print(caloffsets[i], 3);
  55. Serial.print(',');
  56. }
  57. Serial.println(calmag, 3);
  58. loopcount = loopcount + 1;
  59. }
  60. if (loopcount >= 100) {
  61. Serial.print("Cal2:");
  62. float calsoftiron[9];
  63. imu.getCalibration(NULL, calsoftiron, NULL);
  64. for (int i=0; i<9; i++) {
  65. Serial.print(calsoftiron[i], 4);
  66. if (i < 8) Serial.print(',');
  67. }
  68. Serial.println();
  69. loopcount = 0;
  70. }
  71. // blink LED, slow normally, fast when calibration written
  72. if (ledMillis >= 1000) {
  73. if (ledFastblinks > 0) {
  74. ledFastblinks = ledFastblinks - 1;
  75. ledMillis -= 125;
  76. } else {
  77. ledMillis -= 1000;
  78. }
  79. if (ledState == LOW) {
  80. ledState = HIGH;
  81. } else {
  82. ledState = LOW;
  83. }
  84. digitalWrite(ledPin, ledState);
  85. }
  86. }
  87. byte caldata[68]; // buffer to receive magnetic calibration data
  88. byte calcount=0;
  89. void receiveCalibration() {
  90. uint16_t crc;
  91. byte b, i;
  92. if (Serial.available()) {
  93. b = Serial.read();
  94. if (calcount == 0 && b != 117) {
  95. // first byte must be 117
  96. return;
  97. }
  98. if (calcount == 1 && b != 84) {
  99. // second byte must be 84
  100. calcount = 0;
  101. return;
  102. }
  103. // store this byte
  104. caldata[calcount++] = b;
  105. if (calcount < 68) {
  106. // full calibration message is 68 bytes
  107. return;
  108. }
  109. // verify the crc16 check
  110. crc = 0xFFFF;
  111. for (i=0; i < 68; i++) {
  112. crc = _crc16_update(crc, caldata[i]);
  113. }
  114. if (crc == 0) {
  115. // data looks good, use it
  116. imu.writeCalibration(caldata);
  117. calcount = 0;
  118. loopcount = 10000;
  119. ledFastblinks = 16; // Toggle LED faster the next 16 times
  120. return;
  121. }
  122. // look for the 117,84 in the data, before discarding
  123. for (i=2; i < 67; i++) {
  124. if (caldata[i] == 117 && caldata[i+1] == 84) {
  125. // found possible start within data
  126. calcount = 68 - i;
  127. memmove(caldata, caldata + i, calcount);
  128. return;
  129. }
  130. }
  131. // look for 117 in last byte
  132. if (caldata[67] == 117) {
  133. caldata[0] = 117;
  134. calcount = 1;
  135. } else {
  136. calcount = 0;
  137. }
  138. }
  139. }