Last active
February 24, 2025 22:36
-
-
Save Dewb/12c09eb5cf80c8b432c7b4a0f9287d13 to your computer and use it in GitHub Desktop.
Lua scripts for norns and crow for Flash Crash performance on 2022/01/01 https://vimeo.com/662344765
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- crow script loaded from norns, must be in crow/ subfolder | |
public{camera_preset = 0} | |
public{camera_animation = 0} | |
public{clock_phase = 0} | |
ii.self.call2 = function(f, v) | |
print("fc/crow: call2") | |
if f == 1 then | |
public.camera_preset = v | |
elseif f == 2 then | |
public.clock_phase = v | |
elseif f == 3 then | |
public.camera_animation = v | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- flash crash 20220101 | |
-- performance by anagram | |
-- author: @dewb | |
camera = {name="camera", port = nil, device = nil} | |
servo = {name="servo", port = nil, device = nil} | |
camera_metro = nil | |
camera_metro_refresh_fps = 5 | |
speed_p = 0 | |
speed_t = 0 | |
speed_z = 0 | |
max_speed = 24 | |
camera_moving = false | |
function camera_metro_callback() | |
local speed_p_norm = math.floor(speed_p + 0.5) | |
local speed_t_norm = math.floor(speed_t + 0.5) | |
local speed_z_norm = 0 | |
if (speed_p_norm ~= 0 or speed_t_norm ~= 0) then | |
local dir_p = ((speed_p_norm == 0) and '\x03') or ((speed_p_norm > 0) and '\x01') or '\x02' | |
local dir_t = ((speed_t_norm == 0) and '\x03') or ((speed_t_norm > 0) and '\x02') or '\x01' | |
send_command('\x81\x01\x06\x01' .. string.char(math.abs(speed_p_norm)) .. string.char(math.abs(speed_t_norm)) .. dir_p .. dir_t .. '\xFF') | |
camera_moving = true | |
elseif camera_moving then | |
camera_stop() | |
end | |
end | |
function clamp_speed(speed) | |
return math.max(-max_speed, math.min(max_speed, speed)) | |
end | |
function send_command(str) | |
if camera.port then | |
camera.port:write(str) | |
camera.port:flush() | |
--while serial_port:read(1) ~= '\xFF' do | |
--end | |
--serial_port:read(3) -- ack response | |
--serial_port:read(3) -- completion response | |
end | |
end | |
function send_inquiry(str, response_length) | |
send_command(str) | |
return camera.port:read(response_length) | |
end | |
function camera_home() | |
send_command('\x81\x01\x06\x04\xFF') | |
end | |
-- save current position to preset 1-6 | |
function camera_save_preset(preset_num) | |
if preset_num > 0 and preset_num < 9 then | |
send_command('\x81\x01\x04\x3F\x01' .. string.char(preset_num - 1).. '\xFF') | |
end | |
end | |
-- recall presets 1-6 | |
function camera_recall_preset(preset_num) | |
if preset_num > 0 and preset_num < 9 then | |
send_command('\x81\x01\x04\x3F\x02' .. string.char(preset_num - 1) .. '\xFF') | |
end | |
end | |
function camera_stop() | |
speed_p = 0 | |
speed_t = 0 | |
speed_z = 0 | |
camera_moving = false | |
send_command('\x81\x01\x06\x01\x15\x15\x03\x03\xFF') | |
end | |
function enc(n, delta) | |
if n == 2 then | |
--speed_p = clamp_speed(speed_p + delta * 0.4) | |
elseif n == 3 then | |
--speed_t = clamp_speed(speed_t + delta * 0.4) | |
end | |
end | |
function key(n, z) | |
if z == 1 and n == 2 then | |
camera_recall_preset(2) | |
end | |
end | |
function receive_serial_devices(thing, device_list, args) | |
if thing.port then thing.port:close() end | |
for d in device_list:gmatch("([^\n]*)\n?") do | |
thing.port = io.open(d, "r+") | |
if (thing.port) then | |
thing.device = d | |
print("Connected to " .. thing.name .. " at " .. thing.device) | |
norns.system_cmd("stty -F " .. thing.device .. " 9600 cs8 -cstopb -parenb") | |
break | |
end | |
end | |
end | |
function init() | |
local camera_args = "9600 cs8 -cstopb -parenb" | |
norns.system_cmd("bash -c 'ls /dev/ttyUSB*'", function(list) receive_serial_devices(camera, list, camera_args) end) | |
local servo_args = "cs8 9600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts" | |
norns.system_cmd("bash -c 'ls /dev/ttyACM1'", function(list) receive_serial_devices(servo, list, servo_args) end) | |
camera_metro = metro.init(camera_metro_callback, 1/camera_metro_refresh_fps) | |
camera_metro:start() | |
start_crow() | |
end | |
function cleanup() | |
if camera_metro then camera_metro:stop() end | |
if serial_port then serial_port:close() end | |
end | |
function start_crow() | |
function norns.crow.public.change(n, v) public_update(n, v) end | |
function norns.crow.public.discovered() | |
print'fc discovered crow public' | |
end | |
norns.crow.loadscript("flashcrash_20220101.lua") | |
end | |
function public_update(name, value) | |
print("Crow public change detected") | |
if name ~= nil then print(name) end | |
if value ~= nil then print(value) end | |
if name == "camera_preset" then | |
camera_recall_preset(value) | |
elseif name == "clock_phase" and value >= 1 and value <= 4 then | |
local cmds = {"60", "80", "90", "105"} | |
servo_command(cmds[value]) | |
elseif name == "camera_animation" and value >= 1 and value <= 4 then | |
camera_animate(value) | |
end | |
end | |
function servo_command(intstr) | |
if servo.port ~= nil then | |
servo.port:write(intstr .. "\n") | |
servo.port:flush() | |
end | |
end | |
function camera_animate(value) | |
if value < 1 or value > 4 then | |
return | |
end | |
local dir_p = '\x03' | |
local dir_t = '\x03' | |
local sp = 0 | |
local st = 0 | |
local s = 6 | |
if value == 1 then | |
dir_t = '\x01' | |
st = s | |
elseif value == 2 then | |
dir_p = '\x01' | |
sp = s | |
elseif value == 3 then | |
dir_t = '\x02' | |
st = s | |
elseif value == 4 then | |
dir_p = '\x02' | |
sp = s | |
end | |
clock.run(function() | |
send_command('\x81\x01\x06\x01' .. string.char(sp) .. string.char(st) .. dir_p .. dir_t .. '\xFF') | |
clock.sleep(0.2) | |
send_command('\x81\x01\x06\x01' .. string.char(sp/2) .. string.char(st/2) .. dir_p .. dir_t .. '\xFF') | |
clock.sleep(0.2) | |
camera_stop() | |
clock.sleep(0.2) | |
camera_recall_preset(norns.crow.public.lookup("camera_preset").val) | |
norns.crow.public.update("camera_animation", 0) | |
end) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment