I’m taking a look at this over the next couple days. Where is that serial handshake happening with crow? This?

I’m specifically interested in trying to differentiate between ACM devices - hopefully before they get identified as crow

Could someone with crow give me the output from this command:
udevadm info --query=all --name=/dev/ttyACM0

1 Like

plugging away at this tonight and I’m wondering what the purpose of this check_dev_type function really is. The main thing that seems to be doing is ensuring that we only look at USB devices, and then returning the appropriate subsystem type so it can be added with dev_list_add().

So… can we ignore the node_pattern and just get/compare the subsystem type for that dev instead (comparing against sub_name)?

so… check_dev_type() becomes this instead:

device_t check_dev_type(struct udev_device *dev) {
    device_t t = DEV_TYPE_INVALID;
    const char *node = udev_device_get_devnode(dev);
	const char *subsys = udev_device_get_subsystem(dev);

    if (node) {
        // for now, just get USB devices.
        if (udev_device_get_parent_with_subsystem_devtype(dev, "usb", NULL)) {
            for (int i = 0; i < DEV_TYPE_COUNT; i++) {
                if (fnmatch(w[i].sub_name, subsys, 0) == 0) {
                    t = i;
                    break;
                }
            }
        }
    }
    return t;
}

This appears to work with my Teensy grid (a /dev/ttyACM* device)

seems like a reasonable optimization. (i can’t recall the process that led to using regexes and then subsys, but it wasn’t a deep or considered one - just one thing leading to another)

i’m not sure i see how this helps with differentiating between TTY/ACM devices that simply speak different protocols, viz. untz-grid and crow? that’s what the handshake is for

yes, looks like it. so, we have to add some (structured) complexity to attempt different protocols with a new device.

I’m making an assumption that crow is not listing itself on the tty subsystem. (Still need to confirm crow subsystem details). If that’s the case, then that sample code works to tell crow apart from a grid clone like my teensy grid, or the untz-grid. If not, it’s back to hacking.

i’m planning to use TTY/ACM for various DIY devices in the future so yes we need differentiation, but i do not want to build-in the assumption that not-crow means untz grid— so please do not PR an implementation that is this simplistic. let’s get it right so we don’t need to redo it yet again.

I wasn’t really close to submitting a PR,

Realistically this is a bit over my head. I’m trying to make sense of it, but could use some guidance.

I’ll start a GitHub issue and move the conversation there.

i don’t have a crow in front of me, but i don’t believe the new code is functionally different from the old code, and i don’t believe you can distinguish between different TTYs based on libdev subtype, particularly between TTYs that both present ACM interface (line control, etc) vs USB-CDC.

anyways we will either handle the differentiation by A) attempting handshake and then handling failure more gracefully, or B) using VID/PID like the druid script does. (the problem with B is that it will not work for non-monome or DIY devices that conform to crow protocol, but of course that’s not a a real problem at the moment.)

also agree further discussion / test reports best made on github

FWIW - The vendor/product/manufacturer details can be easily modified in code with some DIY devices (with Teensy for example).

Not sure if this is the proper thread for this anymore (please move/remove this message if not), but I got it working: https://www.instagram.com/p/B5-tkvAB2ha/

The solution was new Neonome128 code driven by Teensy 3.2: https://github.com/szymonkaliski/diy-monome/tree/master/Neonome128

And modifying ~/norns/matron/src/device/device_monitor.c line 47 to:

(...)
    {
        .sub_name = "tty",
        .node_pattern = "/dev/tty*"
    },
(...)

Since Neonome128 shows up as /dev/ttyACMXXX.

mlr and awake are working just fine for me, didn’t have a chance to test other scripts yet, but I suspect it should be alright.

4 Likes

yes! 20 characters of get in :slight_smile:

hoping i can adapt it to the untz.

The change in norns means the image needs to be re-compiled?

Thanks!

Yes, you have to recompile after that one line change.

FWIW - I believe this change will still conflict with the device negotiation for crow.

I’ve submitted the start of a possible fix here on github which will not conflict

1 Like

Very possible, I don’t have crow so I ignored that for my use :slight_smile:

1 Like

Hi all, I’m trying to run norns on my Raspberry Pi 3b+ with Raspbian. I’ve managed to build everything correctly, but when i launch crone it fails with some errors related to jack.
In particular at the start it’s unable to connect to the jack server, and then it fails because there are no ADC ports available.
This is the full log:

