I found really interesting a small protoboard created by Sparkfun that allows you to easily connect a Pearl (the one made famous by RIM / Blackberry devices) with a microcontroller. This time I choose the LPC2138 from NXP because I also have a complete 2D graphic engine for interfacing the LPC2138 with a Nokia 128×128 LCD with 16 bits per pixel. One issue with this device is that a small movement on the pearl is detected. And sometimes you want to move in a direction but this little ball moves in more than one direction at a time. So the big problem was designing a software able to detect the movements correctly, providing anti bouncing and a way to easily modify how many pulses of the pearl are detected as one movement.
void pearl_Task() { if ((!(PEARL_INPUT_PIN & (1 << PEARL_LEFT_PIN))) && (pearl_state_left == 0)) { pearl_dir_left_changes++; pearl_state_left = 1; } else if (((PEARL_INPUT_PIN & (1 << PEARL_LEFT_PIN))) && (pearl_state_left == 1)) { pearl_dir_left_changes++; pearl_state_left = 0; } if ((!(PEARL_INPUT_PIN & (1 << PEARL_RIGHT_PIN))) && (pearl_state_right == 0)) { pearl_dir_right_changes++; pearl_state_right = 1; } else if (((PEARL_INPUT_PIN & (1 << PEARL_RIGHT_PIN))) && (pearl_state_right == 1)) { pearl_dir_right_changes++; pearl_state_right = 0; } if ((!(PEARL_INPUT_PIN & (1 << PEARL_DOWN_PIN))) && (pearl_state_down == 0)) { pearl_dir_down_changes++; pearl_state_down = 1; } else if (((PEARL_INPUT_PIN & (1 << PEARL_DOWN_PIN))) && (pearl_state_down == 1)) { pearl_dir_down_changes++; pearl_state_down = 0; } if ((!(PEARL_INPUT_PIN & (1 << PEARL_UP_PIN))) && (pearl_state_up == 0)) { pearl_dir_up_changes++; pearl_state_up = 1; } else if (((PEARL_INPUT_PIN & (1 << PEARL_UP_PIN))) && (pearl_state_up == 1)) { pearl_dir_up_changes++; pearl_state_up = 0; } }
This task can be perform in a main loop, or can be called by a timer when it overflows (as I do in my code). The following piece of code is an example of how to ask if a movement in a particular direction was performed.
unsigned char pearl_IsMovingLeft() { if (pearl_dir_left_changes >= PEARL_DIR_LEFT_LIMIT) { pearl_dir_left_changes = 0; return 1; } return 0; }
Where if PEARL_DIR_LEFT_LIMIT is between 3 or 5 and you run the pearl task every 50mSec the movement is quite smooth.
Pearl (Blackberry’s Trackball) Driver [Header]