are you on factory norns or something else?
what’s your g++ --version ?

Oh sorry, I should have mentioned that. I’m on a rasbperry pi 3b norns. I was actually trying to adjust the timeout in hello.c as you suggested to give jack more time to initialize.

Here’s my g++ info:

norns:norns we$ g++ --version
g++ (Raspbian 8.3.0-6+rpi1) 8.3.0

I’ve run into this before on my 3b+. Adding -latomic to $LINKFLAGS before configure worked for me:

LINKFLAGS="-latomic" ./waf configure && ./waf
1 Like

(per @zebra’s suggestion) I changed the crone wscript to include the “-latomic” flag.

IIRC it’s due to something with Buster?

https://github.com/okyeron/fates/blob/master/install/norns/files/crone/wscript

1 Like

P.s. changing the timeout on hello.c didn’t help. I still seem to get the following errors a lot:

norns:~ we$ journalctl | grep jack
Oct 29 20:11:44 norns systemd[1]: Starting norns-jack.service...
Oct 29 20:11:45 norns jack_wait[356]: Cannot connect to server socket err = No such file or directory
Oct 29 20:11:45 norns jack_wait[356]: Cannot connect to server request channel
Oct 29 20:11:45 norns jack_wait[356]: jack server is not running or cannot be started
Oct 29 20:11:45 norns jack_wait[356]: JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Oct 29 20:11:45 norns jack_wait[356]: JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Oct 29 20:11:46 norns jackd[355]: jackdmp 1.9.12
Oct 29 20:11:46 norns jackd[355]: Copyright 2001-2005 Paul Davis and others.
Oct 29 20:11:46 norns jackd[355]: Copyright 2004-2016 Grame.
Oct 29 20:11:46 norns jackd[355]: Copyright 2016-2017 Filipe Coelho.
Oct 29 20:11:46 norns jackd[355]: jackdmp comes with ABSOLUTELY NO WARRANTY
Oct 29 20:11:46 norns jackd[355]: This is free software, and you are welcome to redistribute it
Oct 29 20:11:46 norns jackd[355]: under certain conditions; see the file COPYING for details
Oct 29 20:11:46 norns jackd[355]: JACK server starting in realtime mode with priority 95
Oct 29 20:11:46 norns jackd[355]: self-connect-mode is "Don't restrict self connect requests"
Oct 29 20:11:46 norns jack_wait[356]: Cannot connect to server socket err = No such file or directory
Oct 29 20:11:46 norns jack_wait[356]: Cannot connect to server request channel
Oct 29 20:11:46 norns jack_wait[356]: jack server is not running or cannot be started
Oct 29 20:11:46 norns jack_wait[356]: JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Oct 29 20:11:46 norns jackd[355]: creating alsa driver ... hw:0|hw:0|256|3|48000|0|0|nomon|swmeter|soft-mode|16bit
Oct 29 20:11:46 norns jackd[355]: configuring for 48000Hz, period = 256 frames (5.3 ms), buffer = 3 periods
Oct 29 20:11:46 norns jackd[355]: ALSA: final selected sample format for capture: 16bit little-endian
Oct 29 20:11:46 norns jackd[355]: ALSA: use 3 periods for capture
Oct 29 20:11:46 norns jackd[355]: ALSA: final selected sample format for playback: 16bit little-endian
Oct 29 20:11:46 norns jackd[355]: ALSA: use 3 periods for playback
Oct 29 20:11:47 norns jack_wait[356]: server is available
Oct 29 20:11:47 norns systemd[1]: Started norns-jack.service.
Oct 29 20:11:47 norns crone[424]: setting up jack clients..
Oct 29 20:11:48 norns crone[424]: starting jack clients..
Oct 29 20:11:50 norns jackd[355]: JackEngine::XRun: client = softcut was not finished, state = Triggered
Oct 29 20:11:50 norns jackd[355]: JackAudioDriver::ProcessGraphAsyncMaster: Process error
Oct 29 20:11:50 norns jackd[355]: JackEngine::XRun: client = softcut was not finished, state = Triggered

Maybe I just need to upgrade to a Rpi 3b+ or 4.

Hi @szymon_k :slight_smile:

I managed to install npm, node and your serialoscd on my fates norns.

When i launch:

serialoscd /dev/ttyACM0 (being ACM0) the port the untz is connected to i get the confirmation from serialoscd:

opening /dev/ttyACM0…

ready!

But the untz is not recognised by norns, like it is on the same procedure on the mac.

