Library to handle SpaceBall, SpaceMouse and SpaceOrb on serial port. Gets access to 3D rotation and translation vector as well as button status. (USB is not supported)

Dependents:   SpaceBall_Example

Library to handle SpaceBall, SpaceMouse and SpaceOrb on serial port. Gets access to 3D rotation and translation vector as well as button status. (USB is not supported)

All handling and decoding is done in the RX interrupt and the vector values can be read out asynchronously with different coordinate mappings.

Example:

#include "mbed.h"
#include "SpaceBall.h"
 
PwmOut led[] = {(LED1), (LED2), (LED3), (LED4) };
SpaceBall SBall(p9, p10);   // tx, rx, bSOrb
 
int main() {
    SBall.Init();
    
    while(1) {
 
        led[0] = abs( SBall[TX] ) + abs( SBall[TY] ) + abs( SBall[TZ] );
        led[1] = abs( SBall[RX] );
        led[2] = abs( SBall[RY] );
        led[3] = abs( SBall[RZ] );
        
        wait_us(500);
    }
}

In this exaple the 4 LEDs are powered dependent on force at the Spaceball. LED1 shows the sum of all translation forces. LED2 to LED4 shows the rotation forces.

For more information about SpaceBall devices see manufactorers page http://www.3dconnexion.com

For connecting a SpaceBall (or SpaceMouse or SpaceOrb) to mbed see page wiki/Serial-Connection

Example: SpaceBall 4000

/media/uploads/jocis/spaceball1.jpg

