### Druid Firmware Update Output Example Source: https://github.com/monome/docs/blob/gh-pages/crow/update.md This is an example of the output you can expect when running the 'druid firmware' command, showing the process of checking for updates, downloading, and installing the new firmware. ```text Checking for updates... >> git version 4.0.1 >> local version: 2.0.0 Downloading new version: https://github.com/monome/crow/releases/download/v4.0.1/crow.dfu Crow bootloader enabled. File: crow.dfu b'DfuSe' v1, image size: 304605, targets: 1 b'Target' 0, alt setting: 0, name: "ST...", size: 304320, elements: 1 0, address: 0x08020000, size: 304312 usb: 0483:df11, device: 0x0000, dfu: 0x011a, b'UFD', 16, 0x03737ae6 Writing memory... 0x08020000 304312 [=========================] 100% Exiting DFU... Update complete. ``` -------------------------------- ### Install and Start serialosc on macOS Source: https://github.com/monome/docs/blob/gh-pages/serialosc/setup.md Installs serialosc using Homebrew and starts it as a service. Ensure Homebrew is installed first. ```bash brew install serialosc ``` ```bash brew services start serialosc ``` -------------------------------- ### Clock Example Source: https://github.com/monome/docs/blob/gh-pages/norns/reference/clock.md An example demonstrating how to use `clock.run` to start a coroutine that loops and prints a message. ```APIDOC ## Clock Example ### Description An example demonstrating how to use `clock.run` to start a coroutine that loops and prints a message. ### Code ```lua -- start a clock which calls function [loop] function init() clock.run(loop, "so true") -- arguments can be passed end -- this function loops forever, printing at 1 second intervals function loop(print_this) while true do print(print_this) clock.sleep(1) end end ``` ``` -------------------------------- ### fileselect example Source: https://github.com/monome/docs/blob/gh-pages/norns/reference/lib/fileselect.md An example demonstrating how to use the fileselect library to select an audio file. ```lua fileselect = require('fileselect') selected_file = 'none' selected_file_path = 'none' function callback(file_path) -- this defines the callback function that is used in fileselect if file_path ~= 'cancel' then -- if a file is selected in fileselect -- the following are some common string functions to help organize the path that is returned from fileselect local split_at = string.match(file_path, "^.*()/\) selected_file_path = string.sub(file_path, 9, split_at) selected_file_path = util.trim_string_to_width(selected_file_path, 128) selected_file = string.sub(file_path, split_at + 1) print(selected_file_path) print(selected_file) end redraw() end function redraw() screen.clear() screen.level(15) screen.move(0,10) screen.text('selected file path:') screen.move(0,20) screen.text(selected_file_path) screen.move(0,30) screen.text('selected file:') screen.move(0,40) screen.text(selected_file) screen.move(0,60) screen.text('press K3 to select file') screen.update() end function key(n,z) if n == 3 and z == 1 then fileselect.enter(_path.audio, callback, "audio") -- runs fileselect.enter; `_path.audio` in this example is the folder that will open when fileselect is run end end ``` -------------------------------- ### Lattice:start Source: https://github.com/monome/docs/blob/gh-pages/norns/api/modules/lib.lattice.html Starts the lattice running. ```APIDOC ## Lattice:start ### Description Start running the lattice. ### Method Lattice:start () ### Endpoint Not applicable (SDK method) ``` -------------------------------- ### Compile and Install libmonome Source: https://github.com/monome/docs/blob/gh-pages/grid/studies/rpi/rpi.txt Downloads, compiles, and installs the libmonome library from source. ```bash wget https://github.com/monome/libmonome/releases/download/v1.4.0/libmonome-1.4.0.tar.bz2 tar xjvf lib cd libmonome ./waf configure ./waf sudo ./waf install ``` -------------------------------- ### start Source: https://github.com/monome/docs/blob/gh-pages/norns/api/modules/lib.lfo.html Starts the LFO. Can optionally take a parameter to define the starting point. ```APIDOC ## start ### Description Starts the LFO. ### Parameters * `from_parameter` (various) - Optional parameter to define the starting point of the LFO. ``` -------------------------------- ### start Source: https://github.com/monome/docs/blob/gh-pages/norns/api/modules/lib.reflection.html Starts the pattern playback transport. ```APIDOC ## start (beat_sync, offset) ### Description Starts the pattern playback transport. ### Parameters: * **beat_sync** (number, optional) - Sync playback start to beat value. * **offset** (number, optional) - If set, this value will be added to the beat_sync value. ### Returns: None ``` -------------------------------- ### Run Seamstress Example Source: https://github.com/monome/docs/blob/gh-pages/grid/studies/seamstress/index.md Navigate to the downloaded code examples directory and run a specific script using the seamstress executable. ```bash cd grid-studies-seamstress/files seamstress grid-studies-1 ``` -------------------------------- ### Install monome-grid Library Source: https://github.com/monome/docs/blob/gh-pages/grid/studies/nodejs/index.md Install the monome-grid library as a project dependency. ```bash $ npm install --save monome-grid ``` -------------------------------- ### Install Prerequisites on Windows Source: https://github.com/monome/docs/blob/gh-pages/crow/druid.md Before installing monome-druid on Windows, install the necessary prerequisites using pip. ```powershell python -m pip install pyserial asyncio prompt_toolkit ``` -------------------------------- ### Install Bonjour Print Services on Windows Source: https://github.com/monome/docs/blob/gh-pages/serialosc/troubleshooting.md Install Bonjour Print Services if you are using Max/MSP and do not have iTunes installed. Max/MSP uses Bonjour for OSC and networked device communication. ```html Bonjour Print Services ``` -------------------------------- ### Install easymidi Library Source: https://github.com/monome/docs/blob/gh-pages/grid/studies/nodejs/index.md Install the easymidi library, which is often used for MIDI communication alongside monome devices. ```bash $ npm install --save easymidi ``` -------------------------------- ### Start Source: https://github.com/monome/docs/blob/gh-pages/teletype/manual/index.html Send a MIDI Clock Start message. ```APIDOC ## Start ### Description Send MIDI Clock Start message ### Method SEND ### Endpoint `I2M.START` ### Parameters None ### Request Example `I2M.START` ### Response None ``` -------------------------------- ### Install libudev Development Files Source: https://github.com/monome/docs/blob/gh-pages/grid/studies/rpi/rpi.txt Installs the libudev library, required for hardware event management. ```bash sudo apt-get install libudev-dev ``` -------------------------------- ### Install Script from GitHub URL via REPL Source: https://github.com/monome/docs/blob/gh-pages/norns/maiden.md Install scripts not present in the community catalog by providing their GitHub URL to the `;install` command in the REPL. Ensure you have a WiFi connection. ```lua ;install https://github.com/tehn/test-update ``` -------------------------------- ### Install and Activate diii CLI Source: https://github.com/monome/docs/blob/gh-pages/iii/diii-cli.md Steps to install the monome-diii package using uv and activate the virtual environment. ```bash mkdir ~\/diii cd ~\/diii uv venv source .venv\/bin\/activate uv pip install monome-diii ``` -------------------------------- ### System Command Example Source: https://github.com/monome/docs/wiki/norns-docs:-todo This is a system command example. Use with extreme caution as it can delete log files. ```bash sudo rm -rf /var/log/kern.log ``` -------------------------------- ### Compile and Install serialosc Source: https://github.com/monome/docs/blob/gh-pages/grid/studies/rpi/rpi.txt Downloads, compiles, and installs the serialosc daemon from source. ```bash cd ~ wget https://github.com/monome/serialosc/releases/download/v1.4/serialosc-1.4.tar.bz2 tar xjvf ser cd serialosc ./waf configure ./waf sudo ./waf install ``` -------------------------------- ### Install liblo Development Files Source: https://github.com/monome/docs/blob/gh-pages/grid/studies/rpi/rpi.txt Installs the liblo library, which is a dependency for some monome software. ```bash apt-get update apt-get install liblo-dev ``` -------------------------------- ### Install SerialOSC on Ubuntu Source: https://github.com/monome/docs/blob/gh-pages/serialosc/linux.md Use these commands to add the monome PPA, update package lists, and install the serialosc package. ```bash sudo add-apt-repository ppa:artfwo/monome sudo apt update sudo apt install serialosc ``` -------------------------------- ### Install Web-Druid Dependencies Source: https://github.com/monome/docs/blob/gh-pages/crow/druid.md Install the necessary Node.js dependencies for web-druid before serving it locally. ```bash npm install ``` -------------------------------- ### Serial Handler Example Source: https://github.com/monome/docs/blob/gh-pages/norns/api/modules/serial.html Example of how to add a serial device handler with matching, configuration, and event callbacks. ```APIDOC ## serial.add_handler ### Description Adds a handler for serial devices. The handler includes matching criteria, configuration logic, and callbacks for device lifecycle events. ### Parameters: * `id` (string or number): A unique identifier for the handler. * `match` (function): A function that takes device attributes and returns true if the device matches. * `configure` (function): A function that takes a terminal configuration table and returns a modified table. * `add` (function): A callback function executed when a device is added. * `remove` (function): A callback function executed when a device is removed. * `event` (function): A callback function executed when an event occurs on the device. ### Example: ```lua serial.add_handler({ id = "example_id", match = function(attrs) return ( (attrs["vendor"] == "FTDI") and (attrs["model"] == "FT232R") and (attrs["serial"] == "ABC123") and (attrs["interface"] == "00") ) end, configure = function(term) term.ispeed = term.ispeed | serial.speed.B115200 term.ospeed = term.ospeed | serial.speed.B115200 term.iflag = term.iflag | serial.iflag.INCLR term.oflag = term.oflag | serial.oflag.ONLCR term.cflag = term.cflag | serial.cflag.CS8 term.lflag = term.lflag & (~serial.lflag.ECHO) return term end, add = function(id, name, dev) print("saying hi...") serial.send(dev, "hello " .. name .. "!") end, remove = function(id) print("it's too late to say goodbye.") end, event = function(id, data) print(id .. " says:", data) end }) ``` ``` -------------------------------- ### Main Application Entry Point Source: https://github.com/monome/docs/blob/gh-pages/libmonome/tutorial.md Initializes the monome device, sets up event handlers, and runs the main application loop. Handles command-line arguments for the device path. ```c int main(int argc, char *argv[]) { monome_t *monome; double now, then; struct app_data *data; int y; if (argc < 2) { printf("Usage %s device_path\n", argv[0]); return 1; } signal(SIGINT, please_close); data = malloc(sizeof(struct app_data)); for (y = 0; y < 8; y++) { data->c.quadL[y] = 0; data->c.quadR[y] = 0; } ripple_stack_init(&data->rstack); if (!(monome = monome_open(argv[1], "8000"))) return -1; data->m = monome; data->please_draw = 0; data->please_update = 0; monome_led_all(monome, 0); monome_register_handler(monome, MONOME_BUTTON_DOWN, handle_press, data); now = then = now_sec(); while(is_running) { while(monome_event_handle_next(monome)); now = now_sec(); if ((now - then) > 0.08) { data->please_update = 1; data->please_draw = 1; then = now; } redraw(data); usleep(800); } printf("Closing!\n"); monome_led_all(monome, 0); monome_close(monome); free(data); return 0; } ``` -------------------------------- ### Connect to MIDI Port and Initialize Music Utilities Source: https://github.com/monome/docs/blob/gh-pages/grid/studies/seamstress/index.md Connects to the first virtual MIDI port and sets up music utility variables. It also initializes active notes tracking and prepares scale names for parameter options. Bangs the parameters to trigger initial scale building. ```lua -- NEW // -- we'll connect to virtual port 1, which is seamstress's MIDI device: m = midi.connect(1) -- for a more robust example of MIDI scaffolding, -- check out the 'hello_midi' example! active_notes = {} -- to keep track of 'note on' messages, for paired 'note off' -- build scales for quantized note selection: scale_names = {} for i = 1, #MU.SCALES do table.insert(scale_names, string.lower(MU.SCALES[i].name)) end params:add_control( "root_note", -- scripting ID "root note", -- UI name controlspec.new(0, 127, "lin", 1, 72, nil, 1 / 127), -- controlspec function(param) -- UI formatter return MU.note_num_to_name(param:get(), true) end ) params:set_action("root_note", function() build_scale() end) params:add_option("scale", "scale", scale_names, 5) params:set_action("scale", function() build_scale() end) -- important! since our script relies on the output of our parameter actions, -- we'll want to fire them off in the init: params:bang() -- // NEW ``` -------------------------------- ### Levels: Get/Set Loop Start Source: https://github.com/monome/docs/blob/gh-pages/teletype/manual/index.html Gets or sets the loop start (x). ```levels LV.L.ST ``` ```levels LV.L.ST x ``` -------------------------------- ### Manual Engine Loading Example Source: https://github.com/monome/docs/blob/gh-pages/norns/reference/engine.md Demonstrates how to manually load an engine and execute commands using the REPL in Maiden. ```APIDOC ## Manual Engine Loading via REPL ### Description This example shows how to interact with the engine module directly through the Maiden REPL for dynamic control and testing. ### Usage Execute these commands in the Maiden REPL: ```bash >> load_callback = function() print("engine has been loaded!") end >> engine.load("PolyPerc", load_callback) >> engine.release(2) >> engine.hz(300) >> engine.pan(-1); engine.hz(400) >> engine.cutoff(4500); engine.pan(0); engine.hz(150) >> engine.load("None", function() print("clearing engine") end) ``` ``` -------------------------------- ### Example ii Device Query and Event Handling Source: https://github.com/monome/docs/blob/gh-pages/crow/reference.md Shows how to set up an event handler for ii device responses and trigger a query. This example specifically listens for the 'ramp' parameter from a Just Friends device. ```lua -- example usage ii.jf.event = function(e, value) if e.name == 'ramp' then print('ramp is '..value) end end ii.jf.get 'ramp' -- will trigger the above .event function ii.jf.trigger(1, 1) -- sets just friends' 1st trigger to the on state ``` -------------------------------- ### Get/Set Working Pattern Start Location Source: https://github.com/monome/docs/blob/gh-pages/teletype/manual/index.html Use P.START to get or set the start index for the working pattern. The default start location is 0. ```script P.START P.START 2 ``` -------------------------------- ### Set up Blackfin Toolchain Path Source: https://github.com/monome/docs/blob/gh-pages/aleph/devdsp.md Add the Blackfin toolchain binaries to your system's PATH. This is necessary for compiling DSP modules. ```bash cd ~/Downloads su tar -xjvf blackfin-toolchain-elf-gcc-4.3-2014R1-RC2.x86_64.tar.bz2 export PATH=$PATH:/opt/uClinux/bfin-elf/bin ``` -------------------------------- ### Kria: Get/Set Loop Start Source: https://github.com/monome/docs/blob/gh-pages/teletype/manual/index.html Gets the loop start for track x, parameter y, or sets it to z. ```kria KR.L.ST x y ``` ```kria KR.L.ST x y z ``` -------------------------------- ### Get/Set Specific Pattern Start Location Source: https://github.com/monome/docs/blob/gh-pages/teletype/manual/index.html Use PN.START to get or set the start index for a specific pattern. ```script PN.START 0 PN.START 0 3 ``` -------------------------------- ### LV.L.ST Source: https://github.com/monome/docs/blob/gh-pages/teletype/manual/index.html Get or set the loop start point in the LV module. ```APIDOC ## LV.L.ST / LV.L.ST x ### Description Get or set the loop start point. ### Syntax `LV.L.ST` `LV.L.ST x` ### Parameters * **x** (number) - The loop start point to set. ``` -------------------------------- ### TO.TR.INIT x Source: https://github.com/monome/docs/blob/gh-pages/teletype/manual/index.html Initializes TR output x back to the default boot settings and behaviors. ```APIDOC ## TO.TR.INIT x ### Description Initializes TR output x back to the default boot settings and behaviors; neutralizes metronomes, dividers, pulse counters, etc. ### Method N/A (Teletype Command) ### Endpoint N/A ### Parameters #### Path Parameters - **x** (number) - Description: Output number to initialize. ### Request Example N/A ### Response N/A ``` -------------------------------- ### Initialize Node.js Project Source: https://github.com/monome/docs/blob/gh-pages/grid/studies/nodejs/index.md Initialize a new Node.js project by creating a package.json file. Press Enter to accept default values. ```bash $ npm init ``` -------------------------------- ### KR.L.ST Source: https://github.com/monome/docs/blob/gh-pages/teletype/manual/index.html Get or set the loop start point for a track in the KR module. ```APIDOC ## KR.L.ST x y / KR.L.ST x y z ### Description Get the loop start for track `x`, parameter `y`. Set the loop start for track `x` to `z`, with parameter `y`. ### Syntax `KR.L.ST x y` `KR.L.ST x y z` ### Parameters * **x** (number) - The track number. * **y** (number) - Parameter identifier. * **z** (number) - The value to set. ``` -------------------------------- ### Initialize and Control Grid LEDs Source: https://github.com/monome/docs/blob/gh-pages/grid/studies/nodejs/index.md A comprehensive example demonstrating grid initialization, LED array management, and continuous refresh. It sets up a 2D array to represent LED states and updates them at a high frequency. ```javascript const monomeGrid = require('monome-grid'); async function run() { let grid = await monomeGrid(); // optionally pass in grid identifier // initialize 2-dimensional led array let led = []; for (let y=0;y<8;y++) { led[y] = []; for (let x=0;x<16;x++) led[y][x] = 0; } // refresh leds with a pattern let refresh = function() { led[0][0] = 15; led[2][0] = 5; led[0][2] = 5; grid.refresh(led); } // call refresh() function 60 times per second setInterval(refresh, 1000 / 60); // set up key handler grid.key((x, y, s) => console.log(`key received: ${x}, ${y}, ${s}`)); } run(); ``` -------------------------------- ### Advanced LFO Control with :set and :get Source: https://github.com/monome/docs/blob/gh-pages/norns/reference/lib/lfo.md Demonstrates advanced LFO configuration using :set and :get methods for parameters like shape, min, max, depth, mode, period, and action callbacks. Includes example of starting/stopping the LFO and adjusting parameters via encoders. ```lua _lfos = require 'lfo' -- assign the library to a general variable engine.name = 'PolyPerc' s = require 'sequins' function init() hz_vals = s{400,600,200,350} sync_vals = s{1,1/3,1/2,1/6,2} clock.run(iter) screen_dirty = true -- establish an LFO variable for a specific purpose: cutoff_lfo = _lfos.new() cutoff_lfo:set('shape', 'sine') cutoff_lfo:set('min', 200) cutoff_lfo:set('max', 5000) cutoff_lfo:set('depth', 0.3) cutoff_lfo:set('mode', 'free') cutoff_lfo:set('period', 2) cutoff_lfo:set('action', function(scaled,raw) engine.cutoff(scaled) screen_dirty = true end) redraw_screen = metro.init(check_dirty,1/15,-1) redraw_screen:start() end function iter() while true do clock.sync(sync_vals()) hertz = hz_vals() engine.hz(hertz) cutoff_lfo:set('depth', math.random()) end end function check_dirty() if screen_dirty then redraw() screen_dirty = false end end function redraw() screen.clear() screen.level(15) screen.move(64,40) screen.font_size(20) screen.text_center(util.round(cutoff_lfo:get('scaled'),0.01)..'hz') screen.update() end -- press K3 to start/stop: function key(n,z) if n == 3 and z == 1 then if cutoff_lfo:get('enabled') == 1 then cutoff_lfo:stop() else cutoff_lfo:start() end end end -- turn E3 to adjust cutoff when LFO is inactive: function enc(n,d) if n == 3 and cutoff_lfo:get('enabled') == 0 then local current = cutoff_lfo:get('scaled') local change = util.clamp(current + d*100, cutoff_lfo:get('min'), cutoff_lfo:get('max')) cutoff_lfo:set('scaled', change) engine.cutoff(cutoff_lfo:get('scaled')) screen_dirty = true end end ``` -------------------------------- ### Example: Random Note Generation and Snapping (Lua) Source: https://github.com/monome/docs/blob/gh-pages/norns/reference/lib/musicutil.md Demonstrates generating random MIDI note numbers, snapping them to a predefined scale using musicutil.generate_scale_of_length, and playing the resulting frequencies. This example also shows how to display raw and snapped note values. ```lua MusicUtil = require("musicutil") engine.name = "PolyPerc" playing = false -- whether notes are playing function init() engine.release(2) build_scale() -- builds initial scale end function build_scale() notes_array = MusicUtil.generate_scale_of_length(60, "dorian", 16) -- builds quantization scale end function play_notes() while true do clock.sync(1/2) rnd = math.random(40,80) print("random: "..rnd) current_note_num = MusicUtil.snap_note_to_array(rnd,notes_array) -- snap the random number to the scale array print("snapped: "..current_note_num) engine.hz(MusicUtil.note_num_to_freq(current_note_num)) -- convert note number to freq and play current_note_name = MusicUtil.note_num_to_name(current_note_num,true) -- convert note number to name redraw() end end function stop_play() -- stops the coroutine playing the notes clock.cancel(play) playing = false redraw() end function key(n,z) if n == 2 and z == 1 then if not playing then play = clock.run(play_notes) -- starts the clock coroutine which plays a random note from the scale playing = true elseif playing then stop_play() end end end function redraw() screen.clear() screen.level(14) screen.move(64,32) if playing == true then screen.font_size(24) screen.text_center(current_note_name) -- display the name of the note that is playing screen.font_size(8) screen.move(128,50) screen.text_right("raw: "..rnd) screen.move(128,60) screen.text_right("snapped: "..current_note_num) else screen.font_size(8) screen.text_center("press k2 to play") end screen.update() end ``` -------------------------------- ### SuperCollider Error Example Source: https://github.com/monome/docs/blob/gh-pages/norns/maiden.md This output shows a common SuperCollider error related to duplicate engine classes. It helps identify conflicting installations of synth engines. ```log compiling class library... Found 738 primitives. Compiling directory '/usr/local/share/SuperCollider/SCClassLibrary' Compiling directory '/usr/local/share/SuperCollider/Extensions' Compiling directory '/home/we/.local/share/SuperCollider/Extensions' Compiling directory '/home/we/norns/sc/core' Compiling directory '/home/we/norns/sc/engines' Compiling directory '/home/we/dust' ERROR: duplicate Class found: 'Engine_PolyPerc' /home/we/norns/sc/engines/Engine_PolyPerc.sc /home/we/dust/code/other-stuff-i-installed/PolyPerc.sc ERROR: There is a discrepancy. numClassDeps 1517 gNumClasses 3032 ``` -------------------------------- ### Basic Transport Callbacks Source: https://github.com/monome/docs/blob/gh-pages/norns/clocks.md Define simple functions to execute when the transport starts and stops. This example sets up a basic engine and a pulse function that runs when the transport begins. ```lua engine.name = 'PolyPerc' function pulse() clock.sync(1/4) engine.hz(333) end function clock.transport.start() print("we begin") id = clock.run(pulse) end function clock.transport.stop() clock.cancel(id) end ``` -------------------------------- ### Serve Monome Docs Locally with Jekyll Source: https://github.com/monome/docs/blob/gh-pages/README.md Clone the repository, install Jekyll and Ruby dependencies, and then build and serve the documentation locally. Use the --baseurl '/docs' flag for correct routing. Access the site at http://localhost:4000/docs/. ```bash git clone https://github.com/monome/docs cd docs/ bundle jeckyll build bundle exec jekyll serve --baseurl '/docs' --watch --livereload ``` -------------------------------- ### run Source: https://github.com/monome/docs/blob/gh-pages/norns/api/modules/script.html Loads the engine and executes the script-specified initialization function, if present. ```APIDOC ## run () ### Description Loads the engine and executes the script-specified init function. ### Method N/A (Function call) ### Parameters None ``` -------------------------------- ### Systemd Unit for SerialOSC Source: https://github.com/monome/docs/blob/gh-pages/serialosc/linux.md Create this systemd unit file to automatically start the serialoscd service on user login when compiling from source. Ensure the ExecStart path matches your installation. ```systemd [Unit] Description=Starts serialoscd at system boot [Service] Type=simple ExecStart=/usr/local/bin/serialoscd ``` -------------------------------- ### Norns textentry Example Source: https://github.com/monome/docs/blob/gh-pages/norns/reference/lib/textentry.md Demonstrates how to use the textentry.enter function to get user input for both on-screen display and parameter modification. Includes a custom check function for input validation. ```lua textentry = require('textentry') my_string_1 = "replace me by pressing K3" my_string_2 = "replace me in params" function init() params:add_trigger('change_string_2', 'change string 2 here') params:set_action('change_string_2', function() textentry.enter(callback_2,my_string_2) end) end function callback_1(txt) if txt ~= nil and check(txt) ~= "too long" then my_string_1 = txt end redraw() end function callback_2(txt) if txt ~= nil then my_string_2 = txt end redraw() end function check(txt) if string.len(txt) > 10 then return "too long" else return ("remaining: "..10 - string.len(txt)) end end function redraw() screen.clear() screen.move(0,30) screen.text(my_string_1) screen.move(0,40) screen.text(my_string_2) screen.update() end function key(n,z) if n == 3 and z == 1 then local default_text = my_string_1 ~= "replace me by pressing K3" and my_string_1 or "" textentry.enter(callback_1,default_text,"enter 10 chars or less", check) end end ``` -------------------------------- ### Sequencer with Transport Synchronization Source: https://github.com/monome/docs/blob/gh-pages/norns/clocks.md A comprehensive example demonstrating a basic sequencer structure that synchronizes with the transport. It includes functions for starting, stopping, sequencing steps, and managing screen updates. ```lua -- define what should happen when the transport starts function clock.transport.start() step = 0 -- assign a variable to a coroutine allows it to be canceled later my_sequencer = clock.run(sequence) -- keep track of the transport state: transport_active = true screen_dirty = true end -- define what should happen when the transport stops function clock.transport.stop() clock.cancel(my_sequencer) transport_active = false end -- this function loops until canceled by clock.transport.stop() -- it advances the sequencer by one step every 1/16th note function sequence() if params:string("clock_source") ~= "midi" then clock.sync(4) -- wait until the "1" of a 4/4 count end while true do step = util.wrap(step + 1,1,16) if step == 1 then print(clock.get_beats()) end screen_dirty = true clock.sync(1/4) -- in 4/4, 1 beat is a quarter note, so sixteenths = 1/4 of a beat end end function init() -- clock.run doesn't always need to be pointed to external functions! -- here, we define a screen redraw coroutine inside of our clock.run: screen_redraw_clock = clock.run( function() while true do clock.sleep(1/30) -- 30 fps if screen_dirty == true then redraw() screen_dirty = false end end end ) step = 0 screen_dirty = true end function key(n,z) -- since MIDI and Link offer their own start/stop messages, -- we'll only need to manually start if using internal or crow clock sources: if params:string("clock_source") == "internal" or params:string("clock_source") == "crow" then if n == 3 and z == 1 then if transport_active then clock.transport.stop() else clock.transport.start() end screen_dirty = true end end end function redraw() screen.clear() for i = 1,16 do screen.level(step == i and 15 or 3) screen.move(10 + (i*5),30) screen.text("|") end if params:string("clock_source") == "internal" or params:string("clock_source") == "crow" then screen.move(20,50) screen.level(15) screen.text(transport_active and "K3 to stop" or "K3 to start") end screen.update() end ``` -------------------------------- ### Norns Grid Reference Example Source: https://github.com/monome/docs/blob/gh-pages/norns/reference/grid.md An example script demonstrating a step sequencer with 8 playheads, note playback, and interactive controls for column count, playback randomization, and LED intensity. ```lua -- // grid reference example \\ -- 8 playheads move across grid -- press a key to add a step -- -- K2: randomize the -- playback rate -- E2: clamp the column count -- E3: change LED intensity g = grid.connect() -- if no argument is provided, defaults to port 1 engine.name = 'PolyPerc' MU = require 'musicutil' function init() engine.release(0.2) engine.cutoff(1200) grid_connected = g.device~= nil and true or false -- ternary operator, eg. http://lua-users.org/wiki/TernaryOperator columns = grid_connected and g.device.cols or 16 -- keep track of device columns rows = grid_connected and g.device.rows or 8 -- keep track of device rows led_intensity = 15 -- scales LED intensity notes = {60,61,51,65,48,68,70,77} -- some notes to play playheads = {} -- table for playheads for i = 1,rows do -- for each row... playheads[i] = {} -- create a playhead! playheads[i].pos = 1 -- track the position playheads[i].rate = 1 -- start rate at 1 beat per step playheads[i].data = {} -- for 1's and 0's for j = 1,columns do playheads[i].data[j] = 0 -- start with 0's in every step end playheads[i].clock = clock.run( function() while true do clock.sync(playheads[i].rate) -- sync to playhead rate playheads[i].pos = util.wrap(playheads[i].pos+1,1,columns) -- advance playhead position if playheads[i].data[playheads[i].pos] == 1 then -- if data at this position equals 1... engine.hz(MU.note_num_to_freq(notes[i])) -- play note! end grid_dirty = true -- redraw grid! end end ) end ``` -------------------------------- ### Norns Script Example: bar2.lua with dofile Source: https://github.com/monome/docs/blob/gh-pages/norns/script-faq.md Demonstrates that `dofile` does not cache module state. Each call to `dofile('baz.lua')` starts with the module's initial state, unaffected by previous calls. ```lua local baz = dofile('baz.lua') print('bar2:baz initial value = ' .. baz.value) baz.value = baz.value + 2 ``` -------------------------------- ### Run Monome Docs with Docker Source: https://github.com/monome/docs/blob/gh-pages/README.md Clone the repository and use Docker Compose to start the documentation development server. Access the site at http://localhost:4000/docs/. ```bash git clone https://github.com/monome/docs cd docs/ docker compose up ``` -------------------------------- ### Norns Keyboard Code to Character Example Source: https://github.com/monome/docs/blob/gh-pages/norns/reference/keyboard.md Demonstrates converting key codes to characters, considering modifier key states. Use `keyboard.code_to_char` to get the character representation of a key press. ```lua -- keyboard.code_to_char(code) example local state = { kcode = { key = nil, value = nil, code_to_char = nil }, kchar = { ch = nil, } } function init() redraw() end function redraw() screen.clear() screen.move(0, 8) screen.text("Last calls to...") screen.move(0, 24) screen.text("keyboard.code(" .. stringify(state.kcode.key) .. ", " .. stringify(state.kcode.value) .. ")" ) screen.move(0, 32) screen.text(" code_to_char(...) = " .. stringify(state.kcode.code_to_char) ) screen.move(0, 48) screen.text("keyboard.char(" .. stringify(state.kchar.ch) .. ")" ) screen.update() end function stringify(s) if type(s) ~= "string" then return tostring(s) end local prefix = (s == '\\' or s == "'") and '\\' or '' return "'" .. prefix .. s .. "'" end function keyboard.code(key, value) state.kcode.key = key state.kcode.value = value state.kcode.code_to_char = keyboard.code_to_char(key) redraw() end function keyboard.char(ch) state.kchar.ch = ch redraw() end ``` -------------------------------- ### Norns Link Clock Synchronization Example Source: https://github.com/monome/docs/blob/gh-pages/norns/clocks.md This script enables multiple Norns units on the same network to communicate tempo and transport start/stop. Run this on each unit and press K3 to start the transport on all devices. ```lua engine.name = 'PolyPerc' function key(n,z) if n == 3 and z == 1 and not transport_running then clock.link.start() -- start Link clock elseif n == 3 and z == 1 and transport_running then clock.link.stop() -- stop Link clock end end function clock.transport.start() print("we begin") id = clock.run(pulse) transport_running = true redraw() end function clock.transport.stop() clock.cancel(id) transport_running = false pulse_count = 0 redraw() end function pulse() while true do clock.sync(1) engine.hz(333) pulse_count = util.wrap(pulse_count + 1,1,4) redraw() end end function redraw() screen.clear() screen.move(20,40) screen.text(transport_running and 'running' or 'not running') screen.move(pulse_count * 20,60) screen.text('|') screen.update() end function init() transport_running = false pulse_count = 0 capture_preinit() end function capture_preinit() preinit_clock_source = params:get('clock_source') preinit_sync = params:get('link_start_stop_sync') preinit_quantum = params:get('link_quantum') preinit_tempo = params:get('clock_tempo') print('setting clock source to Link') params:set('clock_source',3) print('enabling start/stop sync') params:set('link_start_stop_sync',2) print('setting quantum to 1 beat') params:set('link_quantum',1) print('setting tempo to 95 bpm') params:set('clock_tempo',95) end function cleanup() -- important! stop Link clock with script cleanup: clock.link.stop() print('resetting parameters') params:set('clock_source',preinit_clock_source) params:set('link_start_stop_sync',preinit_sync) params:set('link_quantum',preinit_quantum) params:set('clock_tempo',preinit_tempo) end ``` -------------------------------- ### TO.CV.INIT Source: https://github.com/monome/docs/blob/gh-pages/teletype/manual/index.html Initializes a CV output back to its default boot settings and behaviors. ```APIDOC ## TO.CV.INIT x ### Description Initializes `CV` output `x` back to the default boot settings and behaviors; neutralizes offsets, slews, envelopes, oscillation, etc. ### Parameters #### Path Parameters - **x** (number) - CV output to initialize ``` -------------------------------- ### LAST SCRIPT Operator for Tap Tempo Source: https://github.com/monome/docs/blob/gh-pages/teletype/manual/index.html Gets the number of milliseconds since a script was last run. Useful for tap tempo functionality. For example, 'M LAST SCRIPT' sets the metronome to the time between runs. ```teletype LAST SCRIPT ``` -------------------------------- ### Arduino Setup Function with Connection Callback Source: https://github.com/monome/docs/blob/gh-pages/grid/studies/arduino/index.md The setup function initializes the serial port and assigns a callback for grid device connections. Ensure the serial monitor baud rate is set to 115200. ```cpp void setup() { monome.SetConnectCallback(&ConnectCallback); Serial.begin(115200); Serial.print("\r\ninitialized.\r\n"); delay(200); } ``` -------------------------------- ### Basic Norns Script Setup Source: https://github.com/monome/docs/blob/gh-pages/norns/study-1.md This is the initial script to run. It sets the engine and prints a message upon initialization. Ensure the 'TestSine' engine is available on your Norns. ```lua -- study 1 -- code exercise -- hello engine.name = "TestSine" function init() print("the end and the beginning they are the same.") end ``` -------------------------------- ### Three-Voice Moonshine Sequins Example Source: https://github.com/monome/docs/blob/gh-pages/norns/engine-study-2.md This Lua script sets up a three-voice soundscape using the Moonshine engine and the `sequins` library. It defines note sequences, playback toggling via key press, and basic audio parameters. Ensure the Moonshine engine is installed and restart Norns before running. ```lua -- SC engine study 2: -- 3-voice Moonshine sequins engine.name = 'Moonshine' -- nb. single or double quotes doesn't matter, just don't mix + match pairs! s = require 'sequins' -- see https://monome.org/docs/norns/reference/lib/sequins for more info function init() mults = { s{1, 2.25, s{0.25, 1.5, 3.5, 2, 3, 0.75} }, -- create a sequins of hz multiples for voice 1 s{0.25, 1.25, s{2/3, 3.5, 1/3} }, -- create a sequins of hz multiples for voice 2 s{2, 1.25, s{3.5, 1.5, 2.25, 0.5} } -- create a sequins of hz multiples for voice 3 } playing = false base_hz = 200 sequence = {} sequence[1] = clock.run( function() while true do clock.sync(1/4) if playing then for i = 1,2 do engine.trig(i, base_hz * mults[i]() * math.random(2)) end end end end ) sequence[2] = clock.run( function() while true do clock.sync(3) if playing then engine.trig(3, base_hz * mults[3]()) end end end ) -- some default parameters: for i = 1,2 do engine.amp(i,0.5) engine.attack(i,0) engine.release(i,0.3) engine.pan(i,i == 1 and -1 or 1) engine.cutoff(i,2300) end engine.release(3,clock.get_beat_sec()*2.5) end function key(n,z) if n == 3 and z == 1 then playing = not playing for i = 1,3 do mults[i]:reset() -- resets sequins index to 1 end if not playing then engine.free_all_notes() end redraw() end end function redraw() screen.clear() screen.move(64,32) screen.text(playing and "K3: turn off" or "K3: turn on") screen.update() end ``` -------------------------------- ### Led-Grid All LEDs On Command Source: https://github.com/monome/docs/blob/gh-pages/serialosc/serial.txt Turn on all LEDs on the grid. ```bash [0x13] ``` -------------------------------- ### Manually Load Engine and Control Parameters via REPL Source: https://github.com/monome/docs/blob/gh-pages/norns/reference/engine.md This example shows how to manually load an engine, define a callback, and control engine parameters directly from the Norns REPL. It also demonstrates clearing the engine by loading 'None'. ```bash >> load_callback = function() print("engine has been loaded!") end >> engine.load("PolyPerc", load_callback) >> engine.release(2) >> engine.hz(300) >> engine.pan(-1); engine.hz(400) >> engine.cutoff(4500); engine.pan(0); engine.hz(150) >> engine.load("None", function() print("clearing engine") end) ``` -------------------------------- ### Install Homebrew on macOS Source: https://github.com/monome/docs/blob/gh-pages/serialosc/setup.md Installs the Homebrew package manager on macOS. This is a prerequisite for installing serialosc using Homebrew. ```bash /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ``` -------------------------------- ### Sprocket:start Source: https://github.com/monome/docs/blob/gh-pages/norns/api/modules/lib.lattice.html Starts the sprocket. ```APIDOC ## Sprocket:start ### Description Start the sprocket. ### Method Sprocket:start () ### Endpoint Not applicable (SDK method) ``` -------------------------------- ### Upgrade Setuptools on Windows Source: https://github.com/monome/docs/blob/gh-pages/crow/druid.md Ensure setuptools is up-to-date on Windows before installing monome-druid. ```powershell python -m pip install --upgrade setuptools ``` -------------------------------- ### Install Seamstress with Homebrew Source: https://github.com/monome/docs/blob/gh-pages/grid/studies/seamstress/seamstress-and-norns.md Use Homebrew to install Seamstress by tapping the repository and then installing the package. This is a convenient method for macOS users. ```bash brew tap ryleelyman/seamstress brew install seamstress ``` -------------------------------- ### Install easymidi Dependency (Debian/Ubuntu) Source: https://github.com/monome/docs/blob/gh-pages/grid/studies/nodejs/index.md If you encounter errors installing easymidi, you may need to install the libasound2-dev package on Debian-based systems. ```bash $ sudo apt install libasound2-dev ``` -------------------------------- ### List and Run Seamstress Examples Source: https://github.com/monome/docs/blob/gh-pages/grid/studies/seamstress/seamstress-and-norns.md Use the '-e' flag to list available example scripts and run a specific script by its name. This is useful for exploring Seamstress's capabilities. ```bash seamstress -e SCRIPTNAME ``` -------------------------------- ### TO.TR.INIT Source: https://github.com/monome/docs/blob/gh-pages/teletype/manual/index.html Initializes a TR output back to its default boot settings and behaviors. ```APIDOC ## TO.TR.INIT x ### Description Initializes `TR` output `x` back to the default boot settings and behaviors; neutralizes metronomes, dividers, pulse counters, etc. ### Parameters #### Path Parameters - **x** (number) - TR output to initialize ``` -------------------------------- ### Norns Script Startup Actions Source: https://github.com/monome/docs/blob/gh-pages/norns/engine-study-3.md Sets initial parameter values, starts a sequence of random synth frequencies, and begins the LFO. Use 'clock.run' for timed operations. ```lua startup_actions = clock.run(function() clock.sleep(0.1) params:set("delay_level", 1) params:set("reverb_level", 0) params:set("fchz", 1500) params:bang() -- NEW: sequins clock sequence = clock.run(function() while true do engine.set_synth("hz", hz_vals() * random_offset[math.random(#random_offset)]) clock.sync(1 / 4) end end) fchzLFO:start() -- start our LFO, complements ':stop()' end) ``` -------------------------------- ### Install dfu-programmer on macOS Source: https://github.com/monome/docs/blob/gh-pages/modular/update.md Use Homebrew to install the dfu-programmer utility on macOS. Ensure Homebrew is installed and configured correctly before running this command. ```bash brew install dfu-programmer ```