I tried some counsel form @okyeron so norns recognises the untz changing:

sudo nano ~/norns/matron/src/device/device_monitor.c

and modifying this two lines of code:

.sub_name = “tty”,

.node_pattern = “/dev/ttyUSB*”

replacing it for

.sub_name = “ttyACM*”,

.node_pattern = “/dev/ttyACM*”

or

.sub_name = “tty*”,

.node_pattern = “/dev/tty*”

But had not had success, maybe @zebra or @tehn might now what im doing wrong, which i dont even know it its possible to do at the moment.

Many thanks to all!

well firstly, the norns stack doesn’t use OSC for grids, so forget about serialosc.

beyond that i dunno. there are a lot of questions to be asked. also, i don’t have this device and can’t test things for you.

  • if it’s showing up as ACM then it’s actually a different protocol and driver - Abstract Control Model. this implements CDC with additional command sequences, instead of a UART emulation over USB. it likely cannot run at the same baudrates as a USB-serial device.

  • in other words, when you plug in the untz, what actually shows up in /dev?

  • are you sure the untz firmware isn’t configured for midi or HID?

  • assuming it is ACM, does this work with other libmonome applications on other systems?

  • finally, when you change the matron code and recompile, what actually happens besides “it doesn’t work”? did you try printing stuff in the watch loop? &c

1 Like

Thanks for your info as feedback @zebra .

Well i thought about using the same steps as i used on my laptop to have the Untz device recognized by serialosc as a monome device, but as you are pointing out, norns does not speak serialosc but libmonome?

It works with serialosc apps but have not tested with libmonome apps, any pointer on which app to test it with?

Unfortunately im starting to think this might not be able to be done with this combination of hardware and norns :frowning:

As soon as i get back to my laptop ill Come back with more detailed info.

Thanks a bunch!

im starting to think this might not be able to be done with this combination of hardware and norns

well, using the device with norns is certianly possible but i’ve no real idea what’s easiest - i just don’t know enough about the untz. if it shows as a serial device and responds to monome serial protocol then it can surely be made to work. if modifications to matron code are required they are likely to be minor, like changing device path search patterns.

re: libmonome apps, the repo contains basic test programs. here is a recent thread about compiling and running serial device tests with libmonome on macos:

another direction you could consider is running the untz as a midi device and creating+using a grid <-> midi API adapter layer in lua. this just came up here:

implementing this feature would be quite easy and seems like it would have some widespread utility.

@thopa sorry for leading you on the wrong path, like I mentioned I don’t have norns and didn’t look into the source files to figure out that it’s not using serialosc at all.
I’m waiting for fates board to arrive, and given some free time, I’ll probably try to make it work with my diy grid.

1 Like

I probably have “the solution” in my diy grid code somewhere, but I don’t know if it is backwards portable to the untz from my Teensy-grid changes.

I’m just unable to look at this until I am back home in 2 weeks.

1 Like

Thanks a lot your feedback and time @zebra very much appreciated.

I have been doing some research while travelling (hurray for wifi on trains)

Here are some info that i think might be helpfull.

This is the adafruit untz orginal page:

https://learn.adafruit.com/untztrument-trellis-midi-instrument/overview

There is an interesting part saying that the device, since it has a arduino leonardo can do Usb midi and serial:

“Since its USB MIDI it can work instantly with just about all synth software. Don’t like MIDI? The Arduino Leonardo can also emulate a USB keyboard or plain old USB serial”

So, i went back and looked into the orginal files i went over when building the untz, which was to use it as a monome diy version.

*Program an Adafruit Untz 8x8 or HellaUntz 8x16 to work as a monome.org controller via the mext protocol

This project uses the monome.org serial protocol defined at http://monome.org/docs/tech:serialwhich is used to control arrays of lighted buttons for creative control applications.

The Adafruit Untz is a monochrome (B/W) array of 8x8 or 8x16 keys. ----> https://www.adafruit.com/products/1919----> https://www.adafruit.com/products/1999Using an Arduino Leonardo, the serial protocol is read and written according to the mext serial protocol.

mext is used by the monome serialosc software which provides a host computer interface that may be used with many types of creative software packages such as Max MSP that interface well with monome compatible software but the serial protocol may easily be handled by your choice of programming languages including Processing, Python, C, Ruby, or others.*

So here its saying that its using the mext protocol using the defined monome serial protocol but its for serialosc.

Later i found this other approach by monome lines user @szymon_k :slight_smile:

This part got me thinking:

The official software to communicate with monomes and set up OSC server that other patches connect to is called serialoscd. Monome detection is done through FTDI label, there are two solutions to this: either reflash Arduino FTDI chip (I didn’t try that, but it’s possible), or hack around this in libmonome code. There’s folder with patchesfor both serialosc project (that just makes it compile on recent macOS), and a patch for libmonome that allowed me to detect the Arduino, and make it communicate with external software. You can get both serialosc and libmonome code from monome github page, and building them is well documented on official linux docs (they work for macOS as well), read part 2 Preparing your system: serialosc(ignoring the sudo apt-get - I was missing liblo, but it’s available on homebrew): monome.org/docs/linux/.

The template that is loaded in the arduino leonardo is this:

Reduce code:

Arduino ino code
#include "Adafruit_Trellis.h"

#define NUM_TRELLIS (4)
#define NUM_KEYS    (NUM_TRELLIS * 16)

Adafruit_Trellis matrixes[] = {
  Adafruit_Trellis(),
  Adafruit_Trellis(),
  Adafruit_Trellis(),
  Adafruit_Trellis()
};

Adafruit_TrellisSet trellis = Adafruit_TrellisSet(&matrixes[0], &matrixes[1], &matrixes[2], &matrixes[3]);

String deviceID  = "monome";
String serialNum = "m1000000";

unsigned long prevReadTime  = 0;
unsigned long prevWriteTime = 0;

static bool ledBuffer[8][8];

// these functions are from Adafruit_UNTZtrument.h
static const uint8_t PROGMEM
i2xy64[] = {
  0x00, 0x10, 0x20, 0x30, 0x01, 0x11, 0x21, 0x31,
  0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33,
  0x40, 0x50, 0x60, 0x70, 0x41, 0x51, 0x61, 0x71,
  0x42, 0x52, 0x62, 0x72, 0x43, 0x53, 0x63, 0x73,
  0x04, 0x14, 0x24, 0x34, 0x05, 0x15, 0x25, 0x35,
  0x06, 0x16, 0x26, 0x36, 0x07, 0x17, 0x27, 0x37,
  0x44, 0x54, 0x64, 0x74, 0x45, 0x55, 0x65, 0x75,
  0x46, 0x56, 0x66, 0x76, 0x47, 0x57, 0x67, 0x77
},
xy2i64[8][8] = {
  {  0,  1,  2,  3, 16, 17, 18, 19 },
  {  4,  5,  6,  7, 20, 21, 22, 23 },
  {  8,  9, 10, 11, 24, 25, 26, 27 },
  { 12, 13, 14, 15, 28, 29, 30, 31 },
  { 32, 33, 34, 35, 48, 49, 50, 51 },
  { 36, 37, 38, 39, 52, 53, 54, 55 },
  { 40, 41, 42, 43, 56, 57, 58, 59 },
  { 44, 45, 46, 47, 60, 61, 62, 63 }
};

uint8_t xy2i(uint8_t x, uint8_t y) {
  if (x > 7 || y > 7) {
    return 255;
  }

  return pgm_read_byte(&xy2i64[y][x]);
}

void i2xy(uint8_t i, uint8_t *x, uint8_t *y) {
  if (i > NUM_KEYS) {
    *x = *y = 255;
    return;
  }

  uint8_t xy = pgm_read_byte(&i2xy64[i]);

  *x = xy >> 4;
  *y = xy & 15;
}

void setLED(int x, int y, int v) {
  if (x >= 0 && x < 8 && y >= 0 && y < 8) {
    ledBuffer[x][y] = v;
  }
}

void setAllLEDs(int value) {
  uint8_t i, j;

  for (i = 0; i < 8; i++) {
    for (j = 0; j < 8; j++) {
      ledBuffer[i][j] = value;
    }
  }
}

void turnOffLEDs() {
  setAllLEDs(0);
}

void turnOnLEDs() {
  setAllLEDs(1);
}

void setup() {
  Serial.begin(115200);

  // adjust this if x/y makes no sense on your grid
  trellis.begin(0x71, 0x70, 0x73, 0x72);

  setAllLEDs(0);
}

uint8_t readInt() {
  return Serial.read();
}

void writeInt(uint8_t value) {
  Serial.write(value);
}