Committer:
jocis
Date:
Sat Dec 01 05:30:34 2012 +0000
Revision:
0:f67a8fffd94a
Child:
1:e6282b645d9b
.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jocis 0:f67a8fffd94a 1 #include "mbed.h"
jocis 0:f67a8fffd94a 2
jocis 0:f67a8fffd94a 3 /* Spaceball Button bit-masks */
jocis 0:f67a8fffd94a 4 #define SBALL_BUTTON_1 0x0001 /* bit 0 */
jocis 0:f67a8fffd94a 5 #define SBALL_BUTTON_2 0x0002 /* bit 1 */
jocis 0:f67a8fffd94a 6 #define SBALL_BUTTON_3 0x0004 /* bit 2 */
jocis 0:f67a8fffd94a 7 #define SBALL_BUTTON_4 0x0008 /* bit 3 */
jocis 0:f67a8fffd94a 8 #define SBALL_BUTTON_5 0x0010 /* bit 4 */
jocis 0:f67a8fffd94a 9 #define SBALL_BUTTON_6 0x0020 /* bit 5 */
jocis 0:f67a8fffd94a 10 #define SBALL_BUTTON_7 0x0040 /* bit 6 */
jocis 0:f67a8fffd94a 11 #define SBALL_BUTTON_8 0x0080 /* bit 7 */
jocis 0:f67a8fffd94a 12 #define SBALL_BUTTON_9 0x0100 /* bit 8 */
jocis 0:f67a8fffd94a 13 #define SBALL_BUTTON_10 0x0200 /* bit 9 */
jocis 0:f67a8fffd94a 14 #define SBALL_BUTTON_11 0x0400 /* bit 10 */
jocis 0:f67a8fffd94a 15 #define SBALL_BUTTON_12 0x0800 /* bit 11 */
jocis 0:f67a8fffd94a 16
jocis 0:f67a8fffd94a 17 /* The Spaceball 3003 and 3003 FLX only have "left" and "right" buttons */
jocis 0:f67a8fffd94a 18 #define SBALL_BUTTON_RIGHT 0x1000 /* bit 12 */
jocis 0:f67a8fffd94a 19 #define SBALL_BUTTON_LEFT 0x2000 /* bit 13 */
jocis 0:f67a8fffd94a 20
jocis 0:f67a8fffd94a 21 /* The Spaceball 2003A and 2003B have a dedicated pick button on the ball */
jocis 0:f67a8fffd94a 22 /* The Spaceball 2003 FLX uses "button 9" as the pick button. */
jocis 0:f67a8fffd94a 23 /* All of them return this as "button 9" in their encoded button data */
jocis 0:f67a8fffd94a 24 #define SBALL_BUTTON_PICK SBALL_BUTTON_RIGHT /* bit 12 */
jocis 0:f67a8fffd94a 25
jocis 0:f67a8fffd94a 26 /* On Spaceball 2003A and 2003B, the Rezero is "button 8" on the device */
jocis 0:f67a8fffd94a 27 /* On the newer devices, there are dedicated rezero buttons */
jocis 0:f67a8fffd94a 28 #define SBALL_BUTTON_REZERO 0x4000 /* bit 14 */
jocis 0:f67a8fffd94a 29
jocis 0:f67a8fffd94a 30 /* The Spaceball 4000 FLX has a configurable palm rest which can be in */
jocis 0:f67a8fffd94a 31 /* either "left" or "right" handed mode. When it is configured in "left" */
jocis 0:f67a8fffd94a 32 /* handed mode, the "lefty" bit is set, and coordinate systems need to be */
jocis 0:f67a8fffd94a 33 /* inverted on one axis. */
jocis 0:f67a8fffd94a 34 #define SBALL_MODE_LEFTY 0x8000 /* bit 15 */
jocis 0:f67a8fffd94a 35
jocis 0:f67a8fffd94a 36
jocis 0:f67a8fffd94a 37 enum eSpaceBallAxis {
jocis 0:f67a8fffd94a 38 TX=0, TY, TZ,
jocis 0:f67a8fffd94a 39 Right=0, Forward, Up,
jocis 0:f67a8fffd94a 40 RX=3, RY, RZ,
jocis 0:f67a8fffd94a 41 Pitch=3, Roll, Yaw };
jocis 0:f67a8fffd94a 42
jocis 0:f67a8fffd94a 43 class SpaceBall {
jocis 0:f67a8fffd94a 44 public:
jocis 0:f67a8fffd94a 45
jocis 0:f67a8fffd94a 46 SpaceBall ( PinName tx, PinName rx, bool bSpaceOrb=false );
jocis 0:f67a8fffd94a 47 ~SpaceBall() {};
jocis 0:f67a8fffd94a 48
jocis 0:f67a8fffd94a 49 void Init();
jocis 0:f67a8fffd94a 50
jocis 0:f67a8fffd94a 51 void GetTranslation ( float* fValue[3] ) const
jocis 0:f67a8fffd94a 52 {
jocis 0:f67a8fffd94a 53 *fValue[0] = GetAxis ( TX );
jocis 0:f67a8fffd94a 54 *fValue[1] = GetAxis ( TY );
jocis 0:f67a8fffd94a 55 *fValue[2] = GetAxis ( TZ );
jocis 0:f67a8fffd94a 56 }
jocis 0:f67a8fffd94a 57 void GetRotation ( float* fValue[3] ) const
jocis 0:f67a8fffd94a 58 {
jocis 0:f67a8fffd94a 59 *fValue[0] = GetAxis ( RX );
jocis 0:f67a8fffd94a 60 *fValue[1] = GetAxis ( RY );
jocis 0:f67a8fffd94a 61 *fValue[2] = GetAxis ( RZ );
jocis 0:f67a8fffd94a 62 }
jocis 0:f67a8fffd94a 63 float GetAxis ( int nAxis ) const
jocis 0:f67a8fffd94a 64 {
jocis 0:f67a8fffd94a 65 return GetAxisRaw ( nAxis ) * 0.00005f * _fScale;
jocis 0:f67a8fffd94a 66 }
jocis 0:f67a8fffd94a 67 int GetAxisRaw ( int nAxis ) const
jocis 0:f67a8fffd94a 68 {
jocis 0:f67a8fffd94a 69 if ( nAxis<0 || nAxis>5 )
jocis 0:f67a8fffd94a 70 return 0;
jocis 0:f67a8fffd94a 71
jocis 0:f67a8fffd94a 72 return m_axis[nAxis];
jocis 0:f67a8fffd94a 73 }
jocis 0:f67a8fffd94a 74 float operator[] (eSpaceBallAxis nAxis) const
jocis 0:f67a8fffd94a 75 { return GetAxis ( nAxis ); }
jocis 0:f67a8fffd94a 76 float operator[] (int nAxis) const
jocis 0:f67a8fffd94a 77 { return GetAxis ( nAxis ); }
jocis 0:f67a8fffd94a 78
jocis 0:f67a8fffd94a 79 int GetButtons() const
jocis 0:f67a8fffd94a 80 {
jocis 0:f67a8fffd94a 81 return m_buttons;
jocis 0:f67a8fffd94a 82 }
jocis 0:f67a8fffd94a 83 operator int (void) const
jocis 0:f67a8fffd94a 84 { return GetButtons(); }
jocis 0:f67a8fffd94a 85
jocis 0:f67a8fffd94a 86 void SetScale ( float fScale=1.0f )
jocis 0:f67a8fffd94a 87 { _fScale = fScale; }
jocis 0:f67a8fffd94a 88 float GetScale ( void )
jocis 0:f67a8fffd94a 89 { return _fScale; }
jocis 0:f67a8fffd94a 90
jocis 0:f67a8fffd94a 91
jocis 0:f67a8fffd94a 92 protected:
jocis 0:f67a8fffd94a 93 Serial _serial;
jocis 0:f67a8fffd94a 94 bool _bSpaceOrb;
jocis 0:f67a8fffd94a 95 float _fScale;
jocis 0:f67a8fffd94a 96
jocis 0:f67a8fffd94a 97 int m_axis[6]; /* last translational data received */
jocis 0:f67a8fffd94a 98 //int m_rot[3]; /* last rotational data received */
jocis 0:f67a8fffd94a 99 int m_buttons; /* current button status */
jocis 0:f67a8fffd94a 100
jocis 0:f67a8fffd94a 101 void SerialISR(void);
jocis 0:f67a8fffd94a 102 void Process ( char c );
jocis 0:f67a8fffd94a 103
jocis 0:f67a8fffd94a 104 virtual void DoChangedAxis (void) {};
jocis 0:f67a8fffd94a 105 virtual void DoChangedButtons (void) {};
jocis 0:f67a8fffd94a 106
jocis 0:f67a8fffd94a 107 private:
jocis 0:f67a8fffd94a 108 unsigned char m_buf[256];
jocis 0:f67a8fffd94a 109 char m_resetstring[256];
jocis 0:f67a8fffd94a 110 int m_bufpos; /* current char position in packet buffer */
jocis 0:f67a8fffd94a 111 int m_packtype; /* what kind of packet is it */
jocis 0:f67a8fffd94a 112 int m_packlen; /* how many bytes do we ultimately expect? */
jocis 0:f67a8fffd94a 113 int m_escapedchar; /* if set, we're processing an escape sequence */
jocis 0:f67a8fffd94a 114 int m_erroroccured; /* if set, we've received an error packet or packets */
jocis 0:f67a8fffd94a 115 int m_resetoccured; /* if set, ball was reset, so have to reinitialize it */
jocis 0:f67a8fffd94a 116 int m_spaceball4000; /* if set, its a Spaceball 4000 */
jocis 0:f67a8fffd94a 117 int m_leftymode4000; /* if set, Spaceball 4000 in "lefty" orientation */
jocis 0:f67a8fffd94a 118 int m_timer; /* time since last packet was received */
jocis 0:f67a8fffd94a 119
jocis 0:f67a8fffd94a 120 void InitSB() {};
jocis 0:f67a8fffd94a 121 void InitSO() {};
jocis 0:f67a8fffd94a 122
jocis 0:f67a8fffd94a 123 void ProcessSB ( char c );
jocis 0:f67a8fffd94a 124 void ProcessSO ( char c );
jocis 0:f67a8fffd94a 125 };