I just went through the steps of upgrading crow to 2.0. How can I tell if it was successful? Druid has no command to query the version. There is no splash on startup either announcing the version
If your crow is working normally after the update, that is, executing commands through druid, you can type ^^version
or ^^v
in druid to query the firmware version crow is running:
<crow connected>
> ^^version
^^version('v2.0.0-2-g030b36e')
The bit after the g
shows you the exact version of the code that crow is running as a git commit hash, so for instance mine is at 030b36e
.
Great. I dont remeber seeing this in the documentation. If would be great if it is added.
.m
Are there other ^^ codes undocumentd?
I am definitely wanting for some way to get multiple crows to get a metro in sync via code or some way to get them to share a clock/reset around.
So what would a useful hysteresis value on inputs? Does it depend on the stability of the upstream module or can one value cover a useful range?
@grey
I’m guessing you’re thinking of using i2c to do this? If so, it should be pretty easy to have a metro on one crow that sends a tick (or beats:bars counter) to another. Something like:
metro[1].event = function(c)
ii.crow.call1(c)
end
ii.crow.event = function(e,v)
-- do a thing when receiving the clock pulse
end
You could upload this same block to both devices, so long as you only explicitly tell one device metro[1]:start()
. Otherwise every crow will start it’s own metro, and the ii bus will get… messy.
The above is not in the official docs yet, because we’re not 100% on the syntax, but this should work on the current firmware release.
@mleysens
Hysteresis is usually chosen to reflect the stability or ‘bounciness’ of the input signal. If you’re just following a trigger/gate source, you likely won’t need any hysteresis, but it won’t hurt to have it. It is most useful when receiving a noisy, or slow moving signal, to ensure that you don’t get multiple triggers as the input signal crosses the threshold.
In general, a value of 0.1
is a good general purpose setting for avoiding double-triggers.
Yeah, that is effectively the kind of thing I was looking for. Thanks! I’ll give this a think.
Hi all,
I’m having trouble using Crow with Max. I’m running Max 8.18 on Mac OS 11.1 and Crow Firmware 2.0.0 as confirmed by checking in Druid. I’ve followed all the steps to install the crow_max files in my Max user library as per these instructions:
but I can’t instantiate the crow object in Max (I just get the ‘no such object’ error message). My Crow otherwise seems to be OK as far as I can tell, and I can’t figure out why this could be happening…
Any advice please?
Hi! I’ve been writing a couple of crow scripts, which has been a blast: the event based api is perfect! I’m was wondering if its possible to detect whether something is plugged into the jacks? I want to write some normalisation behaviour in my scripts
I figured this out, it was an issue with my Max search path. For some reason it wasn’t looking in my personal user library, it was just looking at my shared user library, so I dropped the crow_max folder in there. If anyone has a similar problem, check out this article on how to view and update your Max search path: Search Path - Max 7 Documentation
oh, jeez, i’m so sorry for missing your original post!
did the install steps here not lead you to the right library? happy to add additional info about ensuring the Max search path has the right folders, but i’d hoped that asking Max for the right location would’ve been bulletproof.
No worries! I really should have figured this out sooner. The part I got stuck on was:
“Open Max
> Options
> File Preferences
> highlight User Library
> the rightmost icon in the bottom bar should illuminate. Clicking this icon will open the User Library folder, where you can drop the crow_max
folder.”
When I open Max
> Options
> File Preferences
there are 4 folders: Global Library; User Library; Snapshots; Examples. For some reason my Max search path didn’t include the ‘User Library,’ but it did include the ‘Global Library.’ Not sure if this is normal or just a quirk with my Max installation / setup. First I tried to update the path list to include the ‘User Library’ location, but that also didn’t work so maybe there’s some other issue going on with my file system. Then I just dropped the crow_max folder into the ‘Global Library’ and hey presto.
Looking for some suggestions (and an excuse to think through this problem).
I’m trying a new approach to my system, and I am hoping to make some space by ditching an Ornament and Crime and using crow as a quad sample and hold: 2 v/o voltages sampled by 4 triggers.
The basic scripting is easy! The rub is that, in order to have enough inputs, I am trying to share a TXi between two crows. There are no other devices on the chain. The first crow is polling the knob positions at a slower pace in order to control my percussion script. The other crow is polling the inputs to catch triggers.If the triggers are high, I am sampling the voltages on the second crow’s inputs and updating its outputs.
As is, it seems like I have to set the metro polling rate to hundredths of a second to avoid audible lag when testing for triggers. That also means I am flooding the i2c bus, and the percussion module has a tough time getting its messages. In an ideal world, I’d use the crow’s inputs to detect the triggers, but I need to sample 4 triggers, AND my TXi has 4 inputs that were not otherwise being used (I also don’t have room for a 3rd crow).
Even with the bonkers fast polling time, the S&H is still off sometimes.
S&H Source Code
state = {
[1] = false,
[2] = false,
[3] = false,
[4] = false
}
function init()
for i=1,4 do
output[i].slew = 0
output[i].scale({}, 12, 1.0)
end
metro[1].event = function(c)
for i=1,4 do ii.txi.get('in', i) end
end
metro[1].time = 0.003
metro[1]:start()
ii.txi.event = function( event, data )
--print(event.arg)
if event.name == 'in' then
chan = event.arg
-- if the trigger is high
if data > 1 then
if state[chan] == false then
state[chan] = true
sample(chan)
-- print(chan)
end
else
if state[chan] then
state[chan] = false
end
end
end
end
end
function sample(channel)
if channel < 3 then
output[channel].volts = input[1].volts
-- print(output[channel].volts)
else
output[channel].volts = input[2].volts
end
end
I could potentially have one crow do all of the polling and then instruct the second crow to do it’s sampling, but that would still require getting messages through on a busy i2c bus.
I realize this isn’t the ideal way to do this, but I’m trying to use the resources I have available.
If anyone has any clever notions about how I could accomplish this more reliably, I’d welcome any insight!
PS - In case this is helpful to anyone else: After making my own i2c cables, the issues I was having with my TXi appear to have completely gone away? I’d tried 3 different cables, and all of them were having periodic dropouts at random times after startup (which required a system reboot). I was never able to catch the moment it happened with debugging enabled, so I still am not sure what what happening. But if you are having mystery i2c dropout issues, keep trying new cables!
Edit: Continuing to think on this, I’m wondering if altering the TXi’s firmware to make it behave like a pseudo leader is the best solution? The crow could register itself as a listener, and the TXi could send messages based on changes to quantized values? Or something like that.
I’ve already got another daunting firmware project to tackle, so it’s definitely not my preferred solution. However, it would reduce the traffic on the i2c line by an order of magnitude, as the TXi is better equipped to notify the crows of changes, in my particular case, rather than the other way around.
Best solution is definitely crow A as leader, crow B and TXi as followers. Anything else will end in bus jams. Also, if you only use TXi for CV and use the crows’ inputs for triggers, you can get reliable interrupts instead of praying to catch a 10mS trigger while polling the TXi.
Sorry, I should have mentioned explicitly that crow A is taking an external clock and reset for my percussion script. I could maybe free up the reset, but I probably want the much faster clock pulse on a crow input.
Thanks for the suggestion. I can try to merge my scripts to see if that gets things to behave in a tighter more reliable fashion.
Shoot, well if you can guarantee that your triggers at the TXi are more like gates (Ladik Gatsby comes to mind, or even just decay-only envelopes with threshold defined in crow A) then you could at least take some pressure of the needed polling rate.
Yeah. They’re coming straight out of Confundo Funkitus, so I don’t have much in the way of control without adding another module, which sort of defeats the point. If I end up adding 6hp+ then I might as well keep the uO_C.
At the very least it’s worth trying out a mega-script before exploring more options.
I may not be doing this as intended: To receive the call on another crow, you need to overwrite the default call behavior in your init, right?
So like:
ii.self.call1 = function(e,v)
{
--do stuff for a single argument call
}
Is that the correct approach to the current methodology? Otherwise the other crow doesn’t seem to do anything but print the the call, as that is the default behavior for the function. Listening for an event didn’t seem to register an event on my second crow.
Edit: And to confirm, my impulse to avoid combining scripts was clearly wrong, as performance has improved following your suggestion. Still need to stress test it to find the best polling speed, but definitely better.
Crow utilizes some “behind the panel” digital connections by connecting to neighboring modules’ I2C headers. There is an emerging lingua franca to this digital communication (based on Monome Teletype-to-Trilogy “II” interactions) and many digital modules now can control and/or be controlled on I2C. Some such modules accept messages which change their settings in a way which is inaccessible via CV.
Oh no! your post is gone. I was just getting warmed up. I do think “Laptop + Crow + Just Friends” is an excellent intro to some aspects of musical coding, btw.
Crow communicates with Just Friends over ii, a digital protocol. Because of this, it is not limited to the amount of physical jacks on Just Friends, and can address more parameters.