void processSerial() {
  uint8_t identifierSent;                     // command byte sent from controller to matrix
  uint8_t deviceAddress;                      // device address sent from controller
  uint8_t dummy;                              // for reading in data not used by the matrix
  uint8_t intensity = 255;                    // led intensity, ignored
  uint8_t readX, readY;                       // x and y values read from driver
  uint8_t i, x, y;

  identifierSent = Serial.read();             // get command identifier: first byte of packet is identifier in the form: [(a << 4) + b]
                                              // a = section (ie. system, key-grid, digital, encoder, led grid, tilt)
                                              // b = command (ie. query, enable, led, key, frame)

  switch (identifierSent) {
    case 0x00:
      writeInt((uint8_t)0x00);                // system/query response 0x00 -> 0x00
      writeInt((uint8_t)0x01);                // grids
      writeInt((uint8_t)0x01);                // one grid
      break;

    case 0x01:
      writeInt((uint8_t)0x01);
      for (i = 0; i < 32; i++) {              // has to be 32
        if (i < deviceID.length()) {
          Serial.print(deviceID[i]);
        }
        else {
          Serial.print('\0');
        }
      }
      break;

    case 0x02:
      for (i = 0; i < 32; i++) {
        deviceID[i] = Serial.read();
      }
      break;

    case 0x03:
      writeInt((uint8_t)0x02);                // system / request grid offsets
      // writeInt(0);                         // n grid?
      writeInt((uint8_t)0x00);                // x offset
      writeInt((uint8_t)0x00);                // y offset
      break;

    case 0x04:
      dummy = readInt();                      // system / set grid offset
      readX = readInt();                      // an offset of 8 is valid only for 16 x 8 monome
      readY = readInt();                      // an offset is invalid for y as it's only 8
      break;

    case 0x05:
      writeInt((uint8_t)0x03);                // system / request grid size
      writeInt((uint8_t)8);
      writeInt((uint8_t)8);
      break;

    case 0x06:
      readX = readInt();                      // system / set grid size - ignored
      readY = readInt();
      break;

    case 0x07:
      break;                                  // I2C stuff - ignored

    case 0x08:
      deviceAddress = readInt();              // set addr - ignored
      dummy = readInt();
      break;

    case 0x0F:
      writeInt((uint8_t)0x0F);                // send serial number
      Serial.print(serialNum);
      break;

    case 0x10:
      readX = readInt();
      readY = readInt();
      setLED(readX, readY, 0);
      break;

    case 0x11:
      readX = readInt();
      readY = readInt();
      setLED(readX, readY, 1);
      break;

    case 0x12:
      turnOffLEDs();
      break;

    case 0x13:
      turnOnLEDs();
      break;

    case 0x14:
      readX = readInt();
      readY = readInt();

      if (readY != 0) break;                  // since we only have 8 LEDs in a column, no offset

      for (y = 0; y < 8; y++) {               // each i will be a row
        intensity = readInt();                // read one byte of 8 bits on/off

        for (x = 0; x < 8; x++) {             // for 8 LEDs on a row
          if ((intensity >> x) & 0x01) {      // set LED if the intensity bit is set
            setLED(readX + x, y, 1);
          }
          else {
            setLED(readX + x, y, 0);
          }
        }
      }
      break;

    case 0x15:
      readX = readInt();                      // led-grid / set row
      readY = readInt();                      // may be any value
      intensity = readInt();                  // read one byte of 8 bits on/off

      for (i = 0; i < 8; i++) {               // for the next 8 lights in row
        if ((intensity >> i) & 0x01) {        // if intensity bit set, light
          setLED(readX + i, readY, 1);
        }
        else {
          setLED(readX + i, readY, 0);
        }
      }
      break;

    case 0x16:
      readX = readInt();                      // led-grid / column set
      readY = readInt();
      intensity = readInt();                  // read one byte of 8 bits on/off

      if (readY != 0) break;                  // we only have 8 lights in a column

      for (i = 0; i < 8; i++) {               // for the next 8 lights in column
        if ((intensity >> i) & 0x01) {        // if intensity bit set, light
          setLED(readX, i, 1);
        }
        else {
          setLED(readX, i, 0);
        }
      }
      break;

    case 0x17:
      intensity = readInt();                  // intensity stuff - ignored
      break;

    case 0x18:
      readX = readInt();                      // led-grid / set LED intensity
      readY = readInt();                      // read the x and y coordinates
      intensity = readInt();                  // read the intensity value (0-255, 0x00-0xFF)

      if (intensity > 0) {
        setLED(readX, readY, 1);
      }
      else {
        setLED(readX, readY, 0);
      }
      break;

    case 0x19:                                // set all leds
      intensity = readInt();

      if (intensity > 0) {
        turnOnLEDs();
      }
      else {
        turnOffLEDs();
      }

    case 0x1A:                                // set 8x8 block
      readX = readInt();
      readY = readInt();

      for (y = 0; y < 8; y++) {
        for (x = 0; x < 8; x++) {
          if ((x + y) % 2 == 0) {             // even bytes, use upper nybble
            intensity = readInt();

            if (intensity >> 4 & 0x0F)  {
              setLED(readX + x, y, 1);
            }
            else {
              setLED(readX + x, y, 0);
            }
          }
          else {                              // odd bytes, use lower nybble
            if (intensity & 0x0F) {
              setLED(readX + x, y, 1);
            }
            else {
              setLED(readX + x, y, 0);
            }
          }
        }
      }
      break;

    case 0x1B:                                // set 8x1 row by intensity
      readX = readInt();
      readY = readInt();

      for (x = 0; x < 8; x++) {
        intensity = readInt();

        if (intensity) {
          setLED(readX + x, readY, 1);
        }
        else {
          setLED(readX + x, readY, 0);
        }
      }
      break;

    case 0x1C:                                // set 1x8 column by intensity
      readX = readInt();
      readY = readInt();

      for (y = 0; y < 8; y++) {
        intensity = readInt();

        if (intensity) {
          setLED(readX, readY + y, 1);
        }
        else {
          setLED(readX, readY + y, 0);
        }
      }
      break;

    default:
      break;
  }

  return;
}

