Skip to content

Commit 49f63a7

Browse files
committed
adds IMU= to the build command
Added the first IMU sensor driver to the build system. This driver is a 6dof sensor that is able to sense roll and pitch. This sensor will allow for automatic rotation of a display depending on how the user has it orientated. IMU/MEMS sensors do not provide data that you can read and easily know what the roll and pitch is so I also wrote a fusion math driver as a C extension module. The math involved in reading the IMU data and turning it into roll pitch and yaw is some pretty heavy lifting which is the reason why I wrote it in C code. All of the math involved is floating point math which no increase in performance is given above python code if I used the viper code emitter which is why it is written in C code. There is also an additional driver that is frozen into the firmware if an IMU driver is added and that is "auto_rotate". This driver handles the reading of the IMU sensor data from a driver that gets passed to it. It does the calculations to figure out which way the display needs to be rotated depending on the orientation that the display is being held in. This driver has 2 modes, a locked rotation mode which will lock rotation angles at 0, 90, 180 and 27o. This mode will use a display hardware rotation if it is available. The other mode would work best on small displays like the ones used on smart watches. The round display also lends to this feature working best as well. The rotation is a free rotation and will adjust as the roll changes so the UI will always be display in the correct position no matter what angle the display is being held at. Not everyone holds their arm perfectly horizontal when looking at a watch. There is one thing I have to get someone to test out and that is when showing the watch to another person which involves the pitch angle. I want the display to roll 180 degrees if the pitch angle is less than zero. I will add that feature and tweak how it works when I get someone to test it with.
1 parent ec87ada commit 49f63a7

19 files changed

+338
-109
lines changed

builder/__init__.py

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ def update_mphalport(target):
217217

218218
def generate_manifest(
219219
script_dir, lvgl_api, manifest_path, displays,
220-
indevs, io_expanders, frozen_manifest, *addl_manifest_files
220+
indevs, io_expanders, imus, frozen_manifest, *addl_manifest_files
221221
):
222222
addl_manifest_files = list(addl_manifest_files)
223223

@@ -256,6 +256,12 @@ def generate_manifest(
256256
)
257257
]
258258

