[Solved] PS2 Mouse rotary encoder library

Hey all!!

First of all, let me say thanks… I’ve gotten so many tips and libraries from reading these forums. You all are amazing.

I’m trying to build a Nest-like thermostat with my core. I’ve gotten pretty far; (farther than their example, at least), but I’m struggling with the potentiometer as a reliable / good way to read rotation. Plus, like a real Nest, I’d like the wheel to be continuously variable with a nice smooth feel and software-read rotational position. Sounds like a job for a rotary encoder… right?
Most of the ones on the typical stores are junky and a real, sweet optical rotary encoder is like 30$ on digikey.

Luckily, any old PS2 ball mouse or newer optical with a scroll wheel has a pretty high-res rotary encoder in it!! I took apart an old logitech ball mouse and found the X and Y sensors are just slotted plastic wheels in between an IR LED and a detector. I didn’t want to desolder those components and re-write it in Spark because the PS2 controller already does a nice job of decoding the LEDs and reporting a position… so I just need a PS2 interface for my spark.

I found these two libraries for Arduino, but alas, I have no experience in porting them for Spark. Could someone tell me what I need to do to get started down that path, and which library of the two is better?

Here they are:

Any advice appreciated!

The first link (from playground.arduino) compiles in the Wed IDE with the #include “application.h” statement in the header file.

However, it crashes the spark core… I get a breathing blue status LED and the only way out is to factory reset.

About to try the other library :smile:

I have done this a while ago and it wasn’t too difficult.
Let me have a look where I got my code - but meanwhile you could search the forum for PS/2. You’ll find some threads about PS/2 keyboard support, but this will get you half way to your mouse support too.

The second library also compiles but leaves the core unresponsive (no serial debug messages) if you include application.h and bko’s bitRead and bitWrite (https://community.spark.io/t/is-it-possible-to-use-bitread/2828) functions.

Scruff - thanks for you help.

Just to get you started have a look at @kennethlimcp 's port here


As far as I recall from my mouse project you’d need to send some init info to the mouse. I’m still trying to find my ol’ code :wink:

Yeah, you need to send a reset and defaults command, catching an ACK after each.
I read through the thread where that code is posted… I think the format of the code is better than the libraries I posted earlier but it will need some major re-writing to report mouse data.

To be honest, I’m struggling to understand why the github library isn’t working. The code seems simple enough… I think maybe the bitRead functions from bko aren’t compatible?

I put a Serial print statement inside setup right before the mouse.initialize() function and right after the Serial.begin function. I don’t see it in the serial monitor… which means that either the code doesn’t run at all or the mouse constructor is bad, which is weird, because it looks fine to me… Again, I don’t know much about the architecture of the core (yet).

For reference, I have the PS2 clock and data lines on pins D5 and D6, respectively. Are those bad choices?

Are the types used in the library int? That is 16-bits on most Arduino’s and 32-bits on Spark (which my notes on the bit functions clear say).

I’m trying to change any pin definitions to uint16_t

Hi @jmohin

The datatypes of the pins like D0 or D5 are all OK and you should not change them.

I looked briefly at the library and this code has problematic use of int and needs to converted to uint16_t:

int PS2Mouse::read_movement_x(int status) {
int x = read();
if (bitRead(status, 4)) {
for(int i = 8; i < 16; ++i) {
x |= (1<<i);
return x;
int PS2Mouse::read_movement_y(int status) {
int y = read();
if (bitRead(status, 5)) {
for(int i = 8; i < 16; ++i) {
y |= (1<<i);
return y;

I changed all the ints in that function to uint16, no luck. Then I tried changing any ints which had bit operations on them to uint16, still nothing. Then I just changed ALL the ints to uint16, and still nuthin’
Each time I get the slow breathing Blue LED and no response over serial.

Did you try this with an arduino, and the unaltered library? You are confident that if you connect to Spark, with similar connections, the mouse works? Just checking to see if you were able to get the baseline example code working yourself.

How are you powering the mouse and how are you connecting it to your Spark? The mouse is 5V, no?

1 Like

In addition to the excellent advice from @BulldogLowell above, I would add that it is really easy to get confused about which pin is clock and which is data on the PS/2 connector since it depends on which side you are “looking” at it from. I would double check that too.

The mouse is hooked up to a wall-wart 5V power supply; I’ve been using it for several projects, it works

I have tried switching the clock / data pins several times. If I unplug them entirely from D5/D6 with the spark is still breathing cyan (it does this for a few minutes), I get the red SOS LED immediately (instead of the breathing blue LEDa few minutes later), so clearly, the spark is trying to communicate over those lines, but maybe hanging/failing.

I do not have an arduino to try, unfortunately. I am trying to write my own library because I don’t trust the clock timing in either of these, seeing as how they use a different microcontroller.

and you are using a logic level shifter ?

Nope…these libraries say you shouldn’t need to… but now that I think about it I don’t see any logic-level shifter on the PS2 board unless it’s a lot smaller than I think… so maybe all logic is at 5V? That doesn’t make a ton of sense to me.

So they work connecting say a 3V3 Pro-Mini or a Due (3V3 GPIOs too) ?

Your Spark is 3V3 (albeit, tolerant to 5V on those pins).

Just spitballing here, really.

I’ve now pulled out an old PS/2 mouse and try to port the PS/2 Keyboard lib for the mouse, since my own project is a bit more complicated than I remembered it :wink:

I got the other ones sort of working, but I don’t like them, since they don’t use interrupts :stuck_out_tongue_closed_eyes:

Edit: Don’t like any of them, back to my ol’ project

Update: Got my project running, but interrupts are not very stable yet - it’ll need some more investigation - sorry :worried:

Update: Got the interrupts stable for SYSTEM_MODE(MANUAL) but still got issues with cloud and least siginificant bit not always being read correctly


Great… so excited you are working on this!!! Thanks a billion

1 Like

It’s still work in progress and needs some adjustments of timing, but to get some feel for it you can already have a look at what I’ve got so far

Edit: Timing should now work better/faster - SYSTEM_MODE(AUTOMATIC) seems to not like me, tho’ :worried:, but I don’t give up (yet)