Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
d24783d
feat: add Arduino Basics extension with matrix display functionality
dido18 Nov 17, 2025
6f5a5b2
feat: implement LED cycling and keyboard interaction in MatrixArgumen…
dido18 Nov 17, 2025
9aef202
feat: enhance LED interaction with mouse events and brightness contro…
dido18 Nov 17, 2025
2689e30
feat: refine mouse interaction for LED control in MatrixArgument
dido18 Nov 17, 2025
fa7ccd9
feat: update drawMatrix command to use heart pattern instead of gradient
dido18 Nov 17, 2025
2e394da
feat: add heart pattern to PATTERNS and refactor drawMatrix to use it
dido18 Nov 18, 2025
aede8c7
feat: update build process to use prg:build task and add prg:upload c…
dido18 Nov 18, 2025
01b3bc1
feat: update mouse interaction in MatrixArgument for LED control and …
dido18 Nov 19, 2025
af160e7
feat: add Arduino logo images and update icon URLs in ArduinoBasics e…
dido18 Nov 19, 2025
2562647
feat: remoe scratch folders
dido18 Nov 19, 2025
aa343f7
feat: remove internal flag from scratch:build task
dido18 Nov 19, 2025
903fedf
format
dido18 Nov 20, 2025
4182b04
feat: remove SCRATCH_EDITOR_VERSION and update Git configuration in s…
dido18 Nov 20, 2025
6329586
feat: update git configuration in scratch:init task for specific repo…
dido18 Nov 20, 2025
4d0b2fd
feat: replace git checkout with git switch in scratch:init task
dido18 Nov 20, 2025
f069280
feat: streamline scratch:init task by removing scratch:patch and ensu…
dido18 Nov 20, 2025
6dc9881
feat: add git remote command in scratch:init task and update app:star…
dido18 Nov 20, 2025
3444f52
feat: simplify scratch:init task by combining commands for better rea…
dido18 Nov 20, 2025
f7138c3
feat: update install task to source bashrc after pnpm installation
dido18 Nov 20, 2025
4fcd4ff
feat: add pnpm setup step in release workflow
dido18 Nov 20, 2025
836d53d
feat: update README and Taskfile for improved local development instr…
dido18 Nov 20, 2025
17d693d
feat: update README for testing instructions, remove unused object de…
dido18 Nov 20, 2025
0719779
feat: remove unused .filesToBundle.js from arduino_basics extension
dido18 Nov 20, 2025
d084d5b
refactor: simplify getArduinoBoardHost function and improve error han…
dido18 Nov 20, 2025
ad2f2c6
style: format getArduinoBoardHost function for improved readability
dido18 Nov 20, 2025
1d992a7
feat: add console log for connection status to Arduino UNO Q
dido18 Nov 20, 2025
956c81d
feat: add new arduino pattern to LED display and update drawMatrix co…
dido18 Nov 21, 2025
9f95733
fix: correct formatting in PATTERNS and remove debug log from drawMat…
dido18 Nov 21, 2025
c24a3c3
fix: update scratch-unoq image for improved clarity
dido18 Nov 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,15 @@ jobs:
- name: Install Task
uses: arduino/setup-task@v2

- name: Install dprint
- name: Install
run: |
task install

- name: use pnpm
uses: pnpm/action-setup@v4
with:
version: 10

- name: Fmt check
run: |
task fmt:check
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
scratch-editor
prg-raise-playground
build/
.bin/
.cache/
.cache/
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ NOTE: the `https` is needed by the `getUserMedia()` method for security reason.
## Local development

- `task scratch:init`
- `task scratch:local:start`
- `ŧask board:upload`
- change the `const DEFAULT_HOST =`<YOUR_IP|BOARD_NAME>`;` in the `scratch-arduino-extensions/packages/scratch-vm/src/extensions/ArduinoUnoQ.js`
- Open local scratch on http://localhost:8601/
- `task scratch:watch` watch scratch GUI files and reload on save
- Open the `http://localhost:8602?host=BOARD_IP`
- `task watch` watch files changes for both python and sketch, and upload the changes to the board and restart"

For testing on the board

