You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: examples/led-matrix-painter/README.md
+46-53Lines changed: 46 additions & 53 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,22 +1,22 @@
1
1
# LED Matrix Painter
2
2
3
-
The **LED Matrix Painter** example transforms your Arduino UNO Q into a design tool for the built-in LED Matrix. It features a web-based pixel editor that allows you to draw frames, create animations, and export the results as ready-to-use C++ code.
3
+
The **LED Matrix Painter** example provides a web-based interface to draw, animate, and control the built-in LED Matrix of the Arduino UNO Q in real-time. It features a pixel editor with 8-bit brightness control, database storage for your designs, and a code generator to export your frames as ready-to-use C++ code.
This App provides a complete workflow for designing LED matrix visuals. It uses the `web_ui` Brick to host a graphical editor where you can draw pixels with 8 levels of brightness. Changes are reflected instantly on the UNO Q's physical matrix.
9
+
This App allows you to design visuals for the 8x13 LED matrix directly from your browser. It uses the `web_ui` Brick to host a graphical editor where you can paint individual pixels, adjust their brightness, and apply transformations like flipping or rotating. Every change you make in the browser is immediately reflected on the physical board.
10
10
11
-
The application uses the `dbstorage_sqlstore` Brick to persist your designs in a database, allowing you to save multiple frames, reorder them via drag-and-drop, and organize them into animations. Finally, the "Export .h" feature generates the exact C++ code needed to use your designs in standalone Arduino sketches.
11
+
The application uses the `dbstorage_sqlstore` Brick to automatically save your work in a local database. You can create multiple frames, organize them into animations, and use the "Code panel" to see the generated C++ code in real-time.
12
12
13
13
Key features include:
14
-
-**Real-time Preview:** Drawing on the web interface updates the UNO Q matrix instantly.
15
-
-**8-bit Grayscale:** Support for 8 brightness levels per pixel (0-7 in the editor, mapped to 0-255).
16
-
-**Frame Management:**Create, delete, and reorder frames using a persistent database.
17
-
-**Transform Tools:**Quickly invert, rotate, or flip your designs.
18
-
-**Animation Mode:** Sequence frames to create and preview animations on the board.
19
-
-**Code Generation:**Export frames or animations as `uint32_t` arrays compatible with the `Arduino_LED_Matrix` library.
14
+
-**Real-time Control:** Drawing on the web grid updates the UNO Q matrix instantly.
15
+
-**8-bit Grayscale:** Support for 8 brightness levels per pixel (0-7).
16
+
-**Persistent Storage:**Frames are automatically saved to a database, allowing you to build complex animations over time.
17
+
-**Transformation Tools:**Invert, rotate, or flip designs with a single click.
18
+
-**Animation Mode:** Sequence frames to create animations and preview them on the board.
19
+
-**Code Export:**Generate `uint32_t` arrays compatible with the `Arduino_LED_Matrix` library for use in standalone sketches.
20
20
21
21
## Bricks Used
22
22
@@ -45,62 +45,59 @@ The LED Matrix Painter example uses the following Bricks:
45
45
Open the App in your browser at `<UNO-Q-IP-ADDRESS>:7000`.
46
46
47
47
3.**Draw Frames**
48
-
-**Click**a cell in the grid to toggle it on.
49
-
-**Click again** (or hover and wait) to open the brightness slider and adjust the intensity (0-7).
50
-
-The design appears immediately on the UNO Q LED Matrix.
48
+
-**Paint:**Click any cell in the central grid to turn it on.
49
+
-**Adjust Brightness:**Click an active cell again (or hover/wait) to open the floating slider and set the brightness level (0-7).
50
+
-**Preview:** Observe the UNO Q; the matrix updates instantly as you draw.
51
51
52
-
4.**Manage Your Session**
53
-
-**Auto-save:** Changes are automatically saved to the database as you draw.
54
-
-**Create:** Use the **+** button in the sidebar to create new empty frames.
55
-
-**Reorder:** Drag and drop frames in the list to change their sequence.
56
-
-**Transform:** Use the toolbar buttons to **Invert**, **Rotate 180°**, or **Flip** the current frame.
52
+
4.**Use the Design Tools**
53
+
-**Transform:** Use the **Tools** panel on the left to **Flip Vertically/Horizontally**, **Rotate 180°**, **Invert Matrix** (negative), or **Invert Draw** (brightness).
54
+
-**Clear:** Use the **Clear Frame** button above the grid to reset the canvas.
57
55
58
-
5.**Create Animations**
59
-
- Switch the radio button in the sidebar to **Animations**.
60
-
- Select multiple frames by clicking on them in the sidebar.
61
-
- Click **Play Animation** to see the sequence run on the UNO Q.
56
+
5.**Manage Frames (Bottom Panel)**
57
+
-**Auto-save:** Your work is saved to the database automatically.
58
+
-**Create:** Click the **+** button to add a new empty frame.
59
+
-**Edit Details:** Assign a **Name** and **Duration** (in milliseconds) for each frame using the inputs above the frame list.
60
+
-**Reorder:** Drag and drop frame thumbnails to change their sequence.
61
+
-**Load/Delete:** Use the **Load** and **Del** buttons on each thumbnail to switch between frames or remove them.
62
62
63
-
6.**Export Code**
64
-
- Click **Export .h** to download a C++ header file containing your designs.
65
-
- Copy the generated code (displayed in the right column) directly into your Arduino sketch.
63
+
6.**Create Animations**
64
+
- Switch the mode to **Animations** using the radio buttons in the bottom panel.
65
+
- Select multiple frames by clicking on their thumbnails (they will highlight).
66
+
- Click the **Play Animation** button below the grid to preview the sequence on the board.
66
67
67
-
## How it Works
68
+
7.**Export Code**
69
+
- Toggle the **Code panel** switch in the top right header to view the C++ code for the current frame or animation in real-time.
70
+
- Click the **Export .h** button to download a header file containing your selected designs, ready to be included in an Arduino sketch.
68
71
69
-
The LED Matrix Painter consists of three main components working together:
70
72
71
-
1.**Web Interface**: An interactive grid editor that captures user input and sends pixel data to the backend.
72
-
2.**Python Backend**: Manages the database, handles frame transformations, and communicates with the hardware.
73
-
3.**Arduino Sketch**: Receives raw data and renders it on the physical matrix.
73
+
## How it Works
74
74
75
-
**High-level data flow:**
75
+
The LED Matrix Painter relies on a synchronized data flow between the browser, the Python backend, and the hardware.
76
76
77
-
```
78
-
Web Browser ──► HTTP API ──► Python Backend ──► Router Bridge ──► Arduino Sketch
79
-
│ │
80
-
▼ ▼
81
-
SQLite Database LED Matrix Display
82
-
```
77
+
1.**Web Interface**: The `app.js` script captures clicks on the grid. It debounces these events and sends the pixel data to the backend via the `/persist_frame` endpoint.
78
+
2.**Python Backend**:
79
+
***Persistence**: The `store.py` module uses `SQLStore` to save the frame data (pixels, duration, position) to a `frames` table in a SQLite database.
80
+
***Bridge**: The `main.py` script converts the frame into a raw byte array and calls `Bridge.call("draw", frame_bytes)`.
81
+
3.**Arduino Sketch**: The sketch receives the raw byte data and uses the `Arduino_LED_Matrix` library to render the grayscale image.
83
82
84
83
## Understanding the Code
85
84
86
85
### 🔧 Backend (`main.py` & `store.py`)
87
86
88
-
The Python backend acts as the controller, managing the API and database interactions.
87
+
The Python backend manages the application logic, database, and hardware communication.
89
88
90
-
-**Persistence**: The application uses `SQLStore` to manage a `frames` table. This allows frames to be loaded, reordered, and updated efficiently.
89
+
-**Database Management**: The `store.py` module handles all SQL operations. It ensures frames are stored persistently and retrieved in the correct order.
91
90
92
91
```python
93
92
# store.py
94
-
db = SQLStore(database_name="led_matrix_frames")
95
-
96
93
defsave_frame(frame: AppFrame) -> int:
97
-
# Logic to calculate position and insert record
94
+
# Logic to calculate position, assign ID, and insert record
98
95
record = frame.to_record()
99
96
db.store("frames", record, create_table=False)
100
97
# ...
101
98
```
102
99
103
-
-**Bridge Communication**: When a frame is loaded or edited, it is sent to the board. The `AppFrame` class handles the conversion of pixel data into the specific byte format required by the sketch.
100
+
-**Hardware Update**: The `apply_frame_to_board` function sends the visual data to the microcontroller.
-**Code Export**: The `AppFrame` class includes logic to generate C++ source code strings (`uint32_t` arrays), which are returned to the frontend for display.
110
+
-**Code Generation**: The `AppFrame` class generates the C++ code displayed in the UI. It formats the internal array data into `uint32_t` hex values.
114
111
115
112
```python
116
113
# app_frame.py
117
114
defto_c_string(self) -> str:
118
115
c_type ="uint32_t"
119
116
parts = [f"const {c_type}{self.name}[] = {{"]
120
-
# ... formats array data as hex/int ...
117
+
# ... logic to format array data ...
121
118
parts.append("};")
122
119
return"\n".join(parts)
123
120
```
124
121
125
122
### 🔧 Arduino Component (`sketch.ino`)
126
123
127
-
The sketch initializes the matrix and registers Bridge functions to receive data from Python.
124
+
The sketch is designed to be a passive renderer, accepting commands from the Python backend.
128
125
129
-
-**Matrix Configuration**: The matrix is configured to accept 8-bit values, allowing for smooth gradients (0-255) rather than just on/off.
126
+
-**Grayscale Setup**: The matrix is initialized with 8-bit grayscale support to allow for varying brightness levels.
130
127
131
128
```cpp
132
129
voidsetup() {
@@ -138,23 +135,19 @@ void setup() {
138
135
}
139
136
```
140
137
141
-
-**Drawing Frames**: The `draw`function receives a vector of bytes, which represents the frame data, and passes it to the matrix driver.
138
+
-**Drawing**: The `draw`provider accepts a vector of bytesand renders it directly.
142
139
143
140
```cpp
144
141
voiddraw(std::vector<uint8_t> frame) {
145
-
// Direct draw of received bytes
146
142
matrix.draw(frame.data());
147
143
}
148
144
```
149
145
150
-
- **Playing Animations**: The `play_animation` function receives a stream of bytes representing multiple frames and durations. It reconstructs them into `uint32_t` arrays (the native format for the matrix library) and plays the sequence.
151
-
152
146
### 🔧 Frontend (`app.js`)
153
147
154
-
The JavaScript frontend handles the interactive grid logic.
148
+
The JavaScript frontend handles the UI logic and data synchronization.
155
149
156
-
- **Brightness Control**: It supports multi-level brightness by managing a dataset attribute `data-b` on each cell.
157
-
- **Auto-Persist**: To ensure a smooth user experience, changes are debounced and automatically sent to the backend via `schedulePersist()`, which updates both the database and the physical board simultaneously.
150
+
- **Auto-Persist**: To provide a responsive experience, changes are saved automatically after a short delay (debounce), updating both the database and the board simultaneously.
158
151
159
152
```javascript
160
153
// Unified persist: save to DB and update board together
0 commit comments