void readKeys() {
  uint8_t x, y;

  for (uint8_t i = 0; i < NUM_KEYS; i++) {
    if (trellis.justPressed(i)) {
      i2xy(i, &x, &y);

      writeInt(0x21);
      writeInt(x);
      writeInt(y);
    }
    else if (trellis.justReleased(i)) {
      i2xy(i, &x, &y);

      writeInt(0x20);
      writeInt(x);
      writeInt(y);
    }
  }
}

void loop() {
  unsigned long now = millis();

  if (Serial.available() > 0) {
    do {
      processSerial();
    } while (Serial.available() > 16);
  }
  else if (now - prevWriteTime >= 10) {
    // set trellis internal matrix from ledBuffer
    for (uint8_t x = 0; x < 8; x++) {
      for (uint8_t y = 0; y < 8; y++) {
        if (ledBuffer[x][y]) {
          trellis.setLED(xy2i(x, y));
        }
        else {
          trellis.clrLED(xy2i(x, y));
        }
      }
    }

    // update display every ~10ms
    trellis.writeDisplay();

    prevWriteTime = now;
  }
  else if (now - prevReadTime >= 30) {
    // read switches not more often than every ~30ms - hardware requirement
    if (trellis.readSwitches()) {
      readKeys();
    }

    prevReadTime = now;
  }
}

From my small knowledge its looks like the code converts the untz button presses to monome serial protocol.

But when connected to the pi it doesnt show up as a serial device, which i find quite confusing.

I just saw @okyeron and @szymon_k posting a reply :slight_smile:

Thanks a lot!

I hope some way or another we can fix this one, it just fustrating to having the pseudo monomes laying around without being able to use them.

Many thanks to all for your help!!!

No worries! I wouldnt have even know where to start without your help! Hopefully you will have your fates with you and there will be more news on this :slight_smile:
Thanks!

Edited:

@zebra i have been thinking about what you told me and i had this idea…

Since the untz can output midi note data, could i use a program like bomes midi translator to convert the midi notes to serial data and therefore monome serial protocol?

This is quoted on the bomes translator manual:

So you can easily implement a Serial-to-MIDI converter, and vice versa, with just a few translators, or convert the serial data flow on the fly, or control devices which only have a serial port

I looks like it could be used to convert midi data to serial and viceversa… Im naming it because i have used it in the past and have the software.

Maybe i could convert the midi from the untz to send monome serial commands…

Any thoughts? Is it faisable?

Thanks!

i’m saying: if there is firmware for untz that implements the mext protocol over usb-serial (or any other monome grid protocol), then it should be usable with norns. if it doesn’t work, we need more information about what exactly isn’t working and we can probably make appropriate changes pretty easily.

[ed: and having scanned the source you posted, that does seem to be the case.]

the first step is to answer my question about what, if anything, shows up in /dev on norns, when you plug the untz into the norns. if it is /dev/ttyACM0, then AFAICT the mods to device_monitor.c should work as far as getting norns to attempt to use libmonome to connect to the device. the best way to debug this is to add / uncomment some print statments in device_monitor.c and device_monome.c.

