From a21de41fd51acf07da15ba0a7fd2ae3bce645497 Mon Sep 17 00:00:00 2001 From: dido18 Date: Tue, 28 Oct 2025 23:10:46 +0100 Subject: [PATCH 1/5] feat: add LED control functionality and update documentation --- README.md | 8 +-- python/main.py | 11 +++- .../src/extensions/arduino_basics/index.js | 51 ++++++++++++++++++- sketch/sketch.ino | 15 +++++- 4 files changed, 78 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 1bbe913..be5acaf 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Scratch for Arduino Uno Q +# Scratch for Arduino Uno Q ## Installation @@ -12,6 +12,8 @@ curl -sSL https://raw.githubusercontent.com/dido18/scratch-arduino-app/main/inst ### Local development - `task scratch:init` +- `task scratch:patch` - `task scratch:local:start` -- change the `const wsServerURL = `:7000`;` in the `index.js` -- Open local scratch on http://localhost:8601/ \ No newline at end of file +- change the `const wsServerURL = `:7000`;` in the `index.js` +- Open local scratch on http://localhost:8601/ +- `ŧask board:upload` diff --git a/python/main.py b/python/main.py index 795e8ac..5cbaa91 100644 --- a/python/main.py +++ b/python/main.py @@ -26,11 +26,20 @@ def on_matrix_draw(_, data): print(f"Transformed frame to draw on 8x13 matrix: {frame_8x13}") Bridge.call("matrix_draw", frame_8x13) +def on_set_led_rgb(_, data): + led = data.get("led") + r = data.get("r") + g = data.get("g") + b = data.get("b") + print(f"Setting LED {led} to color: {r} {g} {b} ") + Bridge.call("set_led_rgb", led, r, g, b) + ui.on_message("matrix_draw", on_matrix_draw) +ui.on_message("set_led_rgb", on_set_led_rgb) def on_modulino_button_pressed(btn): ui.send_message('modulino_buttons_pressed', {"btn": btn}) Bridge.provide("modulino_button_pressed", on_modulino_button_pressed) -App.run() \ No newline at end of file +App.run() diff --git a/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js b/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js index c3085fd..567cc31 100644 --- a/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js +++ b/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js @@ -17,7 +17,10 @@ const iconURI = ''; // eslint-disable-next-line max-len const menuIconURI = '' -const wsServerURL = `${window.location.protocol}//${window.location.hostname}:7000`; +// 'http://http://10.72.240.39:7000' + +// const wsServerURL = `${window.location.protocol}//${window.location.hostname}:7000`; +const wsServerURL = `ws://192.168.1.39:7000`; class ArduinoBasics { constructor(runtime) { @@ -49,6 +52,30 @@ ArduinoBasics.prototype.getInfo = function () { defaultValue: '0101010101100010101000100' } } + }, + { + opcode: 'setLed3', + blockType: BlockType.COMMAND, + text: 'set LED 3 to [HEX]', + func: 'setLed3', + arguments: { + HEX: { + type: ArgumentType.COLOR, + defaultValue: '#ff0000' + } + } + }, + { + opcode: 'setLed4', + blockType: BlockType.COMMAND, + text: 'set LED 4 to [HEX]', + func: 'setLed4', + arguments: { + HEX: { + type: ArgumentType.COLOR, + defaultValue: '#ff0000' + } + } } ] }; @@ -59,4 +86,26 @@ ArduinoBasics.prototype.matrixDraw = function (args) { this.io.emit("matrix_draw", { frame: args.FRAME }); }; +ArduinoBasics.prototype.setLed3 = function (args) { + const hexColor = args.HEX; + const rgb = this.hexToRgb(hexColor); + console.log(`Setting led 3 to: r:${rgb.r}, g:${rgb.g}, b:${rgb.b} (HEX: ${hexColor})`); + this.io.emit("set_led_rgb", {led: "LED3", r: rgb.r, g: rgb.g,b: rgb.b}); +}; + +ArduinoBasics.prototype.setLed4 = function (args) { + const hexColor = args.HEX; + const rgb = this.hexToRgb(hexColor); + console.log(`Setting led 4 to: r:${rgb.r}, g:${rgb.g}, b:${rgb.b} (HEX: ${hexColor})`); + this.io.emit("set_led_rgb", {led: "LED4", r: rgb.r, g: rgb.g,b: rgb.b}); +}; + +ArduinoBasics.prototype.hexToRgb = function (hex) { + hex = hex.replace('#', ''); + const r = parseInt(hex.substring(0, 2), 16); + const g = parseInt(hex.substring(2, 4), 16); + const b = parseInt(hex.substring(4, 6), 16); + return { r, g, b }; +}; + module.exports = ArduinoBasics; diff --git a/sketch/sketch.ino b/sketch/sketch.ino index cafb647..96661ba 100644 --- a/sketch/sketch.ino +++ b/sketch/sketch.ino @@ -10,9 +10,10 @@ void setup() { Bridge.begin(); Modulino.begin(Wire1); // show led indication if buttons cannot be initilized - buttons.begin(); + buttons.begin(); buttons.setLeds(true, true, true); Bridge.provide("matrix_draw", matrix_draw); + Bridge.provide("set_led_rgb", set_led_rgb); } void loop() { @@ -47,4 +48,14 @@ void matrix_draw(String frame){ matrix.draw(shades); } - +void set_led_rgb(String pin, uint8_t r, uint8_t g, uint8_t b) { + if (pin == "LED3") { + analogWrite(LED_BUILTIN, r); + analogWrite(LED_BUILTIN + 1, g); + analogWrite(LED_BUILTIN + 2, b); + } else if (pin == "LED4") { + analogWrite(LED_BUILTIN + 3, r); + analogWrite(LED_BUILTIN + 4, g); + analogWrite(LED_BUILTIN + 5, b); + } +} From cc4271f3e06fa55ae36cfa0490876338f23d131b Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 29 Oct 2025 00:06:19 +0100 Subject: [PATCH 2/5] feat: implement RGB to digital conversion for LED control and enhance setup process --- python/main.py | 15 +++++++++++++-- sketch/sketch.ino | 26 ++++++++++++++++++++------ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/python/main.py b/python/main.py index 5cbaa91..5ac2d6b 100644 --- a/python/main.py +++ b/python/main.py @@ -26,18 +26,29 @@ def on_matrix_draw(_, data): 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") - print(f"Setting LED {led} to color: {r} {g} {b} ") - Bridge.call("set_led_rgb", led, r, g, 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) ui.on_message("matrix_draw", on_matrix_draw) ui.on_message("set_led_rgb", on_set_led_rgb) def on_modulino_button_pressed(btn): + print("Modulino button pressed:", btn) ui.send_message('modulino_buttons_pressed', {"btn": btn}) Bridge.provide("modulino_button_pressed", on_modulino_button_pressed) diff --git a/sketch/sketch.ino b/sketch/sketch.ino index 96661ba..a191a9e 100644 --- a/sketch/sketch.ino +++ b/sketch/sketch.ino @@ -11,6 +11,20 @@ void setup() { Modulino.begin(Wire1); // show led indication if buttons cannot be initilized buttons.begin(); + pinMode(LED_BUILTIN, OUTPUT); + pinMode(LED_BUILTIN + 1, OUTPUT); + pinMode(LED_BUILTIN + 2, OUTPUT); + pinMode(LED_BUILTIN + 3, OUTPUT); + pinMode(LED_BUILTIN + 4, OUTPUT); + pinMode(LED_BUILTIN + 5, OUTPUT); + + digitalWrite(LED_BUILTIN, HIGH); + digitalWrite(LED_BUILTIN + 1, HIGH); + digitalWrite(LED_BUILTIN + 2, HIGH); + digitalWrite(LED_BUILTIN + 3, HIGH); + digitalWrite(LED_BUILTIN + 4, HIGH); + digitalWrite(LED_BUILTIN + 5, HIGH); + buttons.setLeds(true, true, true); Bridge.provide("matrix_draw", matrix_draw); Bridge.provide("set_led_rgb", set_led_rgb); @@ -50,12 +64,12 @@ void matrix_draw(String frame){ void set_led_rgb(String pin, uint8_t r, uint8_t g, uint8_t b) { if (pin == "LED3") { - analogWrite(LED_BUILTIN, r); - analogWrite(LED_BUILTIN + 1, g); - analogWrite(LED_BUILTIN + 2, b); + digitalWrite(LED_BUILTIN, r ? LOW : HIGH ); + digitalWrite(LED_BUILTIN + 1, g ? LOW : HIGH ); + digitalWrite(LED_BUILTIN + 2, b ? LOW: HIGH ); } else if (pin == "LED4") { - analogWrite(LED_BUILTIN + 3, r); - analogWrite(LED_BUILTIN + 4, g); - analogWrite(LED_BUILTIN + 5, b); + digitalWrite(LED_BUILTIN + 3, r ? LOW : HIGH ); + digitalWrite(LED_BUILTIN + 4, g ? LOW : HIGH ); + digitalWrite(LED_BUILTIN + 5, b ? LOW : HIGH ); } } From a226f74a81f356b2f5e3b908df20772024391859 Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 29 Oct 2025 00:09:48 +0100 Subject: [PATCH 3/5] refactor: remove debug print statement from modulino button handler --- python/main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/python/main.py b/python/main.py index 5ac2d6b..554091d 100644 --- a/python/main.py +++ b/python/main.py @@ -48,7 +48,6 @@ def on_set_led_rgb(_, data): ui.on_message("set_led_rgb", on_set_led_rgb) def on_modulino_button_pressed(btn): - print("Modulino button pressed:", btn) ui.send_message('modulino_buttons_pressed', {"btn": btn}) Bridge.provide("modulino_button_pressed", on_modulino_button_pressed) From 29026861d3fc624506de5395145b7562c4edd2a6 Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 29 Oct 2025 00:11:00 +0100 Subject: [PATCH 4/5] fix: update WebSocket server URL to use dynamic protocol and hostname --- .../scratch-vm/src/extensions/arduino_basics/index.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js b/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js index 567cc31..b324606 100644 --- a/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js +++ b/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js @@ -17,10 +17,7 @@ const iconURI = ''; // eslint-disable-next-line max-len const menuIconURI = '' -// 'http://http://10.72.240.39:7000' - -// const wsServerURL = `${window.location.protocol}//${window.location.hostname}:7000`; -const wsServerURL = `ws://192.168.1.39:7000`; +const wsServerURL = `${window.location.protocol}//${window.location.hostname}:7000`; class ArduinoBasics { constructor(runtime) { From 18a43d3e84b82646dd43f7237a1776548733bac1 Mon Sep 17 00:00:00 2001 From: dido18 Date: Wed, 29 Oct 2025 00:14:03 +0100 Subject: [PATCH 5/5] fix: update default HEX color value from red to blue in ArduinoBasics extension --- README.md | 5 ++--- .../scratch-vm/src/extensions/arduino_basics/index.js | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index be5acaf..190978a 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,7 @@ curl -sSL https://raw.githubusercontent.com/dido18/scratch-arduino-app/main/inst ### Local development - `task scratch:init` -- `task scratch:patch` - `task scratch:local:start` -- change the `const wsServerURL = `:7000`;` in the `index.js` -- Open local scratch on http://localhost:8601/ - `ŧask board:upload` +- change the `const wsServerURL = `ws://:7000`;` in the `index.js` +- Open local scratch on http://localhost:8601/ diff --git a/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js b/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js index b324606..b2e6376 100644 --- a/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js +++ b/scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js @@ -70,7 +70,7 @@ ArduinoBasics.prototype.getInfo = function () { arguments: { HEX: { type: ArgumentType.COLOR, - defaultValue: '#ff0000' + defaultValue: '#0000ff' } } }