Tuesday, September 13, 2011

Interlink SuperMouse

Perusing the junk I don’t need at our local Goodwill I spied this odd mouse.
08271101
Being a sucker for vintage computing peripherals I had to buy it ($2.99)
08271104
It has two buttons and a pad that seems to function as a joystick.
08271108
I began my investigation by unscrewing the bottom.
08271109
Which yielded nothing except a rusty weight attached to the bottom plate.
08271110
Then I discovered that the mouse was a two piece unit! It just snaps off the base. Note the two channels for the cord in the base, allowing you to orient it with the buttons at the top or bottom.
09131101
It’s an Interlink Electronics SuperMouse. There isn’t a whole lot of information available on the internet about this mouse. I found the CDW page that shows it as being discontinued as of Friday, May 16, 2003. Scrolling down, the page has a tiny bit of detail:


On your desk, on the go, in your hand, three mice in one
SuperMouse is a mouse for today's computing realities--long hours on crowded desktops and quick setups on cramped tray tables. Its desktop cradle fits comfortably under your hand, positioning your fingers for hours of effortless pointing with none of the repetitive wrist motion common to desktop mice and trackballs. SuperMouse is also versatile. Use it at your desk, or pop the portable unit out of the cradle and take it on the road with your notebook computer. It can even be used a a hand-held pointing device. SuperMouse is one tough mouse. It has no rolling parts or mechanical assemblies to gum up or wear out and comes with a limited lifetime warranty.
Compatibility
OS Compatibility: Windows 3.1, 95, 98
Keyboard and mouse options
Connector : Serial or PS/2
Ergonomic : Yes
Mouse scrolling device : None
Mouse type : Mouse
Number of buttons : 2-button
Number of keys : 0
Wireless : No
Warranty Information
Warranty Terms: Limited lifetime warranty


09131102
I pried the rubber pads off of the bottom and found two screws that hold the unit together. As you can see, it’s fairly simple.
09131103
Those two posts actuate little clicky switches on the PCB. The rubber pad bears against the central pointing unit.
09131104
The rubber pad does not make electrical contact with the PCB. I'm not sure whether it functions as a simple switch or as I think is more likely is a pressure sensitive device. There are a number of patents referenced on later Interlink products that seem to hint at that, especially the one for a Force Sensing Pointing Device. But I don't know for sure. If you are insane you can look at patents#: 6084572, 4489302, 5296837, 5302936, 5659334, 5828363.

09131107
Notice the traces are labelled E,S,W,N and if you follow the traces you can see how each one covers a triangular field overlapping with the adjacent ones.
09131105
The underside of the PCB has the connection for the serial cable, resistors, capacitors and a couple of chips.
09131106
I assume this is the one that does the grunt work.
I hooked it up to one of my old PCs and found it worked but was somewhat unresponsive. You can scroll up/down/right/left easily but diagonal scrolling was slow. Of course I didn’t have the proper driver and Windows XP just identified it as a generic device. So it’s hard to say how well it worked on a machine running Windows 98 and what extra features the software enabled. In any case a neat little vintage peripheral.

Monday, August 29, 2011

Cleaning Up The Month’s Photos.

Just putting up some random pictures from August.


benchmess
My bench went through several different messes.
flatpackfail01
The trundle bed I was assembling had an unthreaded nut. No problem to tap it, but normal people would have been annoyed.


DSCN8148
A sunny day at the Oregon coast.
DSCN8146
Children playing in the sand.
DSCN8150
A tiny landslide.


DSCN8151
Brothers.


DSCN8153
Hannah, Felice and Anne.


DSCN8162
I like taking pictures of people taking pictures, Eric.
DSCN8163
I also like taking pictures when people aren’t posing correctly.


hn02
Henry noticed something hanging above the gate to the driveway…


hn01
A bald faced hornet’s nest…yikes!!!! Jim DiGiulio will be coming to vacuum it up.

Sunday, August 14, 2011

Steam Up 2011

One of our family traditions is the annual visit to the Brooks Steam Up. 08131101
The Flying Merkel.

08131102
081311030813110408131105
The annual picture in front of the big cat.

08131106
08131107081311080813110908131110
I love Stirling engines and fans.




0813111108131112081311130813111408131115
Recoiless rifle jeep.

08131116
Tanks for the memories.

0813111708131118
On the electric trolley.

0813111908131120






We had a great day.




Friday, July 29, 2011

Remote Power Switch For A Computer, Part 2

UPDATE! See end of post for code change made on 08/04/11
With the circuit working al I needed to do was install it on the HTPC…

07280117
For power I could have grafted into the ATX power supply wires as Simerec does (PDF) but I found that the Biostar A780L3L motherboard I used in the HTPC could supply standby power to the USB ports by moving a jumper. This is obviously much easier. Another alternative is to use a powered USB hub to power the Teensy when the PC is off. Notice the yellow power cord attached to the motherboard as well.

07280118
The HTPC pulled apart for testing, as you can see from the TV, the PC is on.