259+
if imus:
260+
frozen_manifest_files.extend([
261+
f'{script_dir}/api_drivers/common_api_drivers/frozen/other/auto_rotation.py',
262+
f'{api_path}/frozen/imu_sensor/imu_sensor_framework.py'
263+
])
264+
259265
toml_gen_driver = f'{script_dir}/build/display.py'
260266
if os.path.exists(toml_gen_driver):
261267
print(toml_gen_driver)
@@ -324,6 +330,17 @@ def generate_manifest(
324330

325331
displays.append(file)
326332

333+
if 'all' in imus:
334+
imus.remove('all')
335+
path = f'{script_dir}/api_drivers/common_api_drivers/imu_sensor'
336+
for file in os.listdir(path):
337+
if '.wip' in file:
338+
continue
339+
340+
if file.endswith('.py'):
341+
name = file[:-3]
342+
imus.append(name)
343+
327344
for file in io_expanders:
328345
if not os.path.exists(file):
329346
tmp_file = (
@@ -346,6 +363,28 @@ def generate_manifest(
346363
if entry not in manifest_files:
347364
manifest_files.append(entry)
348365

366+
for file in imus:
367+
if not os.path.exists(file):
368+
tmp_file = (
369+
f'{script_dir}/api_drivers/common_api_drivers'
370+
f'/imu_sensor/{file.lower()}.py'
371+
)
372+
373+
if not os.path.exists(tmp_file):
374+
raise RuntimeError(f'IMU sensor not found "{file}"')
375+
376+
print(tmp_file)
377+
378+
file_path, file_name = os.path.split(tmp_file)
379+
entry = f"freeze('{file_path}', '{file_name}')"
380+
else:
381+
print(file)
382+
file_path, file_name = os.path.split(file)
383+
entry = f"freeze('{file_path}', '{file_name}')"
384+
385+
if entry not in manifest_files:
386+
manifest_files.append(entry)
387+
349388
for file in indevs:
350389
if not os.path.exists(file):
351390
tmp_file = (
@@ -781,7 +820,7 @@ def mpy_cross():
781820

782821

783822
def build_manifest(
784-
target, script_dir, lvgl_api, displays, indevs, expanders, frozen_manifest
823+
target, script_dir, lvgl_api, displays, indevs, expanders, imus, frozen_manifest
785824
):
786825
update_mphalport(target)
787826
if target == 'teensy':
@@ -793,7 +832,7 @@ def build_manifest(
793832

794833
generate_manifest(
795834
script_dir, lvgl_api, manifest_path,
796-
displays, indevs, expanders, frozen_manifest
835+
displays, indevs, expanders, imus, frozen_manifest
797836
)
798837

799838

builder/esp32.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ def has_correct_idf():
639639

640640

641641
def build_manifest(
642-
target, script_dir, lvgl_api, displays, indevs, expanders, frozen_manifest
642+
target, script_dir, lvgl_api, displays, indevs, expanders, imus, frozen_manifest
643643
):
644644
_update_mphalport(target)
645645

@@ -659,7 +659,7 @@ def build_manifest(
659659

660660
set_displays.extend(generate_manifest(
661661
script_dir, lvgl_api, manifest_path,
662-
displays, indevs, expanders, frozen_manifest
662+
displays, indevs, expanders, imus, frozen_manifest
663663
# f'{script_dir}/api_drivers/common_api_drivers/frozen/other/spi3wire.py'
664664
))
665665

builder/macOS.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,11 @@ def build_manifest(
3737
displays,
3838
indevs,
3939
expanders,
40+
imus,
4041
frozen_manifest
4142
):
4243
_build_manifest(target, script_dir, lvgl_api, displays,
43-
indevs, expanders, frozen_manifest)
44+
indevs, expanders, imus, frozen_manifest)
4445

4546

4647
def clean():

builder/nrf.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,15 @@ def build_manifest(
6363
displays,
6464
indevs,
6565
expanders,
66+
imus,
6667
frozen_manifest
6768
):
6869
update_mphalport(target)
6970
manifest_path = 'lib/micropython/ports/nrf/modules/manifest.py'
7071

7172
generate_manifest(
7273
script_dir, lvgl_api, manifest_path,
73-
displays, indevs, expanders, frozen_manifest
74+
displays, indevs, expanders, imus, frozen_manifest
7475
)
7576

7677

builder/raspberry_pi.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,11 @@ def build_manifest(
3939
displays,
4040
indevs,
4141
expanders,
42+
imus,
4243
frozen_manifest
4344
):
4445
_build_manifest(target, script_dir, lvgl_api, displays,
45-
indevs, expanders, frozen_manifest)
46+
indevs, expanders, imus, frozen_manifest)
4647

4748

4849
def clean():

builder/renesas.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,15 @@ def build_manifest(
6363
displays,
6464
indevs,
6565
expanders,
66+
imus,
6667
frozen_manifest
6768
):
6869
update_mphalport(target)
6970
manifest_path = 'lib/micropython/ports/renesas-ra/boards/manifest.py'
7071

7172
generate_manifest(
7273
script_dir, lvgl_api, manifest_path,
73-
displays, indevs, expanders, frozen_manifest
74+
displays, indevs, expanders, imus, frozen_manifest
7475
)
7576

7677

builder/rp2.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,15 @@ def build_commands(_, extra_args, __, lv_cflags, brd):
8585

8686

8787
def build_manifest(
88-
target, script_dir, lvgl_api, displays, indevs, expanders, frozen_manifest
88+
target, script_dir, lvgl_api, displays, indevs, expanders, imus, frozen_manifest
8989
):
9090
update_mphalport(target)
9191

9292
manifest_path = 'lib/micropython/ports/rp2/boards/manifest.py'
9393

9494
generate_manifest(
9595
script_dir, lvgl_api, manifest_path,
96-
displays, indevs, expanders, frozen_manifest
96+
displays, indevs, expanders, imus, frozen_manifest
9797
)
9898

9999

builder/stm32.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,15 @@ def build_manifest(
7070
displays,
7171
indevs,
7272
expanders,
73+
imus,
7374
frozen_manifest
7475
):
7576
update_mphalport(target)
7677

7778
manifest_path = 'lib/micropython/ports/stm32/boards/manifest.py'
7879

7980
generate_manifest(script_dir, lvgl_api, manifest_path, displays,
80-
indevs, expanders, frozen_manifest)
81+
indevs, expanders, imus, frozen_manifest)
8182

8283

8384
def force_clean(clean_mpy_cross):

builder/unix.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ def build_manifest(
121121
displays,
122122
indevs,
123123
expanders,
124+
imus,
124125
frozen_manifest
125126
):
126127
global SCRIPT_PATH
@@ -132,7 +133,7 @@ def build_manifest(
132133
manifest_path = 'lib/micropython/ports/unix/variants/manifest.py'
133134

134135
generate_manifest(script_dir, lvgl_api, manifest_path, displays,
135-
indevs, expanders, frozen_manifest)
136+
indevs, expanders, imus, frozen_manifest)
136137

137138

138139
def force_clean(clean_mpy_cross):

builder/windows.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ def build_manifest(
111111
displays,
112112
indevs,
113113
expanders,
114+
imus,
114115
frozen_manifest
115116
):
116117
global SCRIPT_PATH
@@ -122,7 +123,7 @@ def build_manifest(
122123
manifest_path = 'lib/micropython/ports/windows/variants/manifest.py'
123124

124125
generate_manifest(script_dir, lvgl_api, manifest_path, displays,
125-
indevs, expanders, frozen_manifest)
126+
indevs, expanders, imus, frozen_manifest)
126127

127128

128129
def force_clean(clean_mpy_cross):

ext_mod/imu_fusion/include/fusion.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include "py/obj.h"
2+
3+
#ifndef __FUSION_H__
4+
#define __FUSION_H__
5+
6+
typedef struct {
7+
mp_obj_base_t base;
8+
9+
uint32_t start_ts;
10+
float mag_bias[3];
11+
float beta; // 0.6045997880780725842169464404f
12+
float declination;
13+
float q[4];
14+
15+
} mp_fusion_obj_t;
16+
17+
18+
extern const mp_obj_type_t mp_spi3wire_type;
19+
20+
#endif

ext_mod/imu_fusion/micropython.cmake

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright (c) 2024 - 2025 Kevin G. Schlosser
2+
3+
# Create an INTERFACE library for our C module.
4+
add_library(usermod_fusion INTERFACE)
5+
6+
set(FUSION_INCLUDES
7+
${CMAKE_CURRENT_LIST_DIR}/include
8+
)
9+
10+
set(FUSION_SOURCES
11+
${CMAKE_CURRENT_LIST_DIR}/src/fusion.c
12+
)
13+
14+
15+
# Add our source files to the lib
16+
target_sources(usermod_fusion INTERFACE ${FUSION_SOURCES})
17+
18+
# Add include directories.
19+
target_include_directories(usermod_fusion INTERFACE ${FUSION_INCLUDES})
20+
21+
# Link our INTERFACE library to the usermod target.
22+
target_link_libraries(usermod INTERFACE usermod_fusion)

0 commit comments

Comments
 (0)