Use a Sparkfun Blackberry Trackball Breakout Board as a mouse.

Dependencies:   mbed BBTrackball

Files at this revision

API Documentation at this revision

Comitter:
AdamGreen
Date:
Sun Dec 11 05:38:54 2011 +0000
Commit message:
Initial version.

Changed in this revision

BBTrackball.lib Show annotated file Show diff for this revision Revisions of this file
USBDevice.lib Show annotated file Show diff for this revision Revisions of this file
acceleration.cpp Show annotated file Show diff for this revision Revisions of this file
acceleration.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BBTrackball.lib	Sun Dec 11 05:38:54 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/AdamGreen/code/BBTrackball/#7715a78a7175
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice.lib	Sun Dec 11 05:38:54 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/samux/code/USBDevice/#f3327d71595f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/acceleration.cpp	Sun Dec 11 05:38:54 2011 +0000
@@ -0,0 +1,141 @@
+/* Copyright 2011 Adam Green (http://mbed.org/users/AdamGreen/)
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+/* Implementation of classes to apply acceleration to input from
+   Sparkfun's Blackberry Trackball Breakout board.
+*/
+#include <mbed.h>
+#include "acceleration.h"
+
+#define ARRAYSIZE(X) (sizeof(X)/sizeof(X[0]))
+
+
+template<size_t SampleCount,
+         int    DecelerateThreshold,
+         int    AccelerateThreshold,
+         int    MaxAcceleration>
+unsigned char CAcceleratedRoller<SampleCount,
+                                 DecelerateThreshold,
+                                 AccelerateThreshold,
+                                 MaxAcceleration>::ClampToUChar(short Value)
+{
+    if (Value < 0)
+    {
+        Value = 0;
+    }
+    else if (Value > 0xFF)
+    {
+        Value = 0xFF;
+    }
+    
+    return Value;
+}
+
+
+template<size_t SampleCount,
+         int    DecelerateThreshold,
+         int    AccelerateThreshold,
+         int    MaxAcceleration>
+void CAcceleratedRoller<SampleCount,
+                        DecelerateThreshold,
+                        AccelerateThreshold,
+                        MaxAcceleration>::AccumulateSample(short CurrVelocity)
+{
+    unsigned char ClampedVelocity = ClampToUChar(CurrVelocity);
+    
+    // Calculate a running sum over the last SampleCount velocity samples.
+    m_VelocitySum -= m_Samples[m_SampleIndex];
+    m_VelocitySum += ClampedVelocity;
+    m_Samples[m_SampleIndex] = ClampedVelocity;
+    
+    m_SampleIndex++;
+    if (m_SampleIndex >= SampleCount)
+    {
+        m_SampleIndex = 0;
+    }
+    
+    // As we see a sustained high velocity, increase acceleration and decrease
+    // as the user slows down the velocity.
+    if (m_VelocitySum > AccelerateThreshold && m_Acceleration < MaxAcceleration)
+    {
+        m_Acceleration++;
+    }
+    if (m_VelocitySum < DecelerateThreshold && m_Acceleration > 1)
+    {
+        m_Acceleration--;
+    }
+}
+
+
+
+void CAcceleratedTrackball::UpdateLEDColourBasedOnMotion(int VelocityX, 
+                                                         int VelocityY, 
+                                                         int ButtonPressed)
+{
+    static const CBBTrackball::SColour  RedColour =   {255,   0,   0, 0};
+    static const CBBTrackball::SColour  GreenColour = {  0, 255,   0, 0};
+    static const CBBTrackball::SColour  BlueColour =  {  0,   0, 255, 0};
+    
+    // If the trackball is being moved then make it green, otherwise leave it
+    // red.
+    if (VelocityX || VelocityY)
+    {
+        m_IterationsSinceLastMotion = 0;
+        SetColour(&GreenColour);
+    }
+    else
+    {
+        if (m_IterationsSinceLastMotion > 250)
+        {
+            SetColour(&RedColour);
+        }
+        else
+        {
+            m_IterationsSinceLastMotion++;
+        }
+    }
+    
+    // Switch the button to blue when the button is pressed.
+    if (ButtonPressed)
+    {
+        SetColour(&BlueColour);
+    }
+}                                                  
+
+
+void CAcceleratedTrackball::GetState(int& DeltaX, int& DeltaY, int& ButtonPressed)
+{
+    CBBTrackball::SState    TrackballState;
+    short                   VelocityX;
+    short                   VelocityY;                  
+    
+    CBBTrackball::GetState(&TrackballState);
+
+    m_UpAcceleration.AccumulateSample(TrackballState.Up);
+    m_DownAcceleration.AccumulateSample(TrackballState.Down);
+    m_LeftAcceleration.AccumulateSample(TrackballState.Left);
+    m_RightAcceleration.AccumulateSample(TrackballState.Right);
+            
+    // NOTE: The breakout board is rotated 90 degrees on my breadboard.
+    VelocityX = TrackballState.Up * m_UpAcceleration.Acceleration() - 
+                TrackballState.Down * m_DownAcceleration.Acceleration();
+    VelocityY = TrackballState.Right * m_RightAcceleration.Acceleration() - 
+                TrackballState.Left * m_LeftAcceleration.Acceleration();
+
+    UpdateLEDColourBasedOnMotion(VelocityX, VelocityY, TrackballState.ButtonPressed);
+    
+    DeltaX = VelocityX;
+    DeltaY = VelocityY;
+    ButtonPressed = TrackballState.ButtonPressed;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/acceleration.h	Sun Dec 11 05:38:54 2011 +0000
@@ -0,0 +1,97 @@
+/* Copyright 2011 Adam Green (http://mbed.org/users/AdamGreen/)
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+/* Classes to apply acceleration to input from Sparkfun's Blackberry Trackball
+   Breakout board.
+*/
+#ifndef _ACCELERATION_H_
+#define _ACCELERATION_H_
+
+#include <mbed.h>
+#include <limits.h>
+#include "BBTrackball.h"
+
+
+
+/* Class which can apply acceleration to each of the roller inputs from the
+   Sparkfun Blackberry Trackball device.
+*/
+template<size_t SampleCount,
+         int    DecelerateThreshold,
+         int    AccelerateThreshold,
+         int    MaxAcceleration>
+class CAcceleratedRoller
+{
+public:
+    CAcceleratedRoller(void)
+    {
+        m_Acceleration = 1;
+        m_VelocitySum = 0;
+        m_SampleIndex = 0;
+        memset(m_Samples, 0, sizeof(m_Samples));
+    }
+
+    void AccumulateSample(short CurrVelocity);
+    int  Acceleration(void) const
+    {
+        return m_Acceleration;
+    }
+    
+protected:
+    unsigned char   ClampToUChar(short Value);
+    int             m_Acceleration;
+    int             m_VelocitySum;
+    size_t          m_SampleIndex;
+    unsigned char   m_Samples[SampleCount];
+};
+
+
+class CAcceleratedTrackball : public CBBTrackball
+{
+public:
+    CAcceleratedTrackball(PinName BluePin,
+                          PinName RedPin,
+                          PinName GreenPin,
+                          PinName WhitePin,
+                          PinName UpPin,
+                          PinName DownPin,
+                          PinName LeftPin,
+                          PinName RightPin,
+                          PinName ButtonPin) : CBBTrackball(BluePin,
+                                                            RedPin,
+                                                            GreenPin,
+                                                            WhitePin,
+                                                            UpPin,
+                                                            DownPin,
+                                                            LeftPin,
+                                                            RightPin,
+                                                            ButtonPin),
+                                               m_IterationsSinceLastMotion(INT_MAX)
+    {
+    }                                                            
+    void GetState(int& DeltaX, int& DeltaY, int& ButtonPressed);
+
+protected:
+    void    UpdateLEDColourBasedOnMotion(int VelocityX, 
+                                         int VelocityY, 
+                                         int ButtonPressed);
+    
+    int                                 m_IterationsSinceLastMotion;
+    CAcceleratedRoller<250, 4, 4, 40>   m_UpAcceleration;
+    CAcceleratedRoller<250, 4, 4, 40>   m_DownAcceleration;
+    CAcceleratedRoller<250, 4, 4, 30>   m_LeftAcceleration;
+    CAcceleratedRoller<250, 4, 4, 30>   m_RightAcceleration;
+};
+
+#endif // _ACCELERATION_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Dec 11 05:38:54 2011 +0000
@@ -0,0 +1,57 @@
+/* Copyright 2011 Adam Green (http://mbed.org/users/AdamGreen/)
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+/* Interfaces to a Sparkfun Blackberry Trackball Breakout Board and uses mbed's
+   USBMouse class to make it look like a mouse to a PC.  Uses the trackball
+   motion to move the mouse pointer, pushing down on the trackball will trigger
+   a microswitch which will act as a left button click, and the LEDs under the
+   trackball will be lit different colours depending on what the user is
+   currently doing with the device (red for no motion, green when the trackball
+   is being moved, and blue during button clicks).  It does use some other
+   utility classes from acceleration.h to provide acceleration to the trackball
+   motion.
+*/
+#include <mbed.h>
+#include <USBMouse.h>
+#include "acceleration.h"
+
+
+
+int main() 
+{
+    static USBMouse                 Mouse;
+    static CAcceleratedTrackball    Trackball(p20,  // BLU
+                                              p25,  // RED
+                                              p26,  // GRN
+                                              p10,  // WHT
+                                              p5,   // UP
+                                              p6,   // DWN
+                                              p7,   // LFT
+                                              p8,   // RHT
+                                              p9);  // BTN
+    
+    for(;;)
+    {
+        int DeltaX;
+        int DeltaY;
+        int ButtonPressed;        
+        
+        Trackball.GetState(DeltaX, DeltaY, ButtonPressed);
+
+        Mouse.update(DeltaX, 
+                     DeltaY, 
+                     ButtonPressed ? MOUSE_LEFT : 0, 
+                     0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sun Dec 11 05:38:54 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/078e4b97a13e