07280119
Satisfied that it all works, I set to work duplicating the circuit on a prototyping perfboard from Radioshack. Note that I have a couple of Teensy-s. $16.00 each is so cheap for what they can do.
07280120
I soldered pins to the Teensy (for $3.00 they will do it for you…) and soldered headers to the perfboard.

07280121
Soldering…I am still learning this skill.

07280122
Slowly moving everything over. Note I had to re-label the perfboard as I didn’t pay attention and had it backwards…

07280123
All done. Please don’t make fun of my poor layout.

07280124
Testing again. Such a mess in my shop.

07280125
The last item was a “Y” cable for the power switch so I could either power on the PC with the switch or the remote. I used some ethernet twisted pair wires.

07280126
I needed a male pin.

07280127
Bent…

07280129
Soldered and heat shrink to insulate the wires from each other.

07280130
Then some heat shrink over that to stiffen it up.

07280131
The finished cable.

07280132
I mounted the board on a piece of aluminum. This is semi-temporary until I figure out an enclosure. I’m thinking a transparent plastic box.

07280133
Set up on top of the HTPC. I could mount it inside the empty 5.25” bay, but I want to leave it out. I can change things, easily reprogram, etc. as well as having a monument to my poor layout and soldering skills.

07280134
The power cable snakes in through a vent in the side.

Now I just turn the PC on while laying ensconced in the comfort of my bed. It’s a lot of work being lazy.
I added some functionality to the code. The remote also emulates the arrow keys, enter key, mouse (R/L, U/D only), right and left mouse buttons, scroll wheel, CTRL++ and CTRL—for screen magnification in Internet Explorer (and other browsers), it will also launch Internet Explorer directly into Hulu, launch Media Center, Media Player. I still have a few buttons left over.
remotemap02
Here’s the code as it stands right now:




#include <IRremote.h>


const int RECV_PIN = 6; // pin that the IR receiver is on
IRrecv irrecv(RECV_PIN); // receive IR on that pin


decode_results results; // the code sent by the remote
int relayPin = 1; // pin out for relay pin and LED


void setup()
{
Serial.begin(9600);
irrecv.enableIRIn(); // Start the receiver

pinMode(relayPin, OUTPUT); // set the pin for the relay.
digitalWrite(relayPin, LOW); // turn off the relay.
}