if the norns stack is seeing the device, but libmonome is failing to connect to it, then a new avenue of investigation is called for. the device serial string may not be recognized, and/or the device may not support the default 115200 baudrate. libmonome has special treatment for “arduinome” devices that only support 57600 baud, but it may not be recognizing your device as an arduinome, requiring modification to the device mapping header or something. ([ed: or, looking at untz source, editing the device serial string to start with a40h.])

(btw, serialosc uses libmonome to manage connections as well, so in general this is an important step to figure out.)


i’m also saying: if you want to use untz MIDI device firmware with norns, you can do that too. and if you want it to “act like” a grid device then to me the obvious solution is to do the “translation” right in the lua layer of norns instead of pulling in some other software. the fact that there is already this vport abstraction layer between norns scripts and device APIs, makes such a feature easy to implement.


bome midi translator, you mean this paid software? ok, i dunno. it will not run on linux if that’s what you mean.

1 Like

Hi again @zebra, thanks a lot for your help and time. Im learning on each step and most of this matters are over my knowledge, much appreciated.

Ok, so when i plug my unt into the norns and run:

ls -l /dev

The untz show up as:

crw-rw---- 1 root dialout 166, 1 Nov 10 22:39 ttyACM1

So as you mentioned before the mods to device_monitor.c should work and norns is trying to use libmonome to connect to the untz.

I have opened device_monitor.c and something got my interest, i think it a mistake on my side:

device_monitor.c

// FIXME: these names / paths are really arbitrary.
static struct watch w[DEV_TYPE_COUNT] = {
{
.sub_name = “tty”,
.node_pattern = “/dev/tty*”
},
{
.sub_name = “input”,
.node_pattern = “/dev/input/event*”
},
{
.sub_name = “sound”,
.node_pattern = “/dev/snd/midiCD
},
{
.sub_name = “crow”,
.node_pattern = “/dev/ttyACM*”
}
};

Its seems i wrongly did the modifications to only the Crow part? as in :

.sub_name = “crow” ,

.node_pattern = "/dev/ttyACM"*

and not in:

.sub_name = “tty” ,

.node_pattern = "/dev/tty"*

so it should be:

.sub_name = “tty” ,

.node_pattern = "/dev/ttyACM"*

Also @okyeron suggested that i do a ./waf on the norns code so it sticks to the device monitor, but im lost on how to do that. apologies as i said im not a coder :frowning:
Is that wha you meant by matron code and recompile ??

Ruling this out, i have tried changing the device serial string to a40h as suggested and reuploading the code to the arduino, and plugging the untz back again.

Now the output of ls -l /dev is ttyACM2, which makes sense since i have plugged the untz again.

As you point out, maybe i should try making the untz act as grid doing the translation in lua, again out of my reach at the moment since unfortunately i know nothing about Lua (seems its inevitable that for many reasons i start looking into that)

What is that vport you mention?

Ps: Yes i have used bomes midi translator on a few projects for converting din midi to usb midi and vice versa, also i use it to send midi over ethernet between my computers in the studio to share midi ports.

Thanks a lot for your help and time, hopefully ill find (or learn) a way to get this going.

Cheers!

yes; you have modified the C code for matron (nice! now you’re a coder) but it has to be recompiled and waf is the build system that handles this on norns.

but… the assumptions made in this source are that any ttyACM device is a crow, and any ttyUSB device is monome-serial. so it won’t work without further modifications.

that assumption is embodied here:

in other words, the only mechanism by which this module can distinguish devices is by their path. but untz and crow have identical paths. so we will have to think about this.

at this point i would like to ask for contributions in that area since i don’t have a crow or an untz and don’t particularly want to get into building arduino things just to test this.

1 Like

Thanks for the info and reply.

Well, yes i have very little knowledge of coding, but thanks to this community im learning lots!

Ok, i understand what you mean, so crow and untz have identical paths :frowning:

Well i did not expect that.

I hope some one can chip in and maybe find a solution to grid emulators or devices working with norns (maybe norns 3,0?)

Thanks again, i think have already taken enough of your time!

Many thanks @zebra!

I think there might be an old issue about this but hard for me to dig for it from my phone.

I think device_monitor.c might need some additional logic. My teeny grid shows up as ttyACM so it’s now gonna conflict with crow.

I’ll follow up on this when I’m home from my trip.

1 Like

Thanks a lot @okyeron !

if someone can work on generalizing the ACM interface i’d appreciate it.

the crow has a serial handshake to ensure the device is actually a crow, so it’d be straightforward to abstract the ACM portion.