Search code examples
algorithm

Cycling LED Modes using ControllerMate


I'm using ControllerMate with a Nostromo (Belkin) n52 (NOT the te version) Speedpad on an iMac running Snow Leopard.

The official SpeedPad configuration software doesn't run beyond Tiger, or at least, it doesn't run on Snow Leopard due to the kext failing to load properly, hence the attempt at using ControllerMate.

The official SpeedPad configuration software has the capability to load 1 unique set of keys per "page", where there are 4 pages. This ultimately led me to be able to do things like basic key mapping on the first page, key combinations on the second, macro'ing on the third, and I set up some global shortcuts for my music player, and bound those same shortcuts on the last page of the Speedpad.

Pages were represented by the currently lit LED on the unit;
No LEDs On / Red LED On / Green LED On / Blue LED On

I'm attempting to use the Logic functions of ControllerMate in order to recreate this same behavior. Clicking a button bound to this routine will cause the LEDs to start cycling in the order listed above, ultimately circling around and restarting at no LEDs on.

I'm going to explain this as best I can so that the basic principles of programming/logic here could feasibly be answered by any individual here, but I might fail, and you might need to familiarize yourself with ControllerMate first :P.

ControllerMate presents you with a grid, where you simply drag objects in. It's a visual programming canvas. For example, my Canvas has 4 blocks on it currently;

Nostromo SpeedPad 2
Keypad LeftAlt

This is the key that corresponds to the large Orange button above the DPad. It's on the Canvas so I can dump other elements into it, and get elements out of it. It's a basic Input/Output system with snapping elements.

Num Lock

Caps Lock

Scroll Lock

These represent the LEDs. When these blocks turn "on", the related LED on the SpeedPad lights up.

For example, if I connect one Lock block, or all of them, directly to the LeftAlt block, pressing the "LeftAlt" button on the SpeedPad turns on one/all of the LED light(s) for the duration that it's held.

ControllerMate actually has a wonderful guide of explaining the "Blocks" and showing what they look like at http://www.orderedbytes.com/controllermate/help/?show=blocks

The Logic blocks I have to work with are as follows:

AND
NOT
OR
XOR
ON/OFF Gate
ON/OFF Latch
1:2 Selector
Toggle

Most of these are self explanatory already, but just in case they aren't, please consult the above link to get the specific Block Reference (My Rep. currently prevents me from linking each of the above elements).

I'm thinking that I'm going to have success with using a series of Toggles and Gates, but I haven't quite been able to interconnect them properly to consistently behave in a perfect loop of invocation.

Bonus Points if you're really feeling up to it (you'll get an accepted answer for satisfying only the primary question, promise!): Not only a linear On/Off per LED, but a complete permutation of all On/Off combinations;
All Off
Red On Blue Off Green Off
Red On Blue On Green Off
Red On Blue Off Green On
Red On Blue On Green On
Red Off Blue On Green Off
etc.

[edit]
If anyone with suitable rep could create/add the "ControllerMate" tag to this question I'd sure appreciate it.


Solution

  • I figured it all out, it was quite a long time coming. Let's break it into a few different topics;

    (1) Keybinding / Key Representation

    (2) Blocks Used

    (3) Logic

    First, I set up a simple key remap, but that example failed because pressing the Speedpad 02 key, would input it's original mapping (q) and the re-map I defined (w). I started crawling over the ControllerMate Forums, and I stumbled on a great couple of posts, which would make better starting points than the .cmate definition files that are easy to find, but I digress…

    After ripping my hair out looking for a setting I had missed, program preferences, or what have you, I looked on the forums and came across a great thread. After reading it, I took the 30 second and disabled all the buttons for the "keyboard" palette portion and the "mouse" palette portion that didn't actually exist.

    This means disabling all but the 15 numbered keys, plus the orange key, plus the dpad for the keyboard portion, and disabling all the mouse keys for the mouse portion. I'm going to send this new map file to Ken (the ControllerMate developer).

    After doing this, and naming the keys something sane so they're properly represented as the key they're labeled, the remaps work as expected. Speedpad 02 only enter my remaped key of w, and nothing else!

    This first step finally was finished.

    Second and third, I sat down and figured out a creative solution to the LED task;

    I'm using exactly zero of the logic blocks above. I use meta blocks (Key blocks, group blocks) and math.

    When pressing the Orange thumb button, a "accumulator" block runs, from 0 to 3, stepping by 1 each push.

    That accumulator has 3 outlets, each going to a subtraction block. The first subtraction block subtracts 1, the second subtracts 2, the third subtracts 3.

    All of those subtractor blocks connect directly to a "Value Selector". If the value is zero, that particular selector turns on.

    Thus, when I've pushed the orange button once, the accumulator provides a value of 1, which goes to all of the subtractors, but more specifically the one controlling the Red LED subtracts 1, and totals 0, so it's Value Selector enables, which enables the "Num Lock" (Red LED) light.

    The LED Outlets connect to a constant number value block (again, the -1 subtraction stack connection ultimately provides a constant value of 1, the -2 subtraction stack ends up at a constant value of 2, -3 goes to 3.

    All three of these constant value blocks goes to a series of 4 Addition blocks, Red LED/Constant 1 has four outputs, to all four Addition blocks. Blue LED/Constant 2 has four outputs that go to all four Addition blocks, and Green LED/Constant 3 [...].

    Then, a configuration page can be placed on the canvas, in which case I moved the "remap" page onto the canvas, and attached it to an addition->expect 0 value selector block, meaning that if the addition equals zero, that particular value selector is on. When all LEDs are off, the top half constant value blocks are disabled, and don't provide their particular value.

    Now, I just need to figure out what to bind to the other three modes I was so desperately working on.

    The ControllerMate screen showing the blocks implementing the logic explained above