void loop() { // main program loop

if (irrecv.decode(&results)) { // if a result is received, put it in results

if (results.value != 0) { //this prints the remote value to the serial monitor if value received.
Serial.println(results.value); // print to serial monitor
delay(25); // 25ms delay. This can probably be decreased to 16ms per 62.5kps, but I don't know if I want it polling constantly?
}

if (results.value == 332 results.value == 2380) { // Power button pressed
digitalWrite(relayPin, HIGH); // actuate the relay to turn on or off power
delay(500); // waits for a second
digitalWrite(relayPin, LOW); // stop relay
delay(10000); // waits for 10 seconds, seems like more.
}

if (results.value == 2421 results.value == 373) { // Play, UP arrow
Keyboard.set_key1(KEY_UP); // set key up arrow
Keyboard.send_now(); //send up arrow
Keyboard.set_key1(0); // set key blank
Keyboard.send_now(); // release key
}

if (results.value == 2422 results.value == 374) { // stop, DOWN arrow
Keyboard.set_key1(KEY_DOWN); // set key down arrow
Keyboard.send_now(); //send up arrow
Keyboard.set_key1(0); // set key blank
Keyboard.send_now(); // release key
}

if (results.value == 2418 results.value == 370) { // rew left arrow
Keyboard.set_key1(KEY_LEFT); // set key left arrow
Keyboard.send_now(); //send left arrow
Keyboard.set_key1(0); // set key blank
Keyboard.send_now(); // release key
}

if (results.value == 2420 results.value == 372) { // FFWD right arrow
Keyboard.set_key1(KEY_RIGHT); // set key right arrow
Keyboard.send_now(); //send right arrow
Keyboard.set_key1(0); // set key blank
Keyboard.send_now(); // release key
}

if (results.value == 2397 results.value == 349) { // menu open IE with HULU
Keyboard.set_modifier(MODIFIERKEY_GUI); // winkey
Keyboard.send_now(); //send keypress
Keyboard.set_key1(KEY_R); // winkey+r
Keyboard.send_now(); //send send keypress
Keyboard.set_modifier(0); // set winkey key blank
Keyboard.set_key1(0); // set key blank
Keyboard.send_now(); // release key
delay(100); // 100ms delay. seems to work.
Keyboard.println("iexplore www.hulu.com"); // enter that in the run box as a line "ln"
}

if (results.value == 2417 results.value == 369) { // clear open media player.
Keyboard.set_modifier(MODIFIERKEY_GUI); // winkey
Keyboard.send_now(); //send keypress
Keyboard.set_key1(KEY_R); // winkey+r
Keyboard.send_now(); //send send keypress
Keyboard.set_modifier(0); // set winkey key blank
Keyboard.set_key1(0); // set key blank
Keyboard.send_now(); // release key
delay(100); // 100ms delay. seems to work.
Keyboard.println("wmplayer"); // enter that in the run box as a line "ln"
delay(100); // 100ms delay. seems to work.
}

if (results.value == 2383 results.value == 335) { // status/exit hit enter!
Keyboard.set_key1(KEY_ENTER); // enter
Keyboard.send_now(); //send send keypress
Keyboard.set_key1(0); // set key blank
Keyboard.send_now(); // release key
}

//mouse! A very slow and annoying mouse...
if (results.value == 2370 results.value == 322) { // 2 up
Mouse.move(0, -10);
}

if (results.value == 2376 results.value == 328) { // 8 down
Mouse.move(0, 10);
}

if (results.value == 2372 results.value == 324) { // 4 left
Mouse.move(-10, 0);
}

if (results.value == 2374 results.value == 326) { // 6 right
Mouse.move(10, 0);
}

if (results.value == 2369 results.value == 321) { // 1 left click
Mouse.set_buttons(1, 0, 0);
Mouse.set_buttons(0, 0, 0);
delay(100); // 100ms delay. seems to work.
}

if (results.value == 2371 results.value == 323) { // 3 right click
Mouse.set_buttons(0, 0, 1);
Mouse.set_buttons(0, 0, 0);
delay(100); // 100ms delay. seems to work.
}

if (results.value == 2400 results.value == 352) { // ch up scroll up
Mouse.scroll(3);
}


if (results.value == 2401 results.value == 353) { // ch down scroll down
Mouse.scroll(-3);
}

//end mouse!


if (results.value == 2423 results.value == 375) { // rec/otr opens media center, somewhat convoluted
Keyboard.set_modifier(MODIFIERKEY_GUI); // winkey
Keyboard.send_now(); //send keypress
Keyboard.set_key1(KEY_R); // winkey+r
Keyboard.send_now(); //send send keypress
Keyboard.set_modifier(0); // set winkey key blank
Keyboard.set_key1(0); // set key blank
Keyboard.send_now(); // release key
delay(100); // 100ms delay. seems to work.
Keyboard.print("%windir%"); // enter that in the run box as a line "ln"
Keyboard.set_key1(KEY_BACKSLASH); // backslash
Keyboard.send_now(); //send send keypress
Keyboard.set_key1(0); // set key blank
Keyboard.send_now(); // release key
Keyboard.print("ehome"); // enter that in the run box as a line "ln"
Keyboard.set_key1(KEY_BACKSLASH); // backslash
Keyboard.send_now(); //send send keypress
Keyboard.set_key1(0); // set key blank
Keyboard.send_now(); // release key
Keyboard.println("ehshell.exe"); // enter that in the run box as a line "ln"
delay(100); // 100ms delay. seems to work.
}

if (results.value == 2426 results.value == 378) { // speed ctrl-- size
Keyboard.set_modifier(MODIFIERKEY_CTRL); // ctrl
Keyboard.send_now(); //send keypress
Keyboard.set_key1(KEY_MINUS); // - key
Keyboard.send_now(); //send keypress
Keyboard.send_now(); //send keypress second time
Keyboard.set_modifier(0); // set ctrl key blank
Keyboard.set_key1(0); // set key blank
Keyboard.send_now(); // release key
delay(100); // 100ms delay. seems to work.
}

if (results.value == 2409 results.value == 361) { // still/pause ctrl++ size
Keyboard.set_modifier(MODIFIERKEY_CTRL); // ctrl
Keyboard.send_now(); //send keypress
Keyboard.set_key1(KEYPAD_PLUS); // + key
Keyboard.send_now(); //send keypress
Keyboard.send_now(); //send keypress second time
Keyboard.set_modifier(0); // set ctrl key blank
Keyboard.set_key1(0); // set key blank
Keyboard.send_now(); // release key
delay(100); // 100ms delay. seems to work.
}

irrecv.resume(); // Receive the next value
}


}


This keyboard and mouse emulation can be used for projects like the Awesome Button or something more evil like the Rubber Ducky. The Hak5 Rubber Ducky project is where I first heard of the Teensy. This same circuit could be used for all sorts of automation and/or practical jokes. I love the Teensy.

EDIT 08/04/11
I found that the remote wasn't working every day or so. I spent some time puzzling over this, testing all the wiring, but couldn't find a solution. Then it occurred to me that I was writing to the serial monitor every time it received an IR code. This could somehow fill whatever output buffer it has up. I was unable to find any reference to a problem like this, and it still may not be the problem, but commenting out this line:

Serial.println(results.value); // print to serial monitor

seems to have fixed the problem and I have not had a similar failure to communicate. Checking what other remotes were picked up, it seems as though the Roku remote puts out a very large number each keypress, I forget exactly but at least 6 or 7 digits. I often press the Roku buttons 20 or 30 times when surfing at night. So that's a lot of data that might have been piling up. Or not. I'll keep an eye on the problem over time. (As of 08/16 it's working perfectly!)