IR LED Array Module v1.0 - API suggestion thread

All,

OK, so now that I’ve got several of the Devhammer IR LED Array modules assembled, it’s time for me to finish up the driver.

Ideally, I want to keep the API as simple as possible. At its simplest, I could just provide a single method, Send, that takes an array of uints for the IR pulses, and call it a day. But I figured it would be best to take the pulse of the community and see what those who will be using the module think the API should look like.

So now is your opportunity to influence the development of the driver API. And if there are folks who are interested in helping write it, I can always put the code up somewhere so we can collaborate.

Are you incorporating any kind of consumer IR protocol (Consumer IR - Wikipedia) like Sony’s? Sounds like your leaving that up to the user, which is fine, but it would be nice to design in some kind of interface or abstract class that would let us easily build stuff like this on top of your code.

@ ransomhall

No, I hadn’t really considered that, though I was giving some thought to adding an extended API for the Syma S107 line of IR helicopters, since that’s what I’m using mine for. :slight_smile:

So, are you thinking something like an interface that would have methods for individual IR commands like Play, Stop, FF, etc.? Perhaps I could set it up so that you just provide an XML or JSON doc with the corresponding commands?

No, not actually mapping all the way to the button function, but instead…

Yes! One of my first projects on a Domino was controlling it with a CIR remote that used the Sony protocol. I hardcoded the transmitted integer values to functions on the Domino, but never got around to doing something like an XML map.

Pie in the sky:

The community could build up a library of these maps for various common remotes (the Sony protocol is the most popular). If we were really motivated, we could make a UI that built the XML auto-magically. Bonus - this effort will keep that many more of these things out of the landfill :slight_smile:

BTW - these are ideas to keep in mind when doing v1 of the driver, and not anything that needs to be in there now… I"ve got my hands full trying to keep up with Gralin on the XBee stuff.

I think that implementing specific IR protocols is a waste of precious time… User should provide the timings array and nothing more. If you want to ease the pain you can hard code some timings arrays and provide them as static members of your API (like IRCodes.Sony.Play). You can then learn all code from some Sony remote, save them to file or hard code to source.

Count my vote for an XML file.

And for v1.1 the ability to load multiple XMLs. I’m thinking something like:

IRCodeMap sonyIRCodeMap = new IRCodeMap(\sony.xml");
irmodule.SendCommand(sonyIRCodeMap, "Play");

This way you could also define an IRCodeMap in code.

Addendum - the XML function mapping does not need to be part of the driver. It can live in its own library. As long as it is an OSS project, we can all contribute. Another codeplex project maybe?

@ MischaBoender

I like that, and thanks for the usage example, as that helps me visualize it better.

So the driver could start with a single method, SendCommand, that takes an array of uints for the timings, and then later add an overload that takes an instance of IRCodeMap, and a command name. That way I wouldn’t need to define an exhaustive list of commands in the API, they’d just be mapped automatically in the XML file.

I would recommend that you just provide a way to pass the timings array and then if you want to provide the XML interface or whatever later then it could be made available as a separate library that extends it using extension methods. Remember, space is critical on these devices (maybe not so much on Gadgeteer?) and adding functions that may not be used by all is not necesarily being helpful. :wink:

@ ianlee74

Agreed…want to keep the driver API simple and spartan. But remember that Gadgeteer is also about higher-level abstractions, so there is some expectation that the API isn’t low-level.

But I agree that starting with a very basic driver and iterating is a good way to go.

After thinking this through in Visual Studio I agree on a “simple and spartan” driver, and my solution would bring dependencies.

Personally, I would like to see a more “newbe” friendly API. So my next idea was to replace the IRCodeMap type with a HashTable. This opens the way for a IRCodeMap helper class that inherits the HashTable and extends it with a ReadXML() method.

But simplifieng it even further I came up with a IRCodeMap : HashTable class with a GetCommand(String Name) method that returns the uint array.

Usage example:

IRCodeMap sonyIRCodeMap = new IRCodeMap(\sony.xml");
irmodule.SendCommand(sonyIRCodeMap.GetCommand("Play"));

@ MischaBoender

OK, so that works great for discrete commands like consumer IR stuff (play, pause, etc.).

Now, let me throw this at you…controlling something like an IR helicopter requires sending compound commands (throttle, pitch, yaw, trim, etc.), all of which can be any value within a given range, and the range can vary depending on the specific protocol. For example, the Syma S107 protocol is pretty straightforward, using 8 bits for throttle, pitch, and yaw (though not necessarily in that order), with a possible value of 0-127 for each.

It’s fairly simple, once you’ve put together the sequence of bits, to convert those to a uint array with the appropriate high/low values in terms of pulse length, but the question becomes, where does the logic live that converts from the individual control values to the IR command?

My initial thought was to simply punt the issue, and have an overload of SendCommand that simply takes the unit array, and possibly the carrier frequency, and keep the actual protocol logic separate from the IR sending. But again, given that one point of Gadgeteer is to abstract some of the low-level stuff as much as possible, I’d really love to make it easier to implement.

Thoughts?

Thoughts… What about a basic driver with just the SendCommand that takes a uint array and an extended driver that inherits the basic driver and extends it with more specific funtions?