Skip to content

Commit b42debb

Browse files
committed
Added hacky heading function to magnetometer example, next version should be refactored and based on https://gist.github.com/CalebFenton/a97444750eb43e3354fd2d0196a2ebcf
1 parent 2a5119c commit b42debb

File tree

5 files changed

+100
-7
lines changed

5 files changed

+100
-7
lines changed

boards/MicroBit_v2/src/full/microbit-accelerometer.adb

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828
-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --
2929
-- --
3030
------------------------------------------------------------------------------
31-
3231
with MicroBit.I2C;
33-
32+
with Ada.Numerics; use Ada.Numerics;
33+
with Ada.Numerics.Generic_Elementary_Functions;
3434
package body MicroBit.Accelerometer is
3535

3636
Acc : LSM303AGR.LSM303AGR_Accelerometer (MicroBit.I2C.Controller);
@@ -47,7 +47,7 @@ package body MicroBit.Accelerometer is
4747
MicroBit.I2C.Initialize;
4848
end if;
4949

50-
Acc.Configure (LSM303AGR.Freq_400, LSM303AGR.Freq_10, LSM303AGR.Continuous_Mode);
50+
Acc.Configure (LSM303AGR.Freq_400, LSM303AGR.Freq_100, LSM303AGR.Continuous_Mode);
5151
end Initialize;
5252

5353
----------
@@ -63,6 +63,48 @@ package body MicroBit.Accelerometer is
6363
function MagData return LSM303AGR.All_Axes_Data
6464
is (Acc.Read_Magnetometer);
6565

66+
--Based on https://rosettacode.org/wiki/Map_range#Ada
67+
function Map ( Value : Float;
68+
A1 : Float; -- Range Min (from)
69+
A2 : Float; -- Range Max (from)
70+
B1 : Float; -- Range Min (to)
71+
B2 : Float -- Range Max (to)
72+
) return Float is
73+
begin
74+
return B1 + (Value - A1) * (B2 - B1) / (A2 - A1);
75+
end Map;
76+
77+
function Heading return LSM303AGR.Angle is
78+
package test is new Generic_Elementary_Functions (Float_Type => Float);
79+
Data : LSM303AGR.All_Axes_Data;
80+
Result: Float;
81+
X : Float;
82+
Y : Float;
83+
Z : Float;
84+
Angle : Integer;
85+
begin
86+
--get raw sensor data
87+
Data := MagData;
88+
X := Float (Data.X);
89+
Y := Float (Data.Y);
90+
Z := Float (Data.Z);
91+
92+
--map to known ranges using calibrated values (or 0 for using factory default)
93+
--it is up to the programmer to call calibrate first (although recommended)
94+
X := Map(X, MagMinX, MagMaxX, -1023.0, 1023.0);
95+
Y := Map(Y, MagMinY, MagMaxY, -1023.0, 1023.0);
96+
Z := Map(Z, MagMinZ, MagMaxZ, 0.0, 1023.0);
97+
98+
--calc angle
99+
Result := (Test.Arctan(Y, X) * 180.0) / Pi;
100+
Result := Result + 90.0;
101+
102+
--normalize such we can cast to Angle.
103+
Angle := Integer(Result) mod 360;
104+
105+
return LSM303AGR.Angle(Angle);
106+
end Heading;
107+
66108
begin
67109
Initialize;
68110
end MicroBit.Accelerometer;

boards/MicroBit_v2/src/full/microbit-accelerometer.ads

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@
3232
with LSM303AGR;
3333

3434
package MicroBit.Accelerometer is
35+
MagMinX : Float := -1.0 ; -- -32767.0;
36+
MagMinY : Float := -6.0 ; -- -32767.0;
37+
MagMinZ : Float := -8.0; -- -32767.0;
38+
39+
MagMaxX : Float := 11.0 ; -- 32767.0;
40+
MagMaxY : Float := 7.0; -- 32767.0;
41+
MagMaxZ : Float := 4.0; -- 32767.0;
3542

3643
function AccelDataRaw return LSM303AGR.All_Axes_Data_Raw;
3744

@@ -41,4 +48,14 @@ package MicroBit.Accelerometer is
4148
function MagData return LSM303AGR.All_Axes_Data;
4249
-- Return the magneto value for each of the three axes (X, Y, Z)
4350

51+
function Map ( Value : Float;
52+
A1 : Float; -- Range Min (from)
53+
A2 : Float; -- Range Max (from)
54+
B1 : Float; -- Range Min (to)
55+
B2 : Float -- Range Max (to)
56+
) return Float;
57+
-- Return mapped value
58+
59+
function Heading return LSM303AGR.Angle;
60+
-- Return the heading based on the magnetometer
4461
end MicroBit.Accelerometer;

components/src/motion/lsm303agr/lsm303agr.ads

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ package LSM303AGR is
5454
type Axis_Data is range -2**9 .. 2**9 - 1 with Size => 10; -- we decimate from 16 (the output of the accel device) to 10 bits? Why?
5555
-- Does this mean that the actual range is -512 .. 511?
5656

57+
type Angle is range 0 .. 360;
5758
type Axis_Data_Raw is record
5859
Low : UInt8;
5960
High : UInt8;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
22
"cortex-debug.armToolchainPrefix": "arm-eabi"
3+
"sarif-viewer.connectToGithubCodeScanning": "off"
34
}

examples/MicroBit_v2/ravenscar/magnetometer/src/main.adb

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,46 @@ use MicroBit;
55
procedure Main is
66

77
Data: All_Axes_Data;
8+
Heading : Angle;
9+
MinX, MinY, MinZ, MaxX, MaxY, MaxZ : Axis_Data := 0;
810
begin
911
loop
1012
Data := Accelerometer.MagData;
11-
Put_Line ("MAG;" &
12-
"X," & Data.X'Img & ";" &
13-
"Y," & Data.Y'Img & ";" &
14-
"Z," & Data.Z'Img);
1513

14+
if Data.X < MinX then
15+
MinX := Data.X;
16+
end if;
17+
18+
if Data.Y < MinY then
19+
MinY := Data.Y;
20+
end if;
21+
22+
if Data.Z < MinZ then
23+
MinZ := Data.Z;
24+
end if;
25+
26+
if Data.X > MaxX then
27+
MaxX := Data.X;
28+
end if;
29+
30+
if Data.Y > MaxY then
31+
MaxY := Data.Y;
32+
end if;
33+
34+
if Data.Z > MaxZ then
35+
MaxZ := Data.Z;
36+
end if;
37+
38+
Put_Line ("MIN X Y Z;" & MinX'Img & MinY'Img & MinZ'Img);
39+
Put_Line ("MAX X Y Z;" & MaxX'Img & MaxY'Img & MaxZ'Img);
40+
41+
-- Put_Line ("MAG;" &
42+
-- "X," & Data.X'Img & ";" &
43+
-- "Y," & Data.Y'Img & ";" &
44+
-- "Z," & Data.Z'Img);
45+
46+
Heading := AcceleroMeter.Heading;
47+
Put_Line("Heading;" & Heading'Img);
1648
delay 0.5;
1749
end loop;
1850
end Main;

0 commit comments

Comments
 (0)