Dev question: receiving tilt info from SerialOSC

  • I'm trying to get my head around tilt info from the monome but there's a couple of things that are confusing me...

    The data comes back in the format of /tilt n x y z

    n = Sensor number. Do any monomes have more than one sensor? What is the difference between sensors?

    x, y & z should be 8bit values. But I'm seeing a greater range than that. If I try in the test patch it sometimes gets up to 270-something when the monome is on it's edge. What's the proper range or is this a bug?

    I've been testing with a current edition 256.


  • i don't have technical answers, but on a practical level:

    all tilt sensors will be at n=0. there's 3 other ADC converter inputs available on the board in case of someone wanting to add some extras but i haven't seen or heard of anything of the like (probably because it's not really documented).

    you're right about not being 8bit, and the number can shoot over 300 if you move it quickly. practically speaking if you assume [-270,270] and truncate values to that (i'm sure 256 would be fine if it's more efficient) i think you'd do pretty well. on top of that the z-axis has an offset into the negative range which i don't understand either (perhaps something to do with gravity?!).

    i think it's difficult to describe the maximum output level as it's dependent on just how fast you think a human can rotate the thing!

    the only issue you might run into regarding development is that older devices use a less accurate and differently ranged sensor. i can't remember the range values but i can dig them up if that'd help.

  • thanks for the quick reply!

    definitely seems more complicated than I thought it would be though hmm

    I just plugged a gs128 in and the x & y values were totally different in range and zero point (ie, what it reads flat on the table). And there is no z value.

    do you know if there are any example apps that deal with these differences in a smart way?

  • there's only ever been one main patch that people have used in the past.

    basic idea:
    - first calibrate the device by tilting to all angles (capture max/mins), then place flat and 'zero' the values to that point.
    - then the calibrated values are scaled and sent to accumulators such that if you tilt it toward you the value shifts in one direction, away from you is the other. flat on a surface doesn't change the value.
    - then the input to the accumulators would be gated by a key press so you only counted when explicitly doing so.

    i put together a patch last month called 'angles' that does a stripped down (but less complicated) version of the same thing by assuming 'flat' is at 0, and assuming max/min of 270. then if a value outside the range was received it would push out the limits by which the values were scaled.

    i also found adding a deadzone (ignoring the few values around 0) helped make it much less erratic when placed on a flatish surface. smoothing (20-100ms) is also nice to avoid too noisey a signal.

    i remember a long time ago people talking about navigating between pages of applications by tilting the box in a given direction (look for a value over the threshold, change page, wait for return to flat, reactivate), but this was back with the 40h that had a much lower sensitivity tilt sensor that users installed themselves.

    not sure how else i can help??

  • that's all great info thanks. always good to hear how others have solved things before going off on my own tangent. i guess i was hoping to avoid the user having to calibrate but maybe it's the only reliable way without have a big table of all the different monome types & ranges etc.

  • there's only 2 different tilt sensors (to my knowledge). everything from the original series 64 through to the 2011 grids used the same tilt sensor which should put out roughly similar values.

    all the 2012/13 models use a much higher sensitivity sensor which includes the z-axis.

    so it's only 2 sets of values.

    agreed that there are some people that might like it otherwise but the simplicity of not needing to calibrate is a really positive thing i think. it would be possible to provide a 'zero' that was not flat.

    that being said, even daedelus uses his 64 flat on the table when not in use. i can't imagine if you're going to the trouble of setting the device on an angle for the audience to see, that you'd be picking up/down and replacing on the same spot?

    ^^ clearly my personal inclination is to have minimal user setup required. perhaps a 're-calibrate' function could be added for alternate arrangements, but i think majority of users appreciate 'plug and play' usability.

  • Ah cool if there's only two sensor types and I can tell them apart by the presence of Z data then that seems good. I think a calibrate to 'center' would still be useful as I've noticed my monome at least does not sit at zero when it's flat (perhaps the sensor isn't mounted perfectly flat).

  • yeah - the sensors are so sensitive it's very hard to get them totally flat in the enclosure! that being said it should be pretty damn close, so if you throw away the few values around zero it might suffice?

    excited to see what you do with tilt!

  • hahha... and the resident troll comes out! definitely appreciate that there might be 1 person that uses the function, but....

    i'm dubious of the accuracy in tilt control one can achieve while holding it. i know i have bad spatial perception, but i find it very difficult to hold the device on an angle and make the numbers drift less than 10ish values. this is where my 'close-enough-is-good-enough' approach comes from with tilt.

    i'd love to proven wrong though! have someone playing a slick theremin melody (w/ velocity!) by tilting their monome!! you could even attach the z-axis to trigger drum loops (or airhorns)?!


  • btw, perhaps it's good to get some of this info added into the tech docs? update what is there regarding the value range and mention the differences between monomes, for future devs :)

  • Think I have something pretty solid for this now, my approach being:
    - When the monome is connected, 'calibrate' to check for Z data (ie, what sensor type do we have) and find the center point. This waits for and stores 12 tilt update msgs then does some noise removal as I was seeing a few random 0 values just after connecting that were throwing things off.
    - If the user for some reason needs to recalibrate they can just re-connect (don't wave the monome around while connecting it!)
    - Ranges are predefined but different for each sensor type.
    - The axis is flipped on Y between old and new sensors so I make those the same.
    - Ignore a 'dead zone' around the center (differs for each sensor type).
    - Smooth the data just a tiny bit with a real simple low pass filter. Could be smoothed more but it's nice that it's responsive to quick movements.

    Here's some awkward one-handed tilting/filming:

    Thanks for all the help!

  • this is great! love the clip as well — the seamless switch between devices is really nice too.

    like your idea of using the presence of a z-axis as the way to determine which device. i've previously used a regular expression to determine it from the reported device name, but i prefer your method that essentially queries the hardware directly.

    it's a good point about the axis being flipped — i should incorporate that into my patch.

    the calibration on connect is a nice idea too. kind of a secret handshake.

    are you assuming the input limits of the sensor, is there more calibration that goes on? i quite like the idea of just forcing it to a certain map. reduces the chance of a strange motion occurrence (dropping..) throwing out the values. are you mapping values outside the range to the coded limit?

    sorry for all the q's - but this is an area i've been working on a little lately as well and curious to hear a perspective from another developer who's trying to make tilt expressive and useful!

  • Glad to help a little in return!

    One little note about detecting the Z data: I did find that if my gs128 is sat on a soft surface totally still (the sofa) then sometimes it will simply send no data until it is moved. With this in mind, if after a timeout of 5 seconds I haven't received any tilt msgs at all I just assume it's the old sensor type. I couldn't ever get the new sensor to not send data.

    For the limits I just picked values that were a bit less than totally tilting to monome on edge slowly. Older sensors get ±35 and newer ones are ±245 from the calibrated center/dead zone. Anything above that is just cut off to the max. Another note: if someone calibrates to a fairly extreme angle they may not be able to get the full range, but I thought that made more sense then having them invert the monome to get there.

    Dead zone for old sensors is ±2 and new ones its ±8. Obviously all these values might need tweaking.

    Honestly, I think it would be more logical for some of these differences to be handled by SerialOSC as I would have struggled to make it work on both types without having the hardware to hand, but maybe there's too many patches already using the current protocol.

    And here's a more musical vid:
    You can download it and see how it feels now too:

    I think I might end up using it more than I expected actually, is pretty fun tilting :)