hi everyone,
currently I finished my diy txo built and now I am experimenting with the txo as a crow expander.
I came across the following problem which I can not understand/solve on my own …
In short: When using the native ii commands for txo (e.g. crow.ii.txo.tr_pulse(1)) it occurs regularly that norns’ screen freezes and only comes back to life when I repower my eurorack case (power cycle crow). But when I am using the crow.ii.raw command the problem does not occur …
Now I am wondering, why my self implemented commands work better than the standard commands? The problem further affects the performance of fastly sent commands. with the native commands pulses of 1/32 length are missed regularly, but with raw they work totally fine.
To the setup: I am using crow (v 3.0.1), with norns shield (latest update) and txo (latest firmware). The pulses are generated in a clock routine which is started from a mod pre_init. The mod is going to be a “crow’s new workout” type of thing!
Do you have any ideas what causes the problem? I only discovered the issue because I thought it is maybe safer to not use my own implemented commands …
i reduced the script to the following which reproduces the error consistently. you can still ;restart but this want solve the issue, only repowering both norns and crow will reset everything.
engine.name = 'PolySub'
txo_command = function (cmd,out,value)
local msg = string.char(cmd)
if out then msg = msg .. string.char(out) end
if value then
value = math.floor(value) & 0xFFFF
local str = string.format("%04x",value)
local len = string.len(str)
str = string.sub(str,len-3,len)
local msb = tonumber(string.sub(str,1,2),16)
local lsb = tonumber(string.sub(str,3,4),16)
msg = msg .. string.char(msb) .. string.char(lsb)
end
crow.ii.raw(0x60,msg)
end
function init()
-- SCREEN LOOP
clock.run(
function ()
while true do
redraw()
clock.sleep(1/10)
end
end
)
-- OTHER LOOP
clock.run(
function ()
clock.sleep(3)
while true do
crow.ii.disting.midi(0xB0,123)
clock.sync(1/2)
end
end
)
-- TXO LOOP
clock.run(
function ()
for n=1,4 do crow.ii.txo.tr_time(n, clock.get_beat_sec()/16*1000) end
--for n=1,4 do txo_command(0x02,n-1,50) end
clock.sync(1)
while true do
for n=1,4 do crow.ii.txo.tr_pulse(n) end
--for n=1,4 do txo_command(0x05,n-1) end
clock.sync(1/8)
end
end
)
end
function redraw()
screen.clear()
screen.move(62,32)
screen.level(15)
screen.text(util.round(clock.get_beats(),0.25))
screen.update()
end
I included the raw alternative which helps to avoid the problem.
I assume that it is related to the clock system, since under some conditions I still could enter the norns menu and when i reentered the script, the screen was updated but did not continue to update automatically.
The way the raw alternative works, but the built-in (well-tested) system doesn’t, suggests the issue might be to do with speed. When you’re building the raw command it’s taking a lot longer on the norns side, than using a built-in crow function.
This makes me think the issue could be to do with the usb connection between the devices being overrun. One thing I’d try is transposing the tr_pulse call so the for loop happens on crow:
-- current version. loop runs on norns. sends 4 msgs to crow
for n=1,4 do crow.ii.txo.tr_pulse(n) end
-- alternative. loop runs on crow. only 1 msg to crow
crow[[for n=1,4 do ii.txo.tr_pulse(n) end]]
Also, just to be sure we’re not on the wrong track, try commenting out the disting clock to prove there is no interaction with that code.
sorry, I was not clear in my last post. I included the disting command, since the error occurs in combination with the really slow call of the disting command. I included it in that manner to make it reproducible, in the original script, such commands were send as a response to some changes of settings.
without the disting command the native ii commands work fine.
your suggestion works with the disting command!
can elaborate a little bit on the syntax? I am by now quite familiar with lua on norns but I have not seen any thing like this syntax before?
sure i think this usage is undocumented, or at least underdocumented.
rather than use the crow.* namespace to call crow functions, you can just send chunks of lua code to crow. the formal function for the this is norns.crow.send(...) but there is a shortcut to do this by calling the crow table itself.
the double-square brackets are the symbol for denoting multi-line strings in lua. and in lua, you can call a function without parentheses if you have a single string argument (or single table arg). so it’s a bunch of shortcuts to convert it like this:
-- longform with single-line string
norns.crow.send( "for n=1,4 do ii.txo.tr_pulse(n) end" )
-- shortcut to make it clear you're running the following code on crow
crow[[
for n=1,4 do ii.txo.tr_pulse(n) end
]]
all of the crow.* calls use this norns.crow.send(...) function under the hood, but just try to make it feel more continuous in style.