|
1 | 1 | #include <stdio.h>
|
2 | 2 |
|
3 | 3 | #include "pico/stdlib.h"
|
4 |
| -#include "lib/fonts.h" |
5 | 4 | #include "lib/st7735.h"
|
6 | 5 | #include "lib/ICM20948.h"
|
7 | 6 |
|
| 7 | +struct Vec { |
| 8 | + float x; |
| 9 | + float y; |
| 10 | + float z; |
| 11 | +}; |
| 12 | + |
8 | 13 | // Thanks plaaosert for the ST7735 and IMU guide :D
|
9 | 14 |
|
10 | 15 | void SetupIMU() {
|
@@ -36,41 +41,78 @@ int main() {
|
36 | 41 |
|
37 | 42 | SetupIMU();
|
38 | 43 |
|
39 |
| - float x; |
40 |
| - float y; |
41 |
| - float z; |
42 |
| - |
43 |
| - while (true) { |
44 |
| - icm20948MagRead(&x, &y, &z); |
| 44 | + struct Vec mag; |
| 45 | + // For calibration: |
| 46 | + struct Vec magmin; |
| 47 | + struct Vec magmax; |
45 | 48 |
|
46 |
| - char arrayX[10]; |
47 |
| - if (x > 0) { |
48 |
| - sprintf(arrayX, "%.2f", x); |
49 |
| - } else { |
50 |
| - sprintf(arrayX, "%.1f", x); |
51 |
| - } |
| 49 | + int centre_x = ST7735_WIDTH / 2; |
| 50 | + int centre_y = ST7735_HEIGHT / 2; |
| 51 | + int point_x; |
| 52 | + int point_y; |
| 53 | + bool negative; |
| 54 | + float magnitude; |
| 55 | + int current; |
| 56 | + float heading; |
| 57 | + char arrayH[10]; |
52 | 58 |
|
53 |
| - char arrayY[10]; |
54 |
| - if (y > 0) { |
55 |
| - sprintf(arrayY, "%.2f", y); |
56 |
| - } else { |
57 |
| - sprintf(arrayY, "%.1f", y); |
58 |
| - } |
| 59 | + icm20948MagRead(&magmin.x, &magmin.y, &magmin.z); |
| 60 | + icm20948MagRead(&magmax.x, &magmax.y, &magmin.z); |
59 | 61 |
|
60 |
| - char arrayZ[10]; |
61 |
| - if (z > 0) { |
62 |
| - sprintf(arrayZ, "%.2f", z); |
| 62 | + while (true) { |
| 63 | + // Read magnetometer values |
| 64 | + icm20948MagRead(&mag.x, &mag.y, &mag.z); |
| 65 | + |
| 66 | + // Calibrate values |
| 67 | + if (mag.x < magmin.x) magmin.x = mag.x; |
| 68 | + if (mag.x > magmax.x) magmax.x = mag.x; |
| 69 | + if (mag.y < magmin.y) magmin.y = mag.y; |
| 70 | + if (mag.y > magmax.y) magmax.y = mag.y; |
| 71 | + if (mag.z < magmin.z) magmin.z = mag.z; |
| 72 | + if (mag.z > magmax.z) magmax.z = mag.z; |
| 73 | + |
| 74 | + // Calibrate by removing offset of smallest seen value |
| 75 | + mag.x -= magmin.x; |
| 76 | + mag.y -= magmin.y; |
| 77 | + mag.z -= magmin.z; |
| 78 | + |
| 79 | + // Scale value based of highest values seen |
| 80 | + // Creates values between 0 and 1 |
| 81 | + |
| 82 | + // Avoid Zero Division |
| 83 | + if (magmax.x - magmin.x > 0.001) mag.x /= magmax.x - magmin.x; |
| 84 | + if (magmax.y - magmin.y > 0.001) mag.y /= magmax.y - magmin.y; |
| 85 | + if (magmax.z - magmin.z > 0.001) mag.z /= magmax.z - magmin.z; |
| 86 | + |
| 87 | + // Shift values to -0.5 <= x <= 0.5 |
| 88 | + mag.x -= 0.5; |
| 89 | + mag.y -= 0.5; |
| 90 | + mag.z -= 0.5; |
| 91 | + |
| 92 | + // Convert Gauss values to Radian heading |
| 93 | + heading = atan2(mag.x, mag.y); |
| 94 | + // Convert to positive heading (add a full radian turn) |
| 95 | + if (heading < 0) heading += 2 * 3.14159; |
| 96 | + |
| 97 | + // Worked out using counterclockwise rotation matrix |
| 98 | + point_x = centre_x + (20 * sin(heading)); |
| 99 | + point_y = centre_y + ((-20) * cos(heading)); |
| 100 | + |
| 101 | + // Draw compass needle |
| 102 | + ST7735_FillScreen(ST7735_BLACK); |
| 103 | + |
| 104 | + ST7735_DrawPixel(centre_x, centre_y, ST7735_RED); |
| 105 | + ST7735_DrawPixel(point_x, point_y, ST7735_RED); |
| 106 | + |
| 107 | + // Convert heading to degrees |
| 108 | + heading *= 180 / 3.14159; |
| 109 | + |
| 110 | + if (heading > 0) { |
| 111 | + sprintf(arrayH, "%.2f", heading); |
63 | 112 | } else {
|
64 |
| - sprintf(arrayZ, "%.1f", z); |
| 113 | + sprintf(arrayH, "%.1f", heading); |
65 | 114 | }
|
66 |
| - |
67 |
| - ST7735_WriteString(5, 5, arrayX, Font_16x26, ST7735_RED, ST7735_BLACK); |
68 |
| - ST7735_WriteString(5, 31, arrayY, Font_16x26, ST7735_GREEN, ST7735_BLACK); |
69 |
| - ST7735_WriteString(5, 57, arrayZ, Font_16x26, ST7735_BLUE, ST7735_BLACK); |
70 |
| - |
71 |
| - ST7735_WriteString(7, 120, "x", Font_16x26, ST7735_RED, ST7735_BLACK); |
72 |
| - ST7735_WriteString(27, 120, "y", Font_16x26, ST7735_GREEN, ST7735_BLACK); |
73 |
| - ST7735_WriteString(47, 120, "z", Font_16x26, ST7735_BLUE, ST7735_BLACK); |
| 115 | + ST7735_WriteString(80, 80, arrayH, Font_16x26, ST7735_RED, ST7735_BLACK); |
74 | 116 |
|
75 | 117 | sleep_ms(100);
|
76 | 118 | }
|
|
0 commit comments