- `ŧask app:build`
- `task board:app:upload`
40 changes: 17 additions & 23 deletions Taskfile.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
version: "3"
vars:
SCRATCH_EDITOR_VERSION: v12.0.1
DPRINT_VERSION: 0.48.0

tasks:
install:
cmds:
- curl -fsSL https://dprint.dev/install.sh | sh -s {{ .DPRINT_VERSION }}
- mkdir -p .bin && cp $HOME/.dprint/bin/dprint .bin/dprint # workaround for local install
- curl -fsSL https://get.pnpm.io/install.sh | sh - && source ~/.bashrc

fmt:
desc: Run format
Expand All @@ -20,21 +20,17 @@ tasks:
- ${PWD}/.bin/dprint check

scratch:init:
cmds:
- rm -rf scratch-editor
- git clone --depth 1 --branch {{ .SCRATCH_EDITOR_VERSION }} https://github.com/scratchfoundation/scratch-editor.git
- cd scratch-editor && npm install
- cd scratch-editor && npm run build
- task scratch:patch

scratch:patch:
cmds:
- cd scratch-editor/packages/scratch-gui && node ../../../scratch-arduino-extensions/scripts/patch-gui.js
- git config --global url."https://github.com/mitmedialab/prg-raise-playground-scratch-gui.git".insteadOf "git@github.com:mitmedialab/prg-raise-playground-scratch-gui.git"
- git config --global url."https://github.com/mitmedialab/prg-raise-playground-scratch-vm.git".insteadOf "git@github.com:mitmedialab/prg-raise-playground-scratch-vm.git"
- git clone --recurse-submodules https://github.com/mitmedialab/prg-raise-playground.git
- cd prg-raise-playground && git switch dev && pnpm install
# copy the extension to the rigth place
- ln -s $PWD/scratch-prg-extensions/extensions/src/arduino_basics $PWD/prg-raise-playground/extensions/src/arduino_basics
- cd scratch-prg-extensions/extensions/src/arduino_basics && pnpm install

scratch:local:start:
dir: scratch-editor
scratch:watch:
cmds:
- npm start --workspace @scratch/scratch-gui
- cd prg-raise-playground && pnpm dev -i arduino_basics &

app:build:
desc: "Copy app files (python, assets, app.yaml) to a build directory"
Expand All @@ -46,17 +42,12 @@ tasks:
- cp -r ./python build/scratch-arduino-app/python
- cp -r ./certs build/scratch-arduino-app/certs
- task scratch:build
- mkdir -p build/scratch-arduino-app/assets
- cp scratch-editor/packages/scratch-gui/build/index.html build/scratch-arduino-app/assets/index.html
- cp scratch-editor/packages/scratch-gui/build/gui.js build/scratch-arduino-app/assets/gui.js
- mkdir -p build/scratch-arduino-app/assets/static
- cp -r scratch-editor/packages/scratch-gui/build/static/blocks-media build/scratch-arduino-app/assets/static/blocks-media
- cp -r prg-raise-playground/build/. build/scratch-arduino-app/assets

scratch:build:
desc: "Build Scratch GUI files"
dir: scratch-editor/packages/scratch-gui
dir: prg-raise-playground
cmds:
- npm run build:dev --workspace @scratch/scratch-gui
- CI=true pnpm build

board:app:upload:
desc: "Upload zip file to Arduino board, unzip and deploy to /home/arduino/ArduinoApps"
Expand All @@ -73,6 +64,9 @@ tasks:
adb shell "cd /tmp && unzip -o $ZIP_BASENAME && mkdir -p /home/arduino/ArduinoApps && rm -rf /home/arduino/ArduinoApps/scratch-arduino-app && mv scratch-arduino-app /home/arduino/ArduinoApps/ && rm $ZIP_BASENAME"
echo "App deployed to /home/arduino/ArduinoApps/scratch-arduino-app"

app:start:
- adb shell "arduino-app-cli app start user:scratch-arduino-app"

