Serialosc /grid/led/level/map data format

I am trying to (re)write some arduino code to properly set the /grid/led/level/map led intensities.

I’m using the test-grid.maxpat to send a the command (which lights up a grid properly) - but I can’t seem to get the wrangle data correctly in my arduino sketch and I’m stumped on how it’s being sent.

From the osc docs page it says
/grid/led/level/map x_off y_off l[64]

and then the serial.txt info says

pattern:	/prefix/led/level/map x y d[64]
desc:		set 8x8 block of leds levels, with offset
args:		x = x offset, will be floored to multiple of 8 by firmware
			y = y offset, will be floored to multiple of 8 by firmware
			d[64] = intensities
serial:		[0x1A, x, y, d[64]]

is d[64] bitwise data (like with /grid/led/map ) or an array or ?

d[64] is an array of 64 values, from 0-15

is that not working?

to clarify - is d[64] an array of bytes, or integers, or ?

(sorry if this is a stupid question - i suppose this is more of an “iterating data in arduino” problem?)

IIRC, in the serial protocol d[64] is actually an array of 4-bit nybbles. so the varibright LED data is 32 bytes and the whole command to refresh a quad is 35 bytes.

at least that’s what i put here:

if you’re using arduino as a grid host, might be easiest to just use (or adapt) that library
PRs welcome if you find bugs of course :slight_smile:

1 Like

Excellent - I think that helps a bunch.

I’ll try your code as well and see if it works better than what I have so far.

EDIT: Found my problem - the data parsing I was doing was actually just fine. I had some bad evaluation math happening. :frowning_face:

Further followup…

I am getting good results now sending /grid/led/level/map commands to my teensy grid from my Mac (using maxpats). However, when I plug into my raspi-norns, I’m not getting leds lighting up properly (they flash very intermittently).

Any script that lights/dims a specific led works fine for me (like jah/step.lua). But, any of the tehn scripts that do the following do not work.

function gridredraw()
  g:all(0)
  g:led(x,y,val)
  g:refresh()
end

So perhaps I’m still parsing the data wrong, or norns is sending things in a slightly different way than Max/serialosc on my mac?

@zebra can you confirm that norns is sending the level/map data in the same exact way? I can’t make sense of ‘dev_monome_refresh()’ in device_monome.c

Also from the norns docs - the following makes zero sense to a newb (like me). What’s a quad, why is it dirty?

refresh ()
update any dirty quads on this grid device]

EDIT: curious - if I change to the following I can get awake to show leds

function gridredraw()
  g:all(0)
  g:refresh()
  g:led(x,y,val)
  g:refresh()
end

just to be clear, you’re using a DIY grid? on teensy?

yes - it’s based on the adafruit trellis boards and code by another lines user.

gotcha.

well,

norns uses libmonome, which has more layers of abstraction:

/level/map:
[ https://github.com/monome/libmonome/blob/master/src/proto/mext.c#L267 ]

i am pretty confident that the payloads from libmonome and from avr32 driver are identical, though haven’t explicitly verified this for a long time. guess i’d try going in and logging the payload data when pack_nybbles is called. in the link above.

What’s a quad, why is it dirty?

a quad is a block of 8x8 LEDs addressed by a single /grid/led/level/map command. the data for a quad is “dirty” when it has changed and needs to be sent to the device.

1 Like

anyways, if it works but takes 2 refreshes then i’d guess at some kind of mismatch in the serial framing mode. or the rate. or some other reason that the teensy serial rx buffer read works with 2 bytes but doesn’t complete with 35 bytes.

in other words, looking for some difference on the wire, rather than in the payload data. b/c norns is using a linux tty device, and the aleph/euro/arduino version is just using a raw serial port peripheral, probably with waits between bytes.

or yeah i guess a bug in the way norns code uses the dirty flag? i think we would have caught that but i will try to verify.

I’d say it kinda works, but I’m not sure it’s 100%.

however - your responses do give me somewhere to look. (I suspect it could be the g:all(0) causing the problem and not the level/map)

I was being a little flippant about the dirty quads. I thought that was probably what it meant, but the documentation seemed way too obtuse there. :slight_smile:

Thanks a ton for taking the time to answer.

Mostly just commenting so as to make the forum follow this thread.

I’ve been playing with the row, col, and map commands in max and javascript lately, and was very curious how those would translate to norns.

But, hey. While we’re here…
(this is somewhat off topic)

/grid/led/level/row feels less responsive if /sys/rotation is in play. Wondering if that’s real or imagined.
(I designed my app 90 degrees off from where it probably belongs)

I’m probably just forcing an extra translation step onto serialosc, which could be optimized away by restructuring my code to simply face the right direction. But I’m a little nervous that maybe rows are just faster than columns somehow?

I’m not sure if this is a bug or not. My teensy grid is a 128

in /norns/matron/src/device/device_monome.c line 98

if I change

for(int quad = 0; quad < 4; quad++) {

to

for(int quad = 0; quad < 2; quad++) {

my LEDs will light up properly when I hold down a key (otherwise they flash on for a second and go off).

ah ok. sounds like potentially a bug on each side:

  • on the norns side, we shouldn’t be sending all 4 quads unless their contents have actually changed (maybe they have? what script are you using)

  • but on the teensy side, it certainly sounds like it is responding to data for quads [2, 3] in addition to quads [0, 1], which is definitely a bug.

On my teensy - what should I be looking for? Would the quads [2, 3] come through as another chunk of mext 0x1A data (with x, y offsets)?

On norns - this is with earthsea or awake

as mentioned above - any script using the pattern here would have the problem:

  g:all(0)
  g:led(x,y,val)
  g:refresh()

so it feels like a combo of dev_monome_all_led and dev_monome_all_led

Would the quads [2, 3] come through as another chunk of mext 0x1A data (with x, y offsets)?

yes

sorry, right. well, that’s strange. what should happen is that if you change a single led, and send refresh, only a single 35B map message will go out, for whatever quad contains that led. and changing the loop indices should not make a difference.

i’ll have a look at it and open a GH issue.

fantastic. thanks for all the help!