feat(vl53l1x): Add proximity alert example with buzzer.#337
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new VL53L1X example that turns the board buzzer into a proximity alert by mapping measured distance to a PWM tone.
Changes:
- Added
proximity_alert.pyexample that reads VL53L1X distance continuously over I2C. - Configured hardware PWM on the
SPEAKERpin and modulated pitch when distance is below a threshold. - Added Ctrl+C handling to silence the buzzer on user exit.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # sensor configuration | ||
| i2c = I2C(1) | ||
| tof = VL53L1X(i2c) | ||
|
|
||
| #buzzer initialisation | ||
| buzzer_tim = Timer(1, freq=1000) | ||
| buzzer_ch = buzzer_tim.channel(4, Timer.PWM, pin=Pin("SPEAKER")) | ||
| buzzer_ch.pulse_width_percent(0) |
There was a problem hiding this comment.
Ruff will flag these block comments because they don’t start with # (E265). Please add a space after # (and keep comment capitalization consistent with other examples).
There was a problem hiding this comment.
I actually ran make lint locally and it passed without throwing any E265 errors, so it seems this specific rule might be ignored in our current Ruff configuration! That being said, you are absolutely right about standard formatting and consistency. I'll update the comments with the proper spacing and capitalization right away. Thanks for catching it!
| #frequency ranging from 1500 (really close) to 500 (at 200mm) | ||
| freq = (1500- (distance * 5)) | ||
| #security limits | ||
| freq = max(500, min(1500, freq)) |
There was a problem hiding this comment.
The frequency calculation has formatting that violates pycodestyle (selected by repo Ruff config): missing whitespace around operators (E225) and comment spacing (E265). Reformat this expression/comments so ruff check passes for examples too.
There was a problem hiding this comment.
Good catch! You are right, I missed the space around the minus operator and the spaces after the hash in the comments. I've removed the redundant parentheses and updated the formatting to fully comply with PEP 8 and the E225/E265 rules. Thanks for pointing this out!
| try: | ||
| while True: | ||
| distance = tof.read() | ||
| print("Distance: {} mm".format(distance)) | ||
|
|
||
| if distance < DISTANCE_THRESHOLD_MM: | ||
| #frequency ranging from 1500 (really close) to 500 (at 200mm) | ||
| freq = (1500- (distance * 5)) | ||
| #security limits | ||
| freq = max(500, min(1500, freq)) | ||
|
|
||
| buzzer_tim.freq(freq) | ||
| buzzer_ch.pulse_width_percent(50) | ||
| else: | ||
| buzzer_ch.pulse_width_percent(0) | ||
|
|
There was a problem hiding this comment.
tof.read() can raise OSError("VL53L1X data ready timeout") (see lib/vl53l1x/vl53l1x/device.py:_ensure_data). If that happens while the buzzer is on, this script will exit without silencing it. Consider using a try: ... finally: (or catching Exception) around the loop to always set the buzzer duty back to 0 before exiting.
There was a problem hiding this comment.
This is an excellent point, I had handled the KeyboardInterrupt to prevent the PWM from running indefinitely, but I completely missed the potential OSError from the I2C bus timeouts. Moving the cleanup code to a finally: block is the perfect way to guarantee the buzzer is silenced no matter how the script exits. I'm updating the structure right away.
|
|
||
|
|
||
| except KeyboardInterrupt: | ||
| buzzer_ch.pulse_width_percent(0) #Properly cut the sound when the user presses CTLR+C |
There was a problem hiding this comment.
Typo in the comment: CTLR+C should be CTRL+C.
| buzzer_ch.pulse_width_percent(0) #Properly cut the sound when the user presses CTLR+C | |
| buzzer_ch.pulse_width_percent(0) #Properly cut the sound when the user presses CTRL+C |
There was a problem hiding this comment.
You're right, there was indeed a typo, I fixed it.
|
|
||
|
|
||
| except KeyboardInterrupt: | ||
| buzzer_ch.pulse_width_percent(0) #Properly cut the sound when the user presses CTLR+C |
There was a problem hiding this comment.
Inline comment spacing here will be flagged by Ruff/pycodestyle (E261/E262): inline comments should be preceded by at least two spaces and start with # .
| buzzer_ch.pulse_width_percent(0) #Properly cut the sound when the user presses CTLR+C | |
| buzzer_ch.pulse_width_percent(0) # Properly cut the sound when the user presses CTLR+C |
There was a problem hiding this comment.
The issue has been fixed
nedseb
left a comment
There was a problem hiding this comment.
Salut Kaan, bienvenue dans le projet ! 🎉
Très bon premier jet - le code sembler fonctionner, la logique est correcte, et le commit message est parfaitement formaté. Voici quelques retours pour coller aux conventions du projet.
✅ Ce qui est bien
- Commit message parfait :
feat(vl53l1x): Add proximity alert example with buzzer.— bon type, bon scope, majuscule, point final. 👍 - Import
sleep_msdepuistime(pasutime) — conforme aux conventions - Constante
DISTANCE_THRESHOLD_MMbien nommée en haut du fichier - Fréquence variable selon la distance — c'est exactement le comportement "optionnel" décrit dans l'issue, bien joué
try/except KeyboardInterruptpour couper le buzzer — bonne pratique
📝 À corriger
1. Docstring manquante en début de fichier
Tous les exemples du projet commencent par une docstring qui décrit ce que fait le script. Regarde par exemple lib/mcp23009e/examples/reaction_timer.py ou lib/bme280/examples/weather_station.py. Ajoute quelque chose comme :
"""Proximity alert using VL53L1X distance sensor and buzzer.
Beeps the buzzer when an object is detected within 200 mm. The pitch
increases as the object gets closer.
"""2. Espaces après # dans les commentaires
Les commentaires doivent avoir un espace après le # (convention PEP 8, vérifié par ruff E265). Quelques endroits à corriger :
# Ligne 13
#buzzer initialisation → # Buzzer initialisation
# Ligne 24
#frequency ranging from... → # Frequency ranging from...
# Ligne 26
#security limits → # Clamp frequency to valid range
# Ligne 39
buzzer_ch.pulse_width_percent(0) #Properly cut...
→ buzzer_ch.pulse_width_percent(0) # Silence buzzer on exitNote : les commentaires inline (en fin de ligne) doivent être précédés de deux espaces minimum.
💡 Astuce :
ruff checkpasse ici parce que les exemples sont exclus de certaines règles. Mais les conventions de style s'appliquent quand même par cohérence avec le reste du projet.
3. Espacement autour des opérateurs
Ligne 25 :
freq = (1500- (distance * 5)) → freq = 1500 - distance * 5Les parenthèses extérieures sont aussi superflues ici.
4. Lignes vides en trop
Lignes 33-34 (double ligne vide avant sleep_ms) et lignes 36-37 (double ligne vide avant except). Une seule ligne vide suffit dans un bloc de code :
else:
buzzer_ch.pulse_width_percent(0)
sleep_ms(50)
except KeyboardInterrupt:5. Robustesse : try/finally au lieu de try/except
Copilot l'a aussi noté : si tof.read() lève une OSError (timeout capteur), le buzzer reste allumé car KeyboardInterrupt ne l'attrape pas. Utilise try/finally qui garantit l'extinction dans tous les cas :
try:
while True:
distance = tof.read()
...
except KeyboardInterrupt:
pass
finally:
buzzer_ch.pulse_width_percent(0)6. Typo
Ligne 39 : CTLR+C → CTRL+C
🔧 Comment corriger
- Fais les modifications sur ta branche
feat/vl53l1x-proximity-alert - Vérifie avec
ruff check lib/vl53l1x/examples/proximity_alert.py - Commite avec un message de fix, par exemple :
fix(vl53l1x): Address review comments on proximity alert example. - Pousse — la PR se mettra à jour automatiquement
Encore bravo pour cette première contribution, le code est fonctionnel et bien structuré. Les corrections sont surtout cosmétiques ! 🙂
6cf9790 to
55691fc
Compare
# [0.11.0](v0.10.0...v0.11.0) (2026-03-30) ### Features * **vl53l1x:** Add proximity alert example with buzzer. ([#337](#337)) ([01d1206](01d1206))
|
🎉 This PR is included in version 0.11.0 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
Summary
Add a
proximity_alert.pyexample for the VL53L1X sensor driver. This script triggers a PWM buzzer when the measured distance falls below a defined threshold (200 mm), with the pitch dynamically adapting to the object's proximity.Closes #325
Changes
lib/vl53l1x/examples/proximity_alert.pyfile.SPEAKERpin.try...except KeyboardInterruptblock to ensure the sound is properly turned off when the user stops the script with Ctrl+C.Checklist
ruff checkpassespython -m pytest tests/ -k mock -vpasses (no mock test broken)<scope>: <Description.>format