Skip to content

Commit 0070239

Browse files
committed
Update documentation, add thumbnail
1 parent 22eb69a commit 0070239

File tree

2 files changed

+46
-53
lines changed

2 files changed

+46
-53
lines changed

examples/led-matrix-painter/README.md

Lines changed: 46 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
# LED Matrix Painter
22

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.
44

55
![LED Matrix Painter Example](assets/docs_assets/thumbnail.png)
66

77
## Description
88

9-
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.
1010

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.
1212

1313
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.
2020

2121
## Bricks Used
2222

@@ -45,62 +45,59 @@ The LED Matrix Painter example uses the following Bricks:
4545
Open the App in your browser at `<UNO-Q-IP-ADDRESS>:7000`.
4646

4747
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.
5151

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.
5755

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.
6262

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.
6667

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.
6871

69-
The LED Matrix Painter consists of three main components working together:
7072

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
7474

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.
7676

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.
8382

8483
## Understanding the Code
8584

8685
### 🔧 Backend (`main.py` & `store.py`)
8786

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.
8988

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.
9190

9291
```python
9392
# store.py
94-
db = SQLStore(database_name="led_matrix_frames")
95-
9693
def save_frame(frame: AppFrame) -> int:
97-
# Logic to calculate position and insert record
94+
# Logic to calculate position, assign ID, and insert record
9895
record = frame.to_record()
9996
db.store("frames", record, create_table=False)
10097
# ...
10198
```
10299

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.
104101

105102
```python
106103
# main.py
@@ -110,23 +107,23 @@ def apply_frame_to_board(frame: AppFrame):
110107
Bridge.call("draw", frame_bytes)
111108
```
112109

113-
- **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.
114111

115112
```python
116113
# app_frame.py
117114
def to_c_string(self) -> str:
118115
c_type = "uint32_t"
119116
parts = [f"const {c_type} {self.name}[] = {{"]
120-
# ... formats array data as hex/int ...
117+
# ... logic to format array data ...
121118
parts.append("};")
122119
return "\n".join(parts)
123120
```
124121

125122
### 🔧 Arduino Component (`sketch.ino`)
126123

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.
128125

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.
130127

131128
```cpp
132129
void setup() {
@@ -138,23 +135,19 @@ void setup() {
138135
}
139136
```
140137

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 bytes and renders it directly.
142139

143140
```cpp
144141
void draw(std::vector<uint8_t> frame) {
145-
// Direct draw of received bytes
146142
matrix.draw(frame.data());
147143
}
148144
```
149145
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-
152146
### 🔧 Frontend (`app.js`)
153147
154-
The JavaScript frontend handles the interactive grid logic.
148+
The JavaScript frontend handles the UI logic and data synchronization.
155149
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.
158151
159152
```javascript
160153
// Unified persist: save to DB and update board together
347 KB
Loading

0 commit comments

Comments
 (0)