Skip to content

feat(ism330dl): Add OLED spirit level example.#376

Open
Kaanoz-en wants to merge 1 commit intomainfrom
feat/ism330dl-spirit-level
Open

feat(ism330dl): Add OLED spirit level example.#376
Kaanoz-en wants to merge 1 commit intomainfrom
feat/ism330dl-spirit-level

Conversation

@Kaanoz-en
Copy link
Copy Markdown
Contributor

Summary

Closes #329

Adds an interactive spirit_level.py example demonstrating a digital bubble level using the ISM330DL accelerometer and the SSD1327 OLED display. The bubble moves dynamically based on the board's physical tilt, providing real-time visual feedback.

Changes

  • Created lib/ism330dl/examples/spirit_level.py.
  • Mapped X and Y acceleration data (acceleration_g()) to a 2D pixel offset.
  • Inverted the Y-axis mapping to simulate the physical behavior of an air bubble (moving towards the highest point).
  • Added a custom fill_circle() helper function to draw a smooth bubble (bypassing the lack of native ellipse support in framebuf).
  • Designed a HUD with a crosshair and dynamic background lighting that brightens when the board reaches a flat state (< 0.05g).
  • Extracted all magic numbers into clean, descriptive constants.
  • Added the new spirit_level.py example to the README.md examples table.

Checklist

  • ruff check passes
  • python -m pytest tests/ -k mock -v passes (no mock test broken)
  • Tested on hardware (if applicable)
  • README updated (if adding/changing public API)
  • Examples added/updated (if applicable)
  • Commit messages follow <scope>: <Description.> format

Copilot AI review requested due to automatic review settings April 10, 2026 12:44
@Kaanoz-en Kaanoz-en requested a review from Charly-sketch April 10, 2026 12:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new interactive ISM330DL + SSD1327 OLED example that visualizes board tilt as a “bubble” moving around a center crosshair, with a brighter background when the device is near level.

Changes:

  • Added lib/ism330dl/examples/spirit_level.py implementing spirit-level visualization on the SSD1327 OLED.
  • Included a custom fill_circle() helper for drawing a filled circular bubble with framebuf.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +59 to +61
# 1. Read acceleration in g-forces
ax, ay, az = imu.acceleration_g()

Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

az is unpacked from imu.acceleration_g() but never used. With Ruff enabled for examples (no per-file ignore for F841), this should be renamed to _/_az or used to avoid an unused-variable lint failure.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've renamed the unused Z-axis variable to _az to satisfy Ruff's F841 rule and clearly indicate it's intentionally ignored.

Comment on lines +35 to +37
for x in range(-r, r + 1):
if x*x + y*y <= r*r:
fbuf.pixel(x0 + x, y0 + y, c)
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The circle fill test uses operators without surrounding whitespace (x*x, r*r, etc.). Ruff explicitly enables E225, so this should be spaced (x * x, etc.) to pass linting.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the required whitespace around the operators in the fill_circle helper (x * x, etc.) to comply with Ruff E225.

Comment on lines +68 to +72
# 3. Map Acceleration to Pixel Offset
# We cap the acceleration at 1.0g to avoid the bubble leaving the screen
# 3. Map Acceleration to Pixel Offset
clamped_ax = max(-1.0, min(1.0, ax))
clamped_ay = max(-1.0, min(1.0, ay))
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate comment header: "Map Acceleration to Pixel Offset" is repeated consecutively. Consider removing one copy to keep the example clean.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

@Kaanoz-en Kaanoz-en Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed the duplicated header.

Comment on lines +1 to +5
"""Spirit level example using ISM330DL accelerometer and SSD1327 OLED.

Displays a digital bubble level. The bubble moves according to the board's tilt.
When the board is perfectly flat, the bubble centers and the background lights up.
"""
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description mentions adding this example to a README examples table, but lib/ism330dl/README.md currently lists only basic_read/static_orientation/motion_orientation and does not include spirit_level.py. Either update the docs or adjust the PR description so they match.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My mistake, I missed staging the README.md file in my previous commit. It's now properly updated in the examples table and included in this push.

@Kaanoz-en Kaanoz-en force-pushed the feat/ism330dl-spirit-level branch from 7939156 to 2566c26 Compare April 10, 2026 13:08
@Charly-sketch
Copy link
Copy Markdown
Contributor

Review

Très bon travail sur cet exemple.

Le rendu est clair et intuitif, et l’effet “niveau à bulle” fonctionne très bien. L’utilisation de l’accéléromètre est pertinente, et le mapping vers l’écran est bien pensé. L’ajout du crosshair, de la zone centrale et du feedback visuel (changement de luminosité) rend l’exemple à la fois pédagogique et agréable à utiliser.

Le code est globalement propre, lisible, avec de bonnes constantes et une structure simple à suivre.

Quelques points à améliorer :


1. Duplication de commentaire

# 3. Map Acceleration to Pixel Offset
# 3. Map Acceleration to Pixel Offset

Petit détail mais à nettoyer pour garder le code propre.


2. Position de la bulle non clampée

bubble_x = SCREEN_CENTER_X + offset_x
bubble_y = SCREEN_CENTER_Y + offset_y

Même avec le clamp à ±1g, la bulle peut sortir de l’écran ou être partiellement coupée.

Suggestion : clamp final des coordonnées pour garantir qu’elle reste visible :

bubble_x = max(BUBBLE_RADIUS, min(127 - BUBBLE_RADIUS, bubble_x))
bubble_y = max(BUBBLE_RADIUS, min(127 - BUBBLE_RADIUS, bubble_y))

3. Inversion d’axe non expliquée

offset_x = int(-clamped_ay * MAX_OFFSET)

Le - est logique pour simuler une bulle physique, mais ce n’est pas expliqué.

Suggestion : ajouter un commentaire rapide pour clarifier l’intention (ex : inversion pour simuler la montée de la bulle vers le point haut).


Conclusion

Exemple très réussi et utile pour comprendre comment combiner capteur + affichage avec une interaction visuelle en temps réel.

Avec ces petits ajustements, il sera encore plus propre et robuste.

@Kaanoz-en Kaanoz-en force-pushed the feat/ism330dl-spirit-level branch from 2566c26 to 66dcd0c Compare April 13, 2026 08:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(ism330dl): Add spirit level example with OLED display.

3 participants