app:zip:
desc: "Create a zip file with version (defaults to git commit hash)"
vars:
Expand All @@ -88,7 +82,7 @@ tasks:
- cd build && zip -r scratch-arduino-app-{{.APP_VERSION}}.zip scratch-arduino-app && cd ..

watch:
desc: "wath cfile changes for both python and sketch, and upload the changes to the board and restart"
desc: "watch files changes for both python and sketch, and upload the changes to the board and restart"
deps:
- python:watch
- sketch:watch
Expand Down
1 change: 0 additions & 1 deletion app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ ports:
- 7000
bricks:
- arduino:web_ui
- arduino:object_detection
icon: 🐱
Binary file modified doc/scratch-unoq.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
85 changes: 5 additions & 80 deletions python/main.py
Original file line number Diff line number Diff line change
@@ -1,91 +1,16 @@
from arduino.app_utils import App, Bridge
from arduino.app_bricks.web_ui import WebUI
from arduino.app_bricks.object_detection import ObjectDetection
import time
import base64

object_detection = ObjectDetection()


def on_matrix_draw(_, data):
print(f"Received frame to draw on matrix: {data}")
# from 5x5 to 8x13 matrix
frame_5x5 = data.get("frame")
row0 = "0" * 13
row1 = "0" * 4 + frame_5x5[0:5] + "0" * 4
row2 = "0" * 4 + frame_5x5[5:10] + "0" * 4
row3 = "0" * 4 + frame_5x5[10:15] + "0" * 4
row4 = "0" * 4 + frame_5x5[15:20] + "0" * 4
row5 = "0" * 4 + frame_5x5[20:25] + "0" * 4
row6 = "0" * 13
row7 = "0" * 13
frame_8x13 = row0 + row1 + row2 + row3 + row4 + row5 + row6 + row7
print(f"Transformed frame to draw on 8x13 matrix: {frame_8x13}")
Bridge.call("matrix_draw", frame_8x13)


def rgb_to_digital(value, threshold=128) -> bool:
"""Convert RGB value (0-255) to digital HIGH(1) or LOW(0)"""
return value >= threshold


def on_set_led_rgb(_, data):
led = data.get("led")
r = data.get("r")
g = data.get("g")
b = data.get("b")

# Convert RGB values (0-255) to digital HIGH/LOW
r_digital = rgb_to_digital(r)
g_digital = rgb_to_digital(g)
b_digital = rgb_to_digital(b)

print(
f"Setting LED {led} to color: RGB({r},{g},{b}) -> Digital({r_digital},{g_digital},{b_digital})"
)
Bridge.call("set_led_rgb", led, r_digital, g_digital, b_digital)


def on_detect_objects(client_id, data):
"""Callback function to handle object detection requests."""
try:
image_data = data.get("image")
confidence = data.get("confidence", 0.5)
if not image_data:
# TODO: implement the 'detection_error` in the extension
ui.send_message("detection_error", {"error": "No image data"})
return

start_time = time.time() * 1000
results = object_detection.detect(base64.b64decode(image_data), confidence=confidence)
diff = time.time() * 1000 - start_time

if results is None:
ui.send_message("detection_error", {"error": "No results returned"})
return

response = {
"detection": results.get("detection", []),
"detection_count": len(results.get("detection", [])) if results else 0,
"processing_time": f"{diff:.2f} ms",
}
ui.send_message("detection_result", response)

except Exception as e:
ui.send_message("detection_error", {"error": str(e)})


ui = WebUI(use_ssl=True)
ui.on_connect(lambda sid: (print(f"Client connected: {sid} "),))
ui.on_message("matrix_draw", on_matrix_draw)
ui.on_message("set_led_rgb", on_set_led_rgb)
ui.on_message("detect_objects", on_detect_objects)


def on_modulino_button_pressed(btn):
ui.send_message("modulino_buttons_pressed", {"btn": btn})
def on_matrix_draw(_, data):
frame = data.get("frame")
print(f"Frame to draw on 8x13 matrix: {frame}")
Bridge.call("matrix_draw", frame)


Bridge.provide("modulino_button_pressed", on_modulino_button_pressed)
ui.on_message("matrix_draw", on_matrix_draw)

App.run()

This file was deleted.

Loading