Skip to content

Commit 2704f1f

Browse files
mirkokurtdsammaruga
authored andcommitted
Add Theremin, Vibration detection and Object Hunting examples
1 parent 6d2c39b commit 2704f1f

File tree

24 files changed

+328
-998
lines changed

24 files changed

+328
-998
lines changed

examples/object-hunting/app.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name: Object Hunting
22
icon: 🔍
33
description: Detect a list of object to win the game
4+
45
bricks:
56
- arduino:video_object_detection
67
- arduino:web_ui

examples/object-hunting/assets/app.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: Copyright (C) ARDUINO SRL (http://www.arduino.cc)
1+
// SPDX-FileCopyrightText: Copyright (C) 2025 ARDUINO SA <http://www.arduino.cc>
22
//
33
// SPDX-License-Identifier: MPL-2.0
44

examples/object-hunting/assets/fonts/fonts.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: Copyright (C) ARDUINO SRL (http://www.arduino.cc)
2+
* SPDX-FileCopyrightText: Copyright (C) 2025 ARDUINO SA <http://www.arduino.cc>
33
*
44
* SPDX-License-Identifier: MPL-2.0
55
*/
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
SPDX-FileCopyrightText: Copyright (C) ARDUINO SRL (http://www.arduino.cc)
1+
SPDX-FileCopyrightText: Copyright (C) 2025 ARDUINO SA <http://www.arduino.cc>
22

33
SPDX-License-Identifier: MPL-2.0

examples/object-hunting/assets/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
SPDX-FileCopyrightText: Copyright (C) ARDUINO SRL (http://www.arduino.cc)
2+
SPDX-FileCopyrightText: Copyright (C) 2025 ARDUINO SA <http://www.arduino.cc>
33
44
SPDX-License-Identifier: MPL-2.0
55
-->

examples/object-hunting/assets/style.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: Copyright (C) ARDUINO SRL (http://www.arduino.cc)
2+
* SPDX-FileCopyrightText: Copyright (C) 2025 ARDUINO SA <http://www.arduino.cc>
33
*
44
* SPDX-License-Identifier: MPL-2.0
55
*/

examples/object-hunting/python/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: Copyright (C) ARDUINO SRL (http://www.arduino.cc)
1+
# SPDX-FileCopyrightText: Copyright (C) 2025 ARDUINO SA <http://www.arduino.cc>
22
#
33
# SPDX-License-Identifier: MPL-2.0
44

examples/theremin/README.md

Lines changed: 85 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,166 +1,146 @@
11
# Theremin Simulator
22

3-
The **Theremin Simulator** example lets you create and control a virtual theremin instrument using an interactive web interface, producing synthesized audio output through a connected **USB** audio device with low latency.
3+
The **Theremin Simulator** example lets you create and control a virtual theremin instrument using an interactive web interface, producing synthesized audio output through a connected **USB** audio device with minimal latency.
44

5-
**Note:** This example requires to be run using **Network Mode** or **Single-Board Computer (SBC)**, since it requires a **USB-C® hub** and a **USB speaker**.
5+
> **Note**: This example must be run in **[Network Mode](learn/network-mode)** or **[SBC Mode](learn/single-board-computer)**, since it requires a **USB-C® hub** and a **USB speaker**.
66
77
![Theremin Simulator](assets/docs_assets/theremin-simulator.png)
88

9-
This App creates a virtual instrument that generates real-time audio by creating sine waves at varying frequencies and amplitudes based on user input. The workflow involves receiving mouse or touch coordinates from the frontend and updating a **Wave Generator** Brick, which handles the audio synthesis, smoothing, and streaming to the **USB device** automatically.
9+
This example generates real-time audio by creating sine waves at varying frequencies and amplitudes based on user input from the web interface. The workflow involves receiving mouse/touch coordinates from the frontend, calculating the corresponding frequency and amplitude, generating audio blocks using a sine wave generator, and playing them through a **USB** audio device with minimal latency.
1010

11-
**Key features include:**
12-
13-
- Real-time audio synthesis with low latency
14-
- Interactive web interface for pitch and volume control
15-
- Visual waveform display showing frequency and amplitude
16-
- Automatic envelope smoothing (attack, release, glide) for natural sound
17-
- Support for USB speakers and wireless USB audio receivers
1811

1912
## Bricks Used
2013

21-
The theremin simulator example uses the following Bricks:
22-
2314
- `web_ui`: Brick that provides the web interface and a WebSocket channel for real-time control of the theremin.
24-
- `wave_generator`: Brick that handles audio synthesis, envelope control (smoothing), and streaming to the USB audio device.
15+
2516

2617
## Hardware and Software Requirements
2718

2819
### Hardware
2920

30-
- Arduino UNO Q (x1)
21+
- [Arduino UNO Q](https://store.arduino.cc/products/uno-q) (x1)
3122
- **USB-C® hub with external power (x1)**
32-
- A power supply (5 V, 3 A) for the USB hub (x1)
23+
- A power supply (5 V, 3 A) for the USB hub adapter with external power (x1)
3324
- A **USB audio device** (choose one):
34-
- **USB speaker** (cabled)
35-
- **USB wireless speaker receiver/dongle** (2.4 GHz, non-Bluetooth)
25+
- **USB speaker** (cabled) (x1) ✅ *supported*
26+
- **USB wireless speaker receiver/dongle** (2.4 GHz) (x1) ✅ *supported*
27+
- **USB‑C → 3.5 mm audio connector** + headphones/speakers (x1) ⚠️ *not tested* (may work)
3628
- A **power supply** (5 V, 3 A) for the USB hub (e.g. a phone charger)
3729

30+
> **Not supported:** **HDMI audio and Bluetooth® Speakers** output is not supported by this App.
31+
3832
### Software
3933

4034
- Arduino App Lab
4135

42-
**Important:** A **USB-C® hub is mandatory** for this example. The UNO Q's single port must be used for the hub, which provides the necessary connections for both the power supply and the USB audio device. Consequently, this example must be run in **[Network Mode](learn/network-mode)** or **[SBC Mode](learn/single-board-computer)**.
36+
**Note:** A **USB-C® hub is mandatory** for this example. The UNO Q's single port must be used for the hub, which provides the necessary connections for both the power supply and the USB audio device. Consequently, this example must be run in **[Network Mode](learn/network-mode)** or **[SBC Mode](learn/single-board-computer)**.
4337

44-
**Note:** **HDMI audio** and **Bluetooth® Speakers** are not supported by this App.
4538

4639
## How to Use the Example
4740

48-
1. **Hardware Setup**
49-
Connect your **USB audio device** (e.g., USB speaker, wireless USB receiver) to a powered **USB-C® hub** attached to the UNO Q. Ensure the hub is powered.
50-
51-
2. **Run the App**
52-
Launch the App from Arduino App Lab. Wait until the App has launched completely.
53-
54-
3. **Access the Web Interface**
55-
Open the App in your browser at `<UNO-Q-IP-ADDRESS>:7000` (typically `192.168.x.x`).
56-
57-
4. **Turn on Power**
58-
Locate the orange control panel at the bottom of the interface. Click the **POWER** switch to toggle it **ON** (the small LED indicator will light up).
59-
*Note: No sound will be produced if this switch is OFF.*
41+
1. Connect your **USB audio device** (e.g., USB speaker, wireless USB receiver, or USB‑C→3.5 mm dongle) to a powered **USB-C® hub** attached to the UNO Q.
42+
![hardware-setup](assets/docs_assets/hardware-setup.png)
6043

61-
5. **Set Master Volume**
62-
Use the **+** and **-** buttons near the **VOL** indicator to adjust the master volume. This sets the maximum output limit for the application.
44+
2. Launch the App by clicking the **Play** button in the top-right corner. Wait until the App has launched.
45+
![Launching an App](assets/docs_assets/launch-app-theremin.png)
46+
3. Open the App in your browser at `<UNO-Q-IP-ADDRESS>:7000` *(typically 192.168.x.x, e.g., http://192.168.1.11:7000)*.
47+
4. Click and drag your mouse (or use touch) on the interactive area to play:
48+
- **Horizontal movement (X-axis)** controls the **pitch** (frequency).
49+
- **Vertical movement (Y-axis)** controls the **volume** (amplitude).
6350

64-
6. **Play the Instrument**
65-
Drag your mouse (or use your finger on a touchscreen) inside the large gray background area:
66-
- **Horizontal (Left ↔ Right):** Controls **Pitch**. Moving right increases the frequency (higher notes).
67-
- **Vertical (Bottom ↕ Top):** Controls **Note Volume**. Moving up increases the amplitude (louder). Moving to the very bottom silences the note.
68-
69-
7. **Visualize Audio**
70-
Observe the screen in the center of the panel, which visualizes the real-time sine wave, frequency (Hz), and amplitude data. You can also toggle the **GRID** switch to visually reference specific pitch intervals.
7151

7252
## How it Works
7353

74-
The application relies on a continuous data pipeline between the web interface and the audio synthesis engine.
54+
The application creates a real-time audio synthesizer controlled by a web interface. User interactions on the webpage are sent to the Python backend via a WebSocket. The backend then calculates the audio parameters, generates a sine wave, and streams the audio data directly to the connected **USB** audio device.
7555

76-
**High-level data flow:**
56+
- **User Interaction**: The frontend captures mouse or touch coordinates within a designated "play area".
57+
- **Real-time Communication**: These coordinates are sent to the Python backend in real-time using the `web_ui` Brick's WebSocket channel.
58+
- **Audio Synthesis**: The backend maps the X-coordinate to **frequency** and the Y-coordinate to **amplitude**. It uses a sine wave generator to create small blocks of audio data based on these parameters.
59+
- **Audio Output**: The generated audio blocks are continuously streamed to the **USB** audio device, creating a smooth and responsive sound.
7760

61+
High-level data flow:
7862
```
79-
Web Browser Interaction ──► WebSocket ──► Python Backend
80-
▲ │
81-
│ ▼
82-
(Visual Updates) (Glide & Synthesis)
83-
│ │
84-
└─ WebSocket ◄── State ◄── Sine Wave Generation
85-
86-
87-
USB Audio Output
63+
Web Browser Interaction → WebSocket → Python Backend → Sine Wave Generation → USB Audio Device Output
8864
```
8965

90-
- **User Interaction**: The frontend captures mouse/touch coordinates and sends them to the backend via the `web_ui` Brick's WebSocket channel.
91-
- **Audio Synthesis**: The `wave_generator` Brick runs in the background. It takes the target frequency and amplitude and applies a **glide algorithm** to transition smoothly between notes.
92-
- **Envelope Smoothing**: The Brick automatically handles attack, release, and glide to ensure the audio changes sound natural and analog-like, rather than robotic.
93-
- **Audio Output**: The Brick streams the generated sine wave directly to the **USB** audio device.
9466

9567
## Understanding the Code
9668

9769
### 🔧 Backend (`main.py`)
9870

99-
The Python script simplifies audio logic by utilizing the `WaveGenerator` Brick.
100-
101-
- **Initialization**: Configures the audio engine with specific parameters (sine wave, 16kHz sample rate) and envelope settings (attack, release, glide).
102-
- **Frequency Calculation**: Maps the X-axis input (0.0 to 1.0) exponentially to a frequency range of 20 Hz to ~8000 Hz.
103-
- **Event Handling**: Listens for `theremin:move` events from the frontend to update frequency and amplitude.
71+
The Python code manages the web server, handles real-time user input, and performs all audio generation and playback.
10472

105-
```python
106-
wave_gen = WaveGenerator(sample_rate=16000, ...)
73+
- `ui = WebUI()` – Initializes the web server that serves the HTML interface and handles WebSocket communication.
74+
- `speaker = Speaker(...)` – Initializes the connection to the USB audio device. This will raise an error if no compatible device is found.
75+
- `sine_gen = SineGenerator(...)` – Creates an instance of the audio synthesis engine.
76+
- `ui.on_message('theremin:move', on_move)` – Registers a handler that fires whenever the frontend sends new coordinates. This function updates the target frequency and amplitude.
77+
- `theremin_producer_loop()` – Core audio engine. Runs continuously, generating ~**30 ms** blocks of audio based on the current frequency and amplitude, and streams them to the audio device for playback. This non-blocking, continuous stream ensures smooth audio without cracks or pops.
10778

108-
def _freq_from_x(x):
109-
# Exponential mapping from 20Hz up to Nyquist frequency
110-
return 20.0 * ((SAMPLE_RATE / 2.0 / 20.0) ** x)
111-
112-
def on_move(sid, data):
113-
# Calculate target frequency and amplitude based on coordinates
114-
freq = _freq_from_x(data.get("x"))
115-
amp = max(0.0, min(1.0, 1.0 - float(data.get("y"))))
116-
117-
wave_gen.set_frequency(freq)
118-
wave_gen.set_amplitude(amp)
119-
```
79+
### 💻 Frontend (`main.js`)
12080

121-
### 🔧 Frontend (`main.js`)
81+
The web interface provides the interactive play area and controls for the user.
12282

123-
The web interface handles user input and visualization.
83+
- **Socket.IO connection** to the backend to send and receive data in real time.
84+
- **Event listeners** capture `mousedown`, `mousemove`, `mouseup` (and touch equivalents) to track user interaction in the play area.
85+
- `socket.emit('theremin:move', { x, y })` – Sends normalized (0.0–1.0) X and Y coordinates to the backend; emissions are **throttled to ~80 Hz (≈12 ms)** to avoid overload.
86+
- `socket.on('theremin:state', ...)` – Receives state updates from the backend (like the calculated frequency and amplitude) and updates the values displayed on the webpage.
87+
- `socket.emit('theremin:set_volume', { volume })` – Sends a **0.0–1.0** master volume value and updates a progress bar in the UI.
88+
- `socket.emit('theremin:power', { on })` – Toggles synth power (**On/Off**). After turning **On**, move/tap in the play area to resume sound.
12489

125-
- **Input Capture**: Event listeners track `mousemove`, `touchmove`, and `touchstart` to capture user interaction.
126-
- **Throttling**: Emissions to the backend are throttled to approximately 80 Hz (~12 ms) to prevent network overload while maintaining responsiveness.
127-
- **Visual Feedback**: The canvas draws a real-time sine wave animation based on the amplitude and frequency data received back from the server.
12890

129-
```javascript
130-
// Send normalized coordinates (0.0 - 1.0) to backend
131-
socket.emit('theremin:move', { x, y });
132-
133-
// Receive state for visualization
134-
socket.on('theremin:state', (data) => {
135-
updateStateDisplay(data.freq, data.amp);
136-
});
137-
```
13891

13992
## Troubleshooting
14093

14194
### "No USB speaker found" error
142-
If the application fails to start and you see an error regarding the speaker:
143-
**Fix:**
144-
1. Ensure a **powered USB-C® hub** is connected to the UNO Q.
145-
2. Verify the **USB audio device** is connected to the hub and turned on.
95+
96+
If the application fails to start and you see the following error in the logs, it means the required audio hardware is missing or not detected.
97+
```
98+
arduino.app_peripherals.speaker.SpeakerException: No USB speaker found.
99+
```
100+
**Fix:**
101+
1. Make sure a **powered USB-C® hub** is connected to the UNO Q and its **5 V / 3 A** power supply is plugged in.
102+
2. Verify the **USB audio device** (USB speaker, wireless USB receiver, or USB-C→3.5 mm dongle) is **connected to the hub** and, if it has a switch, **turned on**.
146103
3. Restart the application.
147104

148105
### No Sound Output
149-
If the interface works but there is no sound:
150-
- **Power Button:** Ensure the **POWER** switch in the web UI is **ON**.
151-
- **Pointer Position:** Ensure you are interacting with the upper part of the play area (bottom is zero volume).
152-
- **Volume Controls:** Increase the volume using the **+** button in the UI.
153-
- **Hardware Volume:** Check the physical volume control on your speaker.
154-
- **Audio Device:** Remember that **HDMI audio** and **Bluetooth® speakers** are not supported.
106+
107+
- **Power Button:** Make sure the button in the web UI shows **On**.
108+
- **Volume Slider:** Increase the volume slider in the web UI.
109+
- **Pointer Position:** Move your mouse/finger toward the top of the play area (the bottom corresponds to zero volume).
110+
- **Speaker/Headphone Volume:** Check the physical volume control and mute status on your speaker or headphones.
111+
- **Output Path:** Remember that **HDMI audio** and **Bluetooth® speakers** are not supported; use a **USB** audio device.
155112

156113
### Choppy or Crackling Audio
157-
- **CPU Load:** Close other applications running on the Arduino UNO Q.
158-
- **Power Supply:** Ensure you are using a stable 5 V, 3 A power supply for the USB-C® hub. Insufficient power often degrades USB audio performance.
114+
115+
- **CPU Load:** Close any other applications running on the Arduino UNO Q that may be consuming significant resources.
116+
- **Power Supply:** Ensure you are using a stable, adequate power supply (5 V, 3 A) for the USB-C® hub, as insufficient power can affect USB peripheral performance.
117+
118+
159119

160120
## Technical Details
161121

162-
- **Sample rate:** 16,000 Hz
163-
- **Audio format:** 32-bit float, little-endian
164-
- **Latency:** ~30 ms block duration
165-
- **Frequency range:** ~20 Hz to ~8,000 Hz
166-
- **Envelope:** Attack (0.01s), Release (0.03s), Glide (0.02s)
122+
- **Sample rate:** 16,000 Hz
123+
- **Audio format:** 32-bit float, little-endian
124+
- **Block duration:** ~30 ms (≈480 samples per block)
125+
- **Frequency range:** ~20 Hz to ~8,000 Hz
126+
- **Update rate:** Frontend throttled to ~80 Hz (≈12 ms minimum between updates)
127+
128+
129+
130+
## Compatibility Notes
131+
132+
- **Works with:**
133+
- **USB speakers** (cabled)
134+
- **USB wireless speaker receivers** (2.4 GHz dongles)
135+
- **Untested (may work):**
136+
- **USB‑C → 3.5 mm audio dongles** feeding analog speakers/headphones
137+
- **Not supported:**
138+
- **HDMI audio** output
139+
- **Bluetooth® speakers**
140+
141+
142+
## License
143+
144+
This example is licensed under the Mozilla Public License 2.0 (MPL-2.0).
145+
146+
Copyright (C) 2025 ARDUINO SA <http://www.arduino.cc>

examples/theremin/app.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,3 @@ icon: 🎼
33
description: A simple theremin simulator that generates audio based on user input.
44
bricks:
55
- arduino:web_ui
6-
- arduino:wave_generator
117 KB
Loading

0 commit comments

Comments
 (0)