^^ crow help: general (connectivity, device q's, ecosystem)

I might have encountered a bug in the crow.connected() function with norns. It always returns false, even when crow is connected (and even outputing stuff). Can anybody verify this?

1 Like

Indeed, looks like a typo in this lua function. One-character patch submitted here.

1 Like

Not sure if this is a thing or not: But after uploading a script I’ve been working on for the last few days, after a restart the crow refused to connect. Had to force the bootloader to remove the script in order to get it to behave again. I had added a very long comment line, ~520 characters. When I broke it up it seemed to start behaving again, though there was a some additional troubleshooting between, so maybe something else was actually at issue. Does crow not prune the comments when uploading a script?

I noticed that the first line of a script (comment or not) gets sent as a druid message when the script runs, so it must be keeping the first line at least!

That is also my assumption, based on the name being maintained as the first line comment. Seems like the rest could be stripped out? But if not, might cause an issue!

Druid and crow should both leave the script as-is, I think the idea being that when you ^^print the uploaded script back it should show you the script in its original human-readable form.

I am guessing you are on the v1.0.3 release firmware? A few of the most common kinds of script errors that could previously have locked up the module have been fixed in development builds (obligatory caveat emptor). I’m curious if the issue you encountered is resolved but I don’t really see how long comments could be the culprit – the entire contents of script memory get passed to Lua to evaluate. Here is a test script that works correctly on a current build, in ‘run’ or ‘upload’ mode, in which the longest comment line is 1731 characters.

-- longcomments
function init()
-- 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
  m = metro.init{ event = print -- 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
                , time = 1.0
-- 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
                , count = -1 -- 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
-- 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef

Hmm. Interesting. I am on 1.0.3. It is, of course, possible it was something else. I only added one other line, but that new line did not seem to cause issues upon re-uploading. Well in anycase, I just wanted to leave record of the weirdness in case it crops up again. Thanks for the clarification! :relaxed:

I was hoping to be able to do something similar to output[n].action = lfo() using ii.er301.cv but no such thing appears to exist? What would I need to do to make something like that possible?

I believe currently ASL actions are always associated to an output, you can’t really have them “free running”. I have still not really taken the time to fully understand how ASL is implemented but I believe that an ASL is sort of an array of “steps” to(volts, seconds, shape), which crow’s firmware uses to pre-calculate interpolated CV values for a particular output. You can’t really send I2C messages as fast as crow is updating its DAC. You can evaluate some Lua to determine the volts or seconds parameter though, so you can maybe sort of schedule occasional I2C messages this way:

function ii_to(dst, time)  -- 🩰
  return to(
    function ()
      ii.txo.cv(1, output[1].volts)
      return dst

function init()
    loop { ii_to(1, 0.25)
         , ii_to(2, 0.25)
         , ii_to(3, 0.25)
         , ii_to(4, 0.25)
         , ii_to(3, 0.25)
         , ii_to(2, 0.25)
         , ii_to(1, 0.25)

This gives a steppy LFO from TXo output 1 that is sort of like sample-and-holding the smooth voltage that crow is outputting. Expanding on this idea you can generate the table of waypoints programmatically:

function ii_lfo(vmax, period, steps)
  local action = {}

  local midpt = math.ceil(steps/2)
  local v_step = vmax / midpt
  local step_time = period / steps

  for i=1,midpt do
    action[#action + 1] = ii_to((i - 1) * v_step, step_time)
  for i=midpt,steps do
    action[#action + 1] = action[midpt - (i - midpt)]

  return loop(action)

function init()
  output[1](ii_lfo(5, 2, 20))

Lots of interesting functionality related to ASL is getting added in each firmware release, so there may be some other ways to do this kind of thing, either at present or in the future.


The ASL stuff comes from a library that Trent has on his git repo - wrDsp I think. It seems quite deeply embedded right now and tied in with the hardware

I see no reason that this library couldn’t be implemented by the likes of TxO and even for ansible (except size of the flash considerations) but I suspect it would have to be client side

However someone could implement something in crow like adding to crow an ASL metro call back

asl_metro.init{ time=0.001,action={ to(6,1.0),to(0,1.0) } , function( asl_value ) ii.something.voltave(asl_value) end }

(excuse syntax errors in my rough code)

and obviously limit of II coms would a factor

There might be reasons for that not working of course which @Galapagoose will know better (like for example him not wanting to since it his code :slight_smile: )

The atoms of ASL are to function calls. Beyond that, ASL is just a method of stitching them together in time (with some fancy looping / conditional options).

A to call is essentially an interpolation curve. Go from the current location to a new location over a certain time (following a given curve). At the moment it is linked directly to a DSP library controlling the output jack. I have an extension coming that will allow an ASL to control a generic variable.

I like the idea of using asllib-style helpers for ii commands. There could be 2 backends: 1) breakpoint style for modules that have ‘slew time’ built in, 2) streaming mode for just setting values continuously with some update interval param.

If anyone has proposals for syntax that’d be a good start. Maybe something like:

 — make an ASL
erlfo = Asl.new()

erlfo.to = ii.er301.cv — redirect ‘to’
erlfo.throttle = 0.1 — update every 100ms

— works like a normal asl
erlfo.action = lfo()

Thanks for the tips @csboling, finally got a chance to try it, works!

Can you help me understand better the distinction between #1 and #2? I think I understand what #2 means, but I’m less clear on the meaning of #1.

Would love a way to output less steppy curves over ii.

The ER-301 I2C implementation current can accept either triggers or CV. I don’t think there’s much Brian from Orthogonal Devices could do to make ER-301 a better partner for crow, but if anybody has specific ideas there, I’d be curious to hear them.

Seems like a great start!

#1 is for modules that support a ‘slew’ style message. That way a to style breakpoint would be translated into 2 messages:

function er_to( dest, time )

ER301 already supports this slew command. The bad news is you lose the ability to do anything but linear slopes, but it means the follower device can interpolate smoothly.

Using #2 allows you to do all of the shaping of curves that ASL can do internally, but you’re limited by the bandwidth of the i2c connection. Some people have only 2 i2c devices on a bus, so sending a couple channels of updates at 1ms rate is no issue, but doing that on a bus with a bunch of other communication going on could cause latency or even bus crashes in the worst case.

If a device supports a slew command, you could do a combination of the two methods. The slew would be used to interpolate linearly between timesteps, so that ASL’s non-linear curves could still be used without putting so much stress on the i2c bus. You could probably do ~20ms linear segments approximating the curve.

1 Like

Would be great to have some userland control over this. For me, it’s just 2 devices on the bus.

I’ll add myself to the list of people curious if you got this figured out. I’m having the same issue. Thanks!

Hi! Sorry, I get confused by how threading works on here. I did get it sorted eventually. It was just a bunch of connecting and reconnecting and then at some point it stopped being intermittent.

I was able to synchronise Elektron Digitakt to crow using DIY DIN/MIDI cable and related script. Should be also possible with other Elektron devices with old DIN/MIDI connector and dinsync24 configuration for MIDI out port in device settings.
Crows input 1 must be connected to Clock pin, and input 2 to Start-Stop pin with common ground GND. Note that not every MIDI cable have those pins wired, since MIDI uses other pins.


24 posts were merged into an existing topic: ^^ crow 2.0 help: general (connectivity, device q’s, ecosystem)

wowowow – i can’t believe crow first landed less than a year ago. lots in this thread is either addressed in docs, fixed in the firmware, or no longer relevant with crow 2.0’s release. for new inquiries, please fly over to ^^ crow 2.0+ help: general (connectivity, device q’s, ecosystem)