Skip to content

Commit 91c6fde

Browse files
committed
feat: implement ArduinoUnoQ class for enhanced LED and matrix control
1 parent 78b6ff9 commit 91c6fde

File tree

2 files changed

+112
-29
lines changed

2 files changed

+112
-29
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
const io = require("./socket.io.min.js");
2+
3+
class ArduinoUnoQ {
4+
constructor(host, port) {
5+
this.serverURL = `wss://${host}:${port}`;
6+
7+
this.io = io(this.serverURL, {
8+
path: "/socket.io",
9+
transports: ["polling", "websocket"],
10+
autoConnect: true,
11+
});
12+
this.isConnected = false;
13+
14+
this._setupConnectionHandlers();
15+
}
16+
17+
_setupConnectionHandlers() {
18+
this.io.on("connect", () => {
19+
this.isConnected = true;
20+
console.log(`Connected to Arduino UNO Q at ${this.serverURL}`);
21+
});
22+
23+
this.io.on("disconnect", (reason) => {
24+
this.isConnected = false;
25+
console.log(`Disconnected from Arduino UNO Q: ${reason}`);
26+
});
27+
28+
this.io.on("connect_error", (error) => {
29+
console.error(`Connection error:`, error.message);
30+
});
31+
32+
this.io.on("reconnect", (attemptNumber) => {
33+
console.log(`Reconnected to Arduino UNO Q after ${attemptNumber} attempts`);
34+
});
35+
}
36+
37+
connect() {
38+
if (!this.io.connected) {
39+
console.log("Attempting to connect to Arduino UNO Q...");
40+
this.io.connect();
41+
}
42+
}
43+
44+
disconnect() {
45+
if (this.io.connected) {
46+
console.log("Disconnecting from Arduino UNO Q...");
47+
this.io.disconnect();
48+
}
49+
}
50+
51+
// ===== LED CONTROL METHODS =====
52+
/**
53+
* Set RGB LED color
54+
* @param {string} led - LED identifier ("LED3" or "LED4")
55+
* @param {number} r - Red value (0-255)
56+
* @param {number} g - Green value (0-255)
57+
* @param {number} b - Blue value (0-255)
58+
*/
59+
setLedRGB(led, r, g, b) {
60+
this.io.emit("set_led_rgb", {
61+
led: led,
62+
r: Math.max(0, Math.min(255, r)),
63+
g: Math.max(0, Math.min(255, g)),
64+
b: Math.max(0, Math.min(255, b)),
65+
});
66+
console.log(`Setting ${led} to RGB(${r}, ${g}, ${b})`);
67+
}
68+
69+
/**
70+
* Turn off LED
71+
* @param {string} led - LED identifier ("LED3" or "LED4")
72+
*/
73+
turnOffLed(led) {
74+
this.setLedRGB(led, 0, 0, 0);
75+
}
76+
77+
// ===== MATRIX CONTROL METHODS =====
78+
79+
/**
80+
* Draw frame on LED matrix
81+
* @param {string} frame - 25-character string representing 5x5 matrix (0s and 1s)
82+
*/
83+
matrixDraw(frame) {
84+
if (typeof frame !== "string" || frame.length !== 25) {
85+
console.error("Invalid frame format. Expected 25-character string of 0s and 1s");
86+
return;
87+
}
88+
// Validate frame contains only 0s and 1s
89+
if (!/^[01]+$/.test(frame)) {
90+
console.error("Frame must contain only 0s and 1s");
91+
return;
92+
}
93+
94+
this.io.emit("matrix_draw", { frame: frame });
95+
console.log(`Drawing matrix frame: ${frame}`);
96+
}
97+
98+
matrixClear() {
99+
const clearFrame = "0".repeat(25);
100+
this.matrixDraw(clearFrame);
101+
}
102+
}
103+
104+
module.exports = ArduinoUnoQ;

scratch-arduino-extensions/packages/scratch-vm/src/extensions/arduino_basics/index.js

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,18 @@
1-
// const formatMessage = require('../../../../../../scratch-editor/node_modules/format-message');
21
const BlockType = require("../../../../../../scratch-editor/packages/scratch-vm/src/extension-support/block-type");
32
const ArgumentType = require(
43
"../../../../../../scratch-editor/packages/scratch-vm/src/extension-support/argument-type",
54
);
6-
const io = require("../socket.io.min.js");
5+
const ArduinoUnoQ = require("../ArduinoUnoQ");
76

8-
/**
9-
* Url of icon to be displayed at the left edge of each extension block.
10-
* @type {string}
11-
*/
12-
// eslint-disable-next-line max-len
7+
// TODO: add icons
138
const iconURI = "";
14-
15-
/**
16-
* Url of icon to be displayed in the toolbox menu for the extension category.
17-
* @type {string}
18-
*/
19-
// eslint-disable-next-line max-len
209
const menuIconURI = "";
2110

22-
const wsServerURL = `${window.location.protocol}//${window.location.hostname}:7000`;
23-
2411
class ArduinoBasics {
2512
constructor(runtime) {
2613
this.runtime = runtime;
27-
28-
this.io = io(wsServerURL, {
29-
path: "/socket.io",
30-
transports: ["polling", "websocket"],
31-
autoConnect: true,
32-
});
14+
this.unoq = new ArduinoUnoQ("192.168.1.39", 7000);
15+
this.unoq.connect();
3316
}
3417
}
3518

@@ -88,27 +71,23 @@ ArduinoBasics.prototype.getInfo = function() {
8871
};
8972

9073
ArduinoBasics.prototype.matrixDraw = function(args) {
91-
console.log(`Drawing frame on matrix: ${args}`);
92-
this.io.emit("matrix_draw", { frame: args.FRAME });
74+
this.unoq.matrixDraw(args.FRAME);
9375
};
9476

9577
ArduinoBasics.prototype.matrixClear = function() {
96-
console.log("Clearing matrix");
97-
this.io.emit("matrix_draw", { frame: "0000000000000000000000000" });
78+
this.unoq.matrixClear();
9879
};
9980

10081
ArduinoBasics.prototype.setLed3 = function(args) {
10182
const hexColor = args.HEX;
10283
const rgb = this.hexToRgb(hexColor);
103-
console.log(`Setting led 3 to: r:${rgb.r}, g:${rgb.g}, b:${rgb.b} (HEX: ${hexColor})`);
104-
this.io.emit("set_led_rgb", { led: "LED3", r: rgb.r, g: rgb.g, b: rgb.b });
84+
this.unoq.setLedRGB("LED3", rgb.r, rgb.g, rgb.b);
10585
};
10686

10787
ArduinoBasics.prototype.setLed4 = function(args) {
10888
const hexColor = args.HEX;
10989
const rgb = this.hexToRgb(hexColor);
110-
console.log(`Setting led 4 to: r:${rgb.r}, g:${rgb.g}, b:${rgb.b} (HEX: ${hexColor})`);
111-
this.io.emit("set_led_rgb", { led: "LED4", r: rgb.r, g: rgb.g, b: rgb.b });
90+
this.unoq.setLedRGB("LED4", rgb.r, rgb.g, rgb.b);
11291
};
11392

11493
ArduinoBasics.prototype.hexToRgb = function(hex) {

0 commit comments

Comments
 (0)