Trackball

Here is a quick demo of using a ‘Blackberry trackball’ with your Pokitto.

The trackball was surprisingly easy to set up for polling on the digital pins.
I used the following for my example, but you can change them if you like.

image

Lets have a little look at the code.

#include "Pokitto.h"
#include "mouse.h"

using PC = Pokitto::Core;
using PD = Pokitto::Display;
using PB = Pokitto::Buttons;

Straight forward, the first two lines will include the Pokittolib and the image data for a mouse pointer. The next three lines basically set up some references to make some of the commands easier to type.

DigitalIn button0 = DigitalIn(EXT0); // Button
DigitalIn ballLeft = DigitalIn(EXT3); // Left
DigitalIn ballRight = DigitalIn(EXT4); // Right
DigitalIn ballUp = DigitalIn(EXT5); // Up
DigitalOut ledGreen = DigitalOut(EXT6); // Green LED
DigitalOut ledWhite = DigitalOut(EXT7); // White LED
DigitalIn ballDown = DigitalIn(EXT8); // Down
DigitalOut ledBlue = DigitalOut(EXT9); // Blue LED
DigitalOut ledRed = DigitalOut(EXT10); // Red LED

First thing to do, is set up all of the input and output pins in the PEX, so that we can read the trackball and light up the LED’s. For ease of reading, I have named every pin in relation to its action. Each being created as either a DigitalIn or DigitalOut. Polling a DigitalIn pin is as simple as ballDown.read() to return either a 0 or a 1.

    PC::begin();
    PD::persistence = false;
    PD::invisiblecolor = 0;

Again, the usual stuff here, begin, set the screen to blank every frame and set the transparent colour for the graphics.

    button0.mode(PullUp); // Button Low active
    ballLeft.mode(PullUp); // Left
    ballRight.mode(PullUp); // Right
    ballUp.mode(PullUp); // Up
    ballDown.mode(PullUp); // Down

    ledGreen.write(LOW); // Green
    ledWhite.write(LOW); // White
    ledBlue.write(LOW); // Blue
    ledRed.write(LOW); // Red

First we set up the pin modes. For this project, they all should be pulled HIGH, letting the trackball pull the pins LOW when it makes changes. This avoids the pins ‘floating’ which can cause flickering values, which we do not want.

    int oldUp, oldDown, oldLeft, oldRight, up, down, left, right;
    int px,py = 0;
    int speed = 3;

    while( PC::isRunning() ){
        PD::update();

Here we create a couple of variables to hold the current state of the input pins, the previous state of the pins, x and y locations for our mouse pointer and the speed of movement.
We also start the loop and update the system, which will draw the screen and capture the start of the d-pad etc.

        up = ballUp.read();
        down = ballDown.read();
        left = ballLeft.read();
        right = ballRight.read();

When reading the trackball, first thing to do is capture the state of all of the input pins. These trackballs work in quite a simple way. When you roll the ball in one direction, the bin associated with it will toggle between HIGH and LOW over and over. So to detect movement, we need to compare these readings with the previous readings over and over again…

        if(up != oldUp){
            oldUp = up;
            py-=speed;
        }
        if(down != oldDown){
            oldDown = down;
            py+=speed;
        }
        if(left != oldLeft){
            oldLeft = left;
            px-=speed;
        }
        if(right != oldRight){
            oldRight = right;
            px+=speed;
        }

As you can see, if the current reading for each direction is different from the previous reading, we change the px or py variables accordingly.

        if(PB::upBtn()){ledRed.write(HIGH);}else{ledRed.write(LOW);}
        if(PB::downBtn()){ledGreen.write(HIGH);}else{ledGreen.write(LOW);}
        if(PB::leftBtn()){ledBlue.write(HIGH);}else{ledBlue.write(LOW);}
        if(button0.read()){ledWhite.write(LOW);}else{ledWhite.write(HIGH);}

Here we check for presses on the Pokitto D-pad and light up the LEDs on the trackball accordingly. Also we check for the trackball button being pressed and light the White LED if detected.

        PD::printf("X: %d, Y: %d\n", px,py);
        PD::drawBitmap(px,py,mouse);
    }

Lastly we print the px and py variables to the screen, and draw the mouse pointer.

Now that you’ve read all of that, here is another version of the same thing,


Only using interrupts instead of constant polling. This results in a much more accurate reading of the ball movement and is also a little easier to code.

10 Likes