Griffin PowerMate as input controller?

Any thoughts on getting one of these to work as an input controller to the Arduino? http://www.griffintechnology.com/products/powermate

Thanks. -J.R.

I have 2 of these, but havent tried interfacing them, so just some general comments on their use.

The knob is continous-rotate. Besides the rotate, theres an led and a pushbutton (the knob it selves).

It uses the hid usb type, so each action sends a "keystroke". Turn left, Turn right, Click, Long click, and the combinations. -Long click may be software handled.

Its made in metal, and theres no easy access to the internals, so the "best" interface way would require a usb host, in an attempt to interface the device trough the hid system.

I think you'll have trouble with this on the Arduino, because it's a USB HID (Human Interface Device), and must be connected to a USB host. The Arduino can't (easily) work as a USB host.

I've worked out a way to use a CD-ROM motor as a spinner control, though. You have to wire up the three hall-effect sensors to some comparators (TLC3704) and to the Arduino. Then, the sketch code reads the three digital inputs and works out the spin.

as Anachrocomputer says, it would not be easy to get the arduino to act as a usb HID host. But you could bypass the USB interface - the bottom of the unit is held on with adhesive. If you carefully open it you should be able to get access to the rotary encoder inside. You could then interface the encoder using the information in the playground : http://www.arduino.cc/playground/Main/RotaryEncoders

Thanks for all the input!

It uses the hid usb type, so each action sends a "keystroke".

As a matter of interest, did you have to install any sort of driver? If not, do you have a way of reading how the device reports itself to the Operating System? (I know how to do this in OS X or Linux if you are on either of those platforms.)

I'm interested because I'd like to implement a similar device and was wondering how the real ones handled it. :-)

--Phil.

No driver, uses standard microsoft one on windows xp (pro sp3).

But you install a program where you map the different functions to macros (mostly keyboard presses).

I dont know how it interfaces with the unit, but the hid system must have a way to interface directly with a specific unit, logitech does it too when calibrating game controllers.

I will check tomorro if I can find a usb spy thing :) Otherwise I also have a ubuntu netbook.

Some ramblings from device properties CM_DEVCAP_SIlENTINSTALL CM_DEVCAP_RAWDEVICEOK CM_DEVCAP_SURPRICEREMOVALOK

VID: 077D PID: 0410 HID_DEVICE_SYSTEM_CONSUMER

Well dont know if this helps, doesnt say much...

I think the OP wanted to use this with his Arduino. I don't want to discourage anyone from trying to write HID host code for the arduino but the easiest way to use the PowerMate is to peel off the plastic cover on the bottom and connect directly to the rotary encoder inside ;)

If it’s of interest to the OP, I actually pulled the rotary encoder from one of my Powermates when I was in a bind. If you don’t mind ripping the powermate to bits, you might be best just connecting to the internal wires and bypassing the usb bits.

The rotary encoder needed four resistors and two caps, and from memory used two i/o lines.

The code which worked ok-ish for me (and of which 98% came from the playground):

#define encoder0PinA  2
#define encoder0PinB  4

volatile unsigned int encoder0Pos = 0;
float encodercalc;
int ledpin = 3;

void setup() { 


  pinMode(encoder0PinA, INPUT); 
  digitalWrite(encoder0PinA, HIGH);       // turn on pullup resistor
  pinMode(encoder0PinB, INPUT); 
  digitalWrite(encoder0PinB, HIGH);       // turn on pullup resistor

  attachInterrupt(0, doEncoder, CHANGE);  // encoder pin on interrupt 0 - pin 2
  Serial.begin (9600);
  Serial.println("start");                // a personal quirk
  Serial.print("?c0");
  Serial.print("?fNo. of revs:");
    Serial.print("?k");
       Serial.print("?BFF");
} 

void loop(){
// do some stuff here - the joy of interrupts is that they take care of themselves
}


void doEncoder(){
  if (digitalRead(encoder0PinA) == HIGH) {   // found a low-to-high on channel A
    if (digitalRead(encoder0PinB) == LOW) {  // check channel B to see which way
                                             // encoder is turning
      encoder0Pos = encoder0Pos - 1;         // CCW
    } 
    else {
      encoder0Pos = encoder0Pos + 1;         // CW
    }
  }
  else                                        // found a high-to-low on channel A
  { 
    if (digitalRead(encoder0PinB) == LOW) {   // check channel B to see which way
                                              // encoder is turning  
      encoder0Pos = encoder0Pos + 1;          // CW
    } 
    else {
      encoder0Pos = encoder0Pos - 1;          // CCW
    }

  }
  Serial.print("?l");
 encodercalc = (float)encoder0Pos / 56.00;
 encodercalc = encodercalc * 100;
  //encodercalc = encoder0Pos;
  if (encoder0Pos < 257) {
    analogWrite(ledpin, encoder0Pos);
  }
  Serial.println (encoder0Pos, DEC);          // debug - remember to comment out
                                              // before final program run
  // you don't want serial slowing down your program if not needed
}

/*  to read the other two transitions - just use another attachInterrupt()
in the setup and duplicate the doEncoder function into say, 
doEncoderA and doEncoderB. 
You also need to move the other encoder wire over to pin 3 (interrupt 1). 
*/

Hope this helps. :slight_smile: