Sending data to HID device (Snyderphonics Manta)

Hi all,

I recently acquired a Manta controller. SC sees this as an HID device. I’m able to read sensor data into SC, but am having trouble sending data to it (e.g. to change sensor behavior from momentary to toggle). I communicated with Jeff Snyder, who relayed details on the internal specs, but he’s not a SC user and I can’t quite translate his info into usable code. Some excerpted details from him:

To send data to the manta to control the LEDs and the different
special modes of operation: The 2nd edition manta wants a 16-byte report.

byte 1-6: amber lights for hex pads
byte 7: amber lights for function buttons
byte 8-9: slider LEDs
byte 10: control byte, see below
byte 11-16: red lights for hex pads

byte 10:
bit 0 HEX_EXT // hexagon and function button LEDs computer controlled
bit 1 SLIDER_EXT // slider LEDs computer controlled
bit 2 TURBO // scan only the bottom 16 sensors at a faster, but less accurate, scan rate
bit 3 RAW_MODE // send the actual capacitance measurements the manta is taking
bit 4 HI_RES // scan only sensors 7 and 8 at slow, accurate rate with higher resolution (DEPRECATED IN 2nd ED)
bit 5 BUTTON_CTRL // only the function buttons respond to computer control

My code looks like this:

(
HID.closeAll;
~mantaInfo = HID.findAvailable.select({arg n; n.vendorName == "Snyderphonics"}).asList.at(0);
~manta = HID.open(~mantaInfo.vendorID, ~mantaInfo.productID, ~mantaInfo.path);
e = ~manta.elements;
)

//e is an Identity dictionary of the Manta's 66 HID elements

~manta.postOutputElements; //element 65, the last one, is the only one returned here, so I assume this is the element that "listens" for information from the computer

e[65].value_(1); //I've tried zero and lots of different positive values — they all seem to do nothing

e[65].value_(-1); //lots of different negative values turn all the Manta's LEDs on, and device communication is interrupted (presumably because it's drawing too much power). I need to physically disconnect and reconnect it at this point. I get this in the post window:

/*
device thread interrupted 
HID: closing device 0
*/

e[65].value_([1,0]); //Arrays produce the following error:

/*
ERROR: Primitive '_HID_API_SetElementOutput' failed.
Wrong type.
RECEIVER: HID
*/

Right now, I’m just trying to do something super basic, like turn a hex sensor’s amber LED on. I have a feeling I’m just not formatting the data correctly, and maybe should be using Int8Array or something like that. But mostly I’m pretty lost. I’m aware of the Manta quark and briefly looked at it, but I’d like to be able to do this with the vanilla library. Does anyone have any experience here?

Eli

I have no experience with this. However what happens if you try…

e[65].value_( Int16Array([127])[0] );

Which might turn on the first light?

That produces an error:

^^ The preceding error dump is for ERROR: Primitive ‘_BasicNew’ failed.
Index not an Integer
RECEIVER: Int16Array

In fact, just the value expression itself:

Int16Array([127])[0]

Produces the same error. Perhaps you meant to suggest something slightly different?

I can’t use the Manta anymore because it triggers my autoimmune condition (allergy to metal). Oh the joys being an adult.

The Manta quark talks to the MantaCocoa app, which was written by Jan T vol Faulkenstein very long ago. I am certain it no longer works. Most recently, I used Gene Kogan’s MantaOSC, which you can talk to from SC. MantaOSC is written in OpenFrameworks, so if for some reason you don’t want to use it, you could look at the source code and see how it is sending the messages. But I think it may be your best option.

Sorry, I always forget you can’t start an Array like that… I meant something more like…

a = Int16Array.newClear(1);
a[0] = 127;

e[65].value_( a[0] );

See if that works?

Reasoning being…
according to the doc you posted Manta takes a 16byte report. You can’t make a 16byte value in sc unless it is an array.
First byte is a light control so 127 should set it on full.
It depends how the backend HID c++ class is written though, if it does any type casting then you cannot do it in supercollider. I don’t think the manta is following the protocol properly as each light or control should be its own element (I think??).

But it would be easier (hopefully) to write something in openframeworks using ofSerial and just send it osc using ofxOsc.


ofSerial device;
uint8_t bytesToWrite[16] = {0, 127 /* ... 16 elements for the 16 bytes. ..*/ };
device.writeBytes( &bytesToWrite[0], 16 );

Thanks Sam – The manta quark was one of the first things I tried and quickly dismissed. MantaOSC is working, though. It has a few quirks, but I can work with it. I’m poking through the source code and can’t quite find the relevant parts for translating between HID/OSC, but then again I don’t really know what I’m looking for. It doesn’t give me the full control I’m looking for (e.g. no access to the 10th byte for manta behavior control) but I can hack stuff with SC code, for example “tricking” the manta into being in toggle mode:

(
m = Array.fill(48, {0});
~manta = NetAddr.new("127.0.0.1", 2880);
OSCdef.new(\toggler, {
	arg msg;
	var i = msg[1]; //hex index
	m[i] = 1-(m[i]);
	~manta.sendMsg('/manta/led/pad', i, m[i] * 2);
}, '/manta/padOn', nil, 12347
)
)

The Int16Array approach still doesn’t work – no errors, no manta activity – Jordan, I don’t know what you mean by ‘type casting’ but I think you are correct that there is some sort of design mismatch between the SC HID class family and how the manta is implemented as an HID device – i.e. It needs an array and SC can’t send one.

Thanks both for the help. I think I’m in good shape. Didn’t know about the metal allergy, sorry to hear — what a drag.

Eli

Exactly, and you get the same thing. As long has your SC code parses the data correctly and the Manta looks right, you are good.

Ahhhh…I miss my Manta.

Sam

I tried something similar some years ago but couldn’t get it to work. I was advised that doing this in sc probably would be less efficient than running the Max or Pd object in the background, sending OSC to sclang. So, that’s what i’ve been doing on my mac. Switching to Linux last year forced me to convert the Max patch to Pd but that version of the manta object seems more sluggish. Yesterday, i converted my sc class to MantaOSC. This actually seems like the best solution so far. It also runs on my Norns!

As of now, i’m starting MantaOSC with a unixCmd in sc. Not sure of this is the best practice. Maybe better to have it auto starting when the Manta is plugged in with an udev rule or something.