{"id":49074783,"url":"https://github.com/useblocks/demo_park_assist","last_synced_at":"2026-04-20T09:35:12.973Z","repository":{"id":350909611,"uuid":"1175292076","full_name":"useblocks/demo_park_assist","owner":"useblocks","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-12T18:11:25.000Z","size":41012,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-12T19:21:16.115Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/useblocks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-07T14:07:33.000Z","updated_at":"2026-04-12T18:11:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/useblocks/demo_park_assist","commit_stats":null,"previous_names":["useblocks/demo_park_assist"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/useblocks/demo_park_assist","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/useblocks%2Fdemo_park_assist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/useblocks%2Fdemo_park_assist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/useblocks%2Fdemo_park_assist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/useblocks%2Fdemo_park_assist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/useblocks","download_url":"https://codeload.github.com/useblocks/demo_park_assist/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/useblocks%2Fdemo_park_assist/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32041705,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T00:18:06.643Z","status":"online","status_checked_at":"2026-04-20T02:00:06.527Z","response_time":94,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-20T09:35:12.044Z","updated_at":"2026-04-20T09:35:12.925Z","avatar_url":"https://github.com/useblocks.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Demo: Park Assist\n\n\u003e **Repository:** [github.com/useblocks/demo_park_assist](https://github.com/useblocks/demo_park_assist)\n\n## Workshop\n\nThis repository was created for a workshop held at the Sphinx-Needs user group meeting.\n\nThe workshop combines **CircuitPython firmware** development with **sphinx-needs documentation** and **GitHub Copilot** assisted coding. Participants work through five progressive steps, each adding a new hardware feature — driven first by documentation (User Stories → Architecture → Test Cases) and then implemented with AI assistance.\n\n### Workshop Steps\n\n| Step | Make target | Starting state | Task | New feature |\n|------|-------------|---------------|------|-------------|\n| Setup | — | Empty board | Flash CircuitPython, deploy code | OLED shows distance |\n| 1 | `make step_start` | Display works | Explore docs \u0026 ubCode | — |\n| 2 | `make step_2` | Display works | Fix traceability, schemas, missing tests | Correct link graph |\n| 3 | `make step_3` | Display works | Add buzzer — docs first, then code | Continuous beep at \u003c 20 cm |\n| 4 | `make step_4` | Display + buzzer | Add LED strip | Red \u003c 20 cm, green otherwise |\n| 5 | `make step_5` | Display + buzzer + simple LED | Add zone logic | 4 proximity zones, dynamic LED count |\n| Bonus | `make step_bonus` | Step 5 complete | Install Pharaoh, analyse requirements with AI | MECE check, traceability trace, change impact analysis |\n\nEach step has a dedicated guide:\n- [WORKSHOP_1_START.md](WORKSHOP_1_START.md) – Setup \u0026 first exploration\n- [WORKSHOP_2_DOCS.md](WORKSHOP_2_DOCS.md) – Traceability, schemas \u0026 Copilot fixes\n- [WORKSHOP_3_BUZZER.md](WORKSHOP_3_BUZZER.md) – Buzzer: docs-first development\n- [WORKSHOP_4_LED.md](WORKSHOP_4_LED.md) – LED strip: docs-first development\n- [WORKSHOP_5_ZONES.md](WORKSHOP_5_ZONES.md) – Dynamic 4-zone proximity system\n- [WORKSHOP_BONUS_PHARAOH.md](WORKSHOP_BONUS_PHARAOH.md) – Pharaoh: AI-assisted requirements engineering\n\nUse `make step_\u003cN\u003e` to jump to any stage or recover a clean baseline.\nTargets can be combined — e.g. `make step_3 clean open` switches state, clears the build cache and opens the docs.\n\n### Needflow: step\\_start vs. step\\_5\n\nThe needflow diagram in `docs/index.rst` shows the end-to-end traceability graph connecting User Stories → Architecture → Implementation → Test Cases.\nBelow is the comparison between the starting state (distance only) and the fully completed project:\n\n**step\\_start** — only the distance feature is documented:\n\n![Needflow step\\_start](docs/_static/needflow_step_start.svg)\n\n**step\\_5** — all features (distance, buzzer, LED strip, zone logic) are fully traced:\n\n![Needflow step\\_5](docs/_static/needflow_step_5.svg)\n\n---\n\nThis README covers the technical setup and implementation details.\n\n## Introduction\n\n\nA CircuitPython demo that simulates a car park assist system. A VL53L1X Time-of-Flight sensor measures the distance to an obstacle; the result is visualised on a 1.3\" SH1106 OLED display and reflected on a NeoPixel LED strip (green → yellow → red as the obstacle gets closer). An audible buzzer warns at short range. Everything runs on an Adafruit Metro board with CircuitPython.\n\nThe project has two hardware setups:\n- **Setup 1 (Prototype):** Adafruit Metro M4 Express + VL53L1X ToF sensor\n- **Setup 2 (Workshop, ×5 units):** Adafruit Metro RP2040 + VL53L1X ToF sensor\n\n## Getting Started\n\n### 1. Prepare the hardware\n\nWire the board (I2C bus, GPIO) as described in [hw.md](hw.md):\n\n| Component | Interface | Pins |\n|-----------|-----------|------|\n| VL53L1X ToF sensor | I2C | `SCL` / `SDA` |\n| SH1106 OLED (128×64) | I2C | `SCL` / `SDA` |\n| NeoPixel strip (60 LEDs) | GPIO | `D2` |\n| Buzzer 1 | GPIO | `D5` |\n| Buzzer 2 | GPIO | `D6` |\n\nThe VL53L1X sensor and the OLED share the I2C bus at different addresses (sensor `0x29`, display `0x3C`).\n\n### 2. Flash CircuitPython\n\nIf CircuitPython is not yet running on the board:\n\n1. Connect the board via USB-C and **double-press** the reset button until the board appears as the `METROBOOT` drive.\n2. Copy the appropriate `.uf2` file from `util/` onto the drive:\n   - Metro M4 Express → `adafruit-circuitpython-metro_m4_express-en_US-10.1.3.uf2`\n3. The board reboots automatically and then appears as the `CIRCUITPY` drive.\n\n### 3. Install libraries\n\nThe required libraries are already bundled under `src/lib/` and just need to be copied to the board:\n\n```\nsrc/lib/ → CIRCUITPY/lib/\n```\n\nNewer versions can alternatively be taken from the included Adafruit bundle at `util/adafruit-circuitpython-bundle-10.x-mpy-*/lib/`.\n\n### 4. Deploy the code\n\nCopy all files from `src/` to the root of the `CIRCUITPY` drive:\n\n```\nsrc/boot.py  → CIRCUITPY/boot.py\nsrc/code.py  → CIRCUITPY/code.py\nsrc/lib/     → CIRCUITPY/lib/\n```\n\nThe board runs `boot.py` once at startup and then executes `code.py` automatically. Any save to `code.py` triggers an immediate restart.\n\n### 5. Open a serial monitor (optional)\n\nFor debug output, open a serial monitor (e.g. [Mu Editor](https://codewith.mu/) or `screen /dev/ttyACM0 115200`). REPL access is enabled via `boot.py`.\n\n---\n\n## Where to find information\n\n| Topic | File |\n|-------|------|\n| Hardware components, wiring, and pin assignments | [hw.md](hw.md) |\n| Software requirements, architecture, and open tasks | [sw.md](sw.md) |\n| Main application code | [src/code.py](src/code.py) |\n| Boot configuration | [src/boot.py](src/boot.py) |\n| CircuitPython libraries | [src/lib/](src/lib/) |\n| CircuitPython firmware and Adafruit bundle | [util/](util/) |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuseblocks%2Fdemo_park_assist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fuseblocks%2Fdemo_park_assist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fuseblocks%2Fdemo_park_assist/lists"}