attempting to bind socket at url ws://*:5556
constructed Client: crone
constructed Client: softcut
initializing buffer management worker..
setting up jack clients..
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jackdmp 1.9.12
Copyright 2001-2005 Paul Davis and others.
Copyright 2004-2016 Grame.
Copyright 2016-2017 Filipe Coelho.
jackdmp comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to redistribute it
under certain conditions; see the file COPYING for details
JACK server starting in realtime mode with priority 10
self-connect-mode is "Don't restrict self connect requests"
creating alsa driver ... hw:0|hw:0|1024|2|48000|0|0|nomon|swmeter|-|32bit
ALSA: Cannot open PCM device alsa_pcm for capture. Falling back to playback-only mode
configuring for 48000Hz, period = 1024 frames (21.3 ms), buffer = 2 periods
ALSA: final selected sample format for playback: 16bit little-endian
ALSA: use 2 periods for playback
JACK server started
engine sample rate: 48000
engine sample rate: 48000
starting jack clients..
connecting ports...
terminate called after throwing an instance of 'std::runtime_error'
  what():  no ADC ports found
JackEngine::XRun: client = crone was not finished, state = Triggered
JackEngine::XRun: client = softcut was not finished, state = Triggered
JackAudioDriver::ProcessGraphAsyncMaster: Process error
Cannot read socket fd = 12 err = Connection reset by peer
Could not read notification result
ClientNotify fails name = crone notification = 18 val1 = 0 val2 = 0
Cannot write socket fd = 15 err = Broken pipe
CheckRes error
Could not write notification
ClientNotify fails name = softcut notification = 18 val1 = 0 val2 = 0
Cannot write socket fd = 15 err = Broken pipe
CheckRes error
Could not write notification
ClientNotify fails name = softcut notification = 18 val1 = 1 val2 = 0
Cannot write socket fd = 12 err = Broken pipe
CheckRes error
Could not write notification
ClientNotify fails name = crone notification = 18 val1 = 1 val2 = 0
JackEngine::XRun: client = softcut was not finished, state = Triggered
JackAudioDriver::ProcessGraphAsyncMaster: Process error
JackEngine::XRun: client = softcut was not finished, state = Triggered
JackAudioDriver::ProcessGraphAsyncMaster: Process error
Cannot write socket fd = 15 err = Broken pipe
CheckRes error
Could not write notification
ClientNotify fails name = crone notification = 1 val1 = 0 val2 = 0
Unknown error...
terminate called after throwing an instance of 'Jack::JackTemporaryException'
  what():
compiling class library...
qt.qpa.screen: QXcbConnection: Could not connect to display
Could not connect to any X display.
terminate called without an active exception

Seems to be complaining that the default device has no capture ( which would be an adc) - perhaps it’s using hdmi?
What soundcard are you using, is it configured?

You can see what alsa is setting with aplay -l , and then make sure that’s setup in .jackdrc (?) and just try to start jack to resolve issues.

Yes, I was using HDMI, i will try just with the standard jack of the rPi, thanks

Hi, I have Norns software running on a Raspberry Pi 3B+, and I’ve found some performance issues when I use it with the arpeggiator of the Arturia Keystep. seems like the thread that handles the midi events is blocked after some time, and some of the midi messages are delayed.
I found that the screen code in matron was not copyng the screen updates to the framebuffer in its own thread so, that was the first change I’ve made an it works but didn’t resolve the issue completly.
Has anyone expriencied this issue?

The CPU is 12%, so it is not a problem with the CPU usage.

My setup is:
Raspberry Pi 3B+
Behringer UCA-222 USB audio interface
TFT Screen 3.5 (480x320) (I have to scale the image before copy it to framebuffer)
Encoder to GPIO and Buttons to a MCP2008 IO expander (with some custom process to make it work as matron expect)

are you saying you fixed this somewhat complicated issue which is in-progress? https://github.com/monome/norns/pull/1052

very likely your keystep has old firmware https://github.com/monome/norns/issues/609

I have the last firmware version in Keystep which fixes the hanging notes issue.

Regarding the render loop issue, I’ve made a quick test, my suspicion was that due the display that I’m using has a lot more resolution the process to copy the scaled image to framebuffer takes more time and that was blocking the process that handles midi events.
I didn’t implement a full solution with an event queue to process all the screen changes in another thread. I just moved the call to cairo_paint(crfb) to a different thread an I used a pthread_cond_t to wake up that thread from screen_update() function.
The improvement was very noticeable, so think that my suspicion was right.
Now you mention that it is a known issue and I saw your PR with the event queue I think that maybe that will fix the problem completely.

1 Like

Hello,
Im starting with Norns using Raspberry PI 3 MODEL B.
Im following all the setup steps, but when at the moment to run the SuperCollider install bash script , i get this error message

cp: cannot create regular file ‘/home/we/.local/share/SuperCollider/Extensions/’: No such file or directory

Im not clear if i need to create this directory manually and with Extensions i need to add to use with crone.

Thanks a lot in advance