Use a Sparkfun Blackberry Trackball Breakout Board as a mouse.

Dependencies:   mbed BBTrackball

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers acceleration.cpp Source File

acceleration.cpp

00001 /* Copyright 2011 Adam Green (http://mbed.org/users/AdamGreen/)
00002 
00003    Licensed under the Apache License, Version 2.0 (the "License");
00004    you may not use this file except in compliance with the License.
00005    You may obtain a copy of the License at
00006 
00007        http://www.apache.org/licenses/LICENSE-2.0
00008 
00009    Unless required by applicable law or agreed to in writing, software
00010    distributed under the License is distributed on an "AS IS" BASIS,
00011    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012    See the License for the specific language governing permissions and
00013    limitations under the License.
00014 */
00015 /* Implementation of classes to apply acceleration to input from
00016    Sparkfun's Blackberry Trackball Breakout board.
00017 */
00018 #include <mbed.h>
00019 #include "acceleration.h"
00020 
00021 #define ARRAYSIZE(X) (sizeof(X)/sizeof(X[0]))
00022 
00023 
00024 template<size_t SampleCount,
00025          int    DecelerateThreshold,
00026          int    AccelerateThreshold,
00027          int    MaxAcceleration>
00028 unsigned char CAcceleratedRoller<SampleCount,
00029                                  DecelerateThreshold,
00030                                  AccelerateThreshold,
00031                                  MaxAcceleration>::ClampToUChar(short Value)
00032 {
00033     if (Value < 0)
00034     {
00035         Value = 0;
00036     }
00037     else if (Value > 0xFF)
00038     {
00039         Value = 0xFF;
00040     }
00041     
00042     return Value;
00043 }
00044 
00045 
00046 template<size_t SampleCount,
00047          int    DecelerateThreshold,
00048          int    AccelerateThreshold,
00049          int    MaxAcceleration>
00050 void CAcceleratedRoller<SampleCount,
00051                         DecelerateThreshold,
00052                         AccelerateThreshold,
00053                         MaxAcceleration>::AccumulateSample(short CurrVelocity)
00054 {
00055     unsigned char ClampedVelocity = ClampToUChar(CurrVelocity);
00056     
00057     // Calculate a running sum over the last SampleCount velocity samples.
00058     m_VelocitySum -= m_Samples[m_SampleIndex];
00059     m_VelocitySum += ClampedVelocity;
00060     m_Samples[m_SampleIndex] = ClampedVelocity;
00061     
00062     m_SampleIndex++;
00063     if (m_SampleIndex >= SampleCount)
00064     {
00065         m_SampleIndex = 0;
00066     }
00067     
00068     // As we see a sustained high velocity, increase acceleration and decrease
00069     // as the user slows down the velocity.
00070     if (m_VelocitySum > AccelerateThreshold && m_Acceleration < MaxAcceleration)
00071     {
00072         m_Acceleration++;
00073     }
00074     if (m_VelocitySum < DecelerateThreshold && m_Acceleration > 1)
00075     {
00076         m_Acceleration--;
00077     }
00078 }
00079 
00080 
00081 
00082 void CAcceleratedTrackball::UpdateLEDColourBasedOnMotion(int VelocityX, 
00083                                                          int VelocityY, 
00084                                                          int ButtonPressed)
00085 {
00086     static const CBBTrackball::SColour  RedColour =   {255,   0,   0, 0};
00087     static const CBBTrackball::SColour  GreenColour = {  0, 255,   0, 0};
00088     static const CBBTrackball::SColour  BlueColour =  {  0,   0, 255, 0};
00089     
00090     // If the trackball is being moved then make it green, otherwise leave it
00091     // red.
00092     if (VelocityX || VelocityY)
00093     {
00094         m_IterationsSinceLastMotion = 0;
00095         SetColour(&GreenColour);
00096     }
00097     else
00098     {
00099         if (m_IterationsSinceLastMotion > 250)
00100         {
00101             SetColour(&RedColour);
00102         }
00103         else
00104         {
00105             m_IterationsSinceLastMotion++;
00106         }
00107     }
00108     
00109     // Switch the button to blue when the button is pressed.
00110     if (ButtonPressed)
00111     {
00112         SetColour(&BlueColour);
00113     }
00114 }                                                  
00115 
00116 
00117 void CAcceleratedTrackball::GetState(int& DeltaX, int& DeltaY, int& ButtonPressed)
00118 {
00119     CBBTrackball::SState    TrackballState;
00120     short                   VelocityX;
00121     short                   VelocityY;                  
00122     
00123     CBBTrackball::GetState(&TrackballState);
00124 
00125     m_UpAcceleration.AccumulateSample(TrackballState.Up);
00126     m_DownAcceleration.AccumulateSample(TrackballState.Down);
00127     m_LeftAcceleration.AccumulateSample(TrackballState.Left);
00128     m_RightAcceleration.AccumulateSample(TrackballState.Right);
00129             
00130     // NOTE: The breakout board is rotated 90 degrees on my breadboard.
00131     VelocityX = TrackballState.Up * m_UpAcceleration.Acceleration() - 
00132                 TrackballState.Down * m_DownAcceleration.Acceleration();
00133     VelocityY = TrackballState.Right * m_RightAcceleration.Acceleration() - 
00134                 TrackballState.Left * m_LeftAcceleration.Acceleration();
00135 
00136     UpdateLEDColourBasedOnMotion(VelocityX, VelocityY, TrackballState.ButtonPressed);
00137     
00138     DeltaX = VelocityX;
00139     DeltaY = VelocityY;
00140     ButtonPressed = TrackballState.ButtonPressed;
00141 }