I've removed the rotary encoder from the scroll button of a defect mouse. Let's see how we can use that in a microcontroller design.

In post 1, I wired up the electronics.

In this one, I'm capturing the encoder's info on a Cypress PSoC4.


Photo 12-07-15 21 16 33.jpg

The Firmware


My original plan was to use another microcontroller as development platform. But this comment from DAB made me change my mind.

I'm using the Cypress PSoC4 BLE development kit. The BLE part isn't active in my design (although it would be easy to publish the encoder's data via BLE - maybe something for a follow up blog.



The Cypress PSoC Creator (their IDE) comes with a neat Quadrature Decoding example. It doesn't even need a rotary (or other) encoder. It generates the signals using the on board PWM modules.

I took it as a start, but replaced the on-chip generated signals with the real hardware encoder encoder outputs.

In my code, I added some instructions to read the decoder counter value. That's the data that I'm really after.

Because my needs are so close to that example, I started off with that:


I searched for a Quadrature example, and loaded it to the IDE. You can choose your favorite one out of the two create buttons.



Once the project is created, take care that you select the right device.

I found the right device name in the Quick Start leaflet of my dev kit.

I then adapted the routing so that it fits my boards layout. The PDF file that's loaded in your IDE when you create the project has good info on that:

I kept the assignments for encoder PIN A and Pin B. I had to change the green LED assignment to the green pin of the RGB LED mounted on my kit.

Content from the QuadDecExample documentation.


That LED is the only on-board route to change. In the next section I'll describe the external connections. But as mentioned above, I haven't altered them.


Changes to the example C code.


Almost none. I removed the on-chip quadrature signal generation, and replaced it by a few lines to read the decoded count.

Because I just want to show that the concept works, I just put a check in there to see if my movements brought the counter to a multiple of 10.

That allows me to put a breakpoint in my code where I can read back the counter (logging PSoC info to the IDE console is somewhat involved, otherwise I would just have used a printf() instead).



// ...

    /* Set index trigger */
    QuadDec_TriggerCommand(QuadDec_MASK, QuadDec_CMD_RELOAD);

    uint32_t oldcount = QuadDec_ReadCounter();

//        PhiAbGeneration(CNT_PULSE); // I COMMENTED THIS OUT
        uint32_t count = QuadDec_ReadCounter();
        if (! (count % 10) && (count != oldcount) ) { // each 10 counts
            oldcount = count; // BREAKPOINT POSITION

// ...



That's it. You can now compile and debug the program.

Put a breakpoint on line 13, and add count to your watch window.

The program will halt whenever you reached a count that's dividable by 10. And you can evaluate in the watch display if the encoder really counted up or down as desired.


Wiring the Hardware


Look back at my first post to check how to components are wired up.

Then connect the encoder with the board.

Ground to Ground, 3.3V to 3.3V,

PINA to P0[1], PINB to p0[0].


Connect the kit, start the debugger and check if the execution breaks after a few turns left or right.


Part 1: Electronics
Part 2: Capturing Input on Cypress PSoC4
Part 3: Capturing Input on an Arduino
Part 4: Capturing Input on a Texas Instruments Hercules LaunchPad with eQEP
Part 5: Capturing Input on an FPGA
Real World Application: Hercules LaunchPad and GaN FETs: Control Big Power with a Flimsy Mouse Scroll Wheel