Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
# Using Python
AMYboard runs MicroPython and gives you a full Python REPL for controlling the synthesizer, reading inputs, and building instruments and effects in real time.
## Connecting to the REPL
### From your computer
Connect AMYboard via USB-C and use a serial terminal or `mpremote`:
```bash
pip install mpremote
mpremote resume
```
You'll see the MicroPython `>>>` prompt. You can type Python commands directly.
### From the web
Open [amyboard.com](https://amyboard.com) -- it includes a Python REPL running in the browser. You can test code online before deploying it to hardware.
## Playing sounds with AMY
The `amy` module gives you direct access to the synthesizer engine:
```python
import amy
# Clear any existing setup
amy.reset()
# Play a 440Hz sine wave
amy.send(osc=0, wave=amy.SINE, freq=440, vel=1)
# Stop the note
amy.send(osc=0, vel=0)
```
### Using patches
AMY has 256+ built-in patches: 0-127 are Juno-6 analog, 128-255 are DX7 FM, 256 is piano, and 257+ are PCM drum kits.
In general, a patch will use multiple oscs. `synth` is our abstraction to manage multiple oscs at the same time.
```python
# Load Juno-6 patch #10 on synth 1
amy.send(synth=1, patch=10, num_voices=4)
# Play middle C
amy.send(synth=1, note=60, vel=1)
# Send the note-off
amy.send(synth=1, note=60, vel=0)
# Switch to DX7 patch #5
amy.send(synth=1, patch=133) # 128 + 5
```
### Polyphony with synths
The `synth` objects provide the specified level of polyphony. They also connect directly to MIDI channels:
```python
# Set up a 4-voice polyphonic Juno patch on synth 1 (MIDI channel 1).
amy.send(synth=1, patch=0, num_voices=4)
# Play notes on individual voices
amy.send(synth=1, note=60, vel=1) # C
amy.send(synth=1, note=64, vel=1) # E
amy.send(synth=1, note=67, vel=1) # G
# Send vel=0 with no note number for "all notes off"
amy.send(synth=1, vel=0)
# You can also play polyphonically with a MIDI keyboard (connected via the "MIDI in" jack) or your computer (writing to the AMYboard USB MIDI gadget) sending notes on channel 1.
```
## The `amyboard` module
The `amyboard` module provides functions specific to the AMYboard hardware:
```python
import amyboard
# CV I/O
amyboard.cv_out(5.0, channel=0) # Output 5V on CV out 1
volts = amyboard.cv_in(channel=0) # Read CV in 1
# Rotary encoders. The defaults are for the Adafruit single-encoder https://www.adafruit.com/product/5880
print(amyboard.read_encoder())
amyboard.init_buttons()
print(amyboard.read_buttons())
# OLED display (if connected)
amyboard.init_display()
amyboard.display.fill(0)
amyboard.display_refresh()
# I2C
i2c = amyboard.get_i2c()
devices = i2c.scan()
print(devices)
# SD card
amyboard.mount_sd()
```
See the [Modular Synth Setup](modular.md) page for detailed CV and encoder examples.
## The sketch.py startup script
AMYboard automatically runs `sketch.py` from your current environment directory on boot. The top-level code runs once at startup, and if you define a `loop()` function it will be called repeatedly (~60ms interval). Use it to set up your default configuration:
```python
# /user/current/sketch.py
import amy, amyboard
# Set up my preferred patches
amy.send(synth=1, patch=0, num_voices=6) # Channel 1: Juno patch 0, 6-voice poly
amy.send(synth=10, num_voices=1, oscs_per_voice=1, synth_flags=3) # Channel 10: Drums (synth_flags magic).
# Set CV out 1 to 0V on startup
amyboard.cv_out(0.0, channel=0)
def loop():
pass
```
You can edit `sketch.py` directly on the hardware using the built-in text editor. Connect to your AMYboard with `screen` or `mpremote` (not `idf.py monitor`, which doesn't support full terminal emulation):
```bash
screen /dev/YOUR_SERIAL_PORT 115200
# or
mpremote connect /dev/YOUR_SERIAL_PORT
```
Then at the REPL:
```python
amyboard.edit('current/sketch.py')
```
This opens a full-screen text editor. On macOS, use **Esc then the key** instead of Ctrl (macOS terminals intercept many Ctrl sequences):
- **Esc, S** — Save
- **Esc, Q** — Quit
- **Esc, X** — Cut line
- **Esc, V** — Paste
- **Esc, Z** — Undo
- **Esc, F** — Find
On Linux or Windows terminals, Ctrl-S, Ctrl-Q, etc. work as usual. See the [pye documentation](https://github.com/robert-hh/Micropython-Editor) for the full list of key bindings.
You can also create or edit files from [AMYboard Online](https://amyboard.com/editor) and send them to hardware with **Send to AMYboard**.
## File management
### On hardware
```python
from upysh import *
ls # List files
cat('sketch.py') # Print file contents
cd('/user') # Change directory
pwd # Print working directory
```
### Transfer files with mpremote
```bash
# Copy a file from your computer to AMYboard
mpremote resume fs cp my_script.py :my_script.py
# Copy a file from AMYboard to your computer
mpremote resume fs cp :sketch.py sketch.py
# Edit a file on AMYboard with your local editor
mpremote resume edit sketch.py
```
## Working with MIDI in Python
```python
import tulip
# Set up a MIDI callback
def my_midi_callback(is_sysex):
if is_sysex:
return # Ignore sysex
message = tulip.midi_in()
while message is not None and len(message) > 0:
# message is a bytes object
status = message[0]
if status & 0xF0 == 0x90: # Note on
note = message[1]
vel = message[2]
print(f"Note on: {note} velocity: {vel}")
# Maybe there are more messages queued?
message = tulip.midi_in()
tulip.midi_callback(my_midi_callback)
```
## Example: simple arpeggiator
```python
import amy, time
notes = [60, 64, 67, 72] # C major arpeggio
amy.send(synth=1, patch=0, num_voices=4) # Juno patch 0
for _ in range(10):
for note in notes:
amy.send(synth=1, note=note, vel=1)
time.sleep(0.15)
amy.send(synth=1, note=note, vel=0)
time.sleep(0.05)
```
**Note:** Keyboard interrupt (Ctrl-C) doesn't work while the loop is running, so beware of getting stuck. Pressing the "Reset" button will start you over.
## Example: CV-controlled pitch
```python
import amy, amyboard, time
amy.reset()
amy.send(osc=0, wave=amy.SINE, vel=1) # Sine wave, on
for _ in range(100):
v = amyboard.cv_in(channel=0)
# Map -10..+10V to 100..1000 Hz
freq = 100 + ((v + 10) / 20.0) * 900
amy.send(osc=0, freq=freq)
time.sleep(0.05)
```
## More resources
- [AMY wire protocol reference](https://github.com/shorepine/amy/blob/main/docs/api.md) -- every parameter you can control
- [AMY synth architecture](https://github.com/shorepine/amy/blob/main/docs/synth.md) -- deep dive into oscillators, filters, modulation
- [MicroPython documentation](https://docs.micropython.org/en/latest/) -- general MicroPython reference
[Back to Getting Started](README.md)
36f3307bcThis file is pinned to the selected release. Download the original to open it in your design tool.