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 21:38:49 2012 +0000
Revision:
2:a7c0fcd157f7
Parent:
1:e6282b645d9b
Child:
3:7bacae57a30b
Addef mapping and cleanup

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 1:e6282b645d9b 37 #define SPACEBALL_MAX_LENGTH 128
jocis 1:e6282b645d9b 38
jocis 0:f67a8fffd94a 39 enum eSpaceBallAxis {
jocis 0:f67a8fffd94a 40 TX=0, TY, TZ,
jocis 0:f67a8fffd94a 41 Right=0, Forward, Up,
jocis 0:f67a8fffd94a 42 RX=3, RY, RZ,
jocis 0:f67a8fffd94a 43 Pitch=3, Roll, Yaw };
jocis 0:f67a8fffd94a 44
jocis 2:a7c0fcd157f7 45 enum eSpaceBallMapping {
jocis 2:a7c0fcd157f7 46 RAW=0, CNC, CNCvert };
jocis 2:a7c0fcd157f7 47
jocis 2:a7c0fcd157f7 48
jocis 0:f67a8fffd94a 49 class SpaceBall {
jocis 0:f67a8fffd94a 50 public:
jocis 0:f67a8fffd94a 51
jocis 0:f67a8fffd94a 52 SpaceBall ( PinName tx, PinName rx, bool bSpaceOrb=false );
jocis 0:f67a8fffd94a 53 ~SpaceBall() {};
jocis 0:f67a8fffd94a 54
jocis 0:f67a8fffd94a 55 void Init();
jocis 0:f67a8fffd94a 56
jocis 2:a7c0fcd157f7 57 void SetMapping ( int mapping )
jocis 2:a7c0fcd157f7 58 { _mapping = mapping; }
jocis 2:a7c0fcd157f7 59
jocis 0:f67a8fffd94a 60 void GetTranslation ( float* fValue[3] ) const
jocis 0:f67a8fffd94a 61 {
jocis 0:f67a8fffd94a 62 *fValue[0] = GetAxis ( TX );
jocis 0:f67a8fffd94a 63 *fValue[1] = GetAxis ( TY );
jocis 0:f67a8fffd94a 64 *fValue[2] = GetAxis ( TZ );
jocis 0:f67a8fffd94a 65 }
jocis 2:a7c0fcd157f7 66
jocis 0:f67a8fffd94a 67 void GetRotation ( float* fValue[3] ) const
jocis 0:f67a8fffd94a 68 {
jocis 0:f67a8fffd94a 69 *fValue[0] = GetAxis ( RX );
jocis 0:f67a8fffd94a 70 *fValue[1] = GetAxis ( RY );
jocis 0:f67a8fffd94a 71 *fValue[2] = GetAxis ( RZ );
jocis 0:f67a8fffd94a 72 }
jocis 2:a7c0fcd157f7 73
jocis 2:a7c0fcd157f7 74 float GetAxis ( int nAxis ) const;
jocis 2:a7c0fcd157f7 75
jocis 2:a7c0fcd157f7 76 int GetAxisRaw ( int nAxis ) const;
jocis 2:a7c0fcd157f7 77
jocis 0:f67a8fffd94a 78 float operator[] (eSpaceBallAxis nAxis) const
jocis 0:f67a8fffd94a 79 { return GetAxis ( nAxis ); }
jocis 0:f67a8fffd94a 80 float operator[] (int nAxis) const
jocis 0:f67a8fffd94a 81 { return GetAxis ( nAxis ); }
jocis 0:f67a8fffd94a 82
jocis 0:f67a8fffd94a 83 int GetButtons() const
jocis 2:a7c0fcd157f7 84 { return _buttons; }
jocis 2:a7c0fcd157f7 85
jocis 0:f67a8fffd94a 86 operator int (void) const
jocis 0:f67a8fffd94a 87 { return GetButtons(); }
jocis 0:f67a8fffd94a 88
jocis 0:f67a8fffd94a 89 void SetScale ( float fScale=1.0f )
jocis 0:f67a8fffd94a 90 { _fScale = fScale; }
jocis 0:f67a8fffd94a 91 float GetScale ( void )
jocis 0:f67a8fffd94a 92 { return _fScale; }
jocis 0:f67a8fffd94a 93
jocis 0:f67a8fffd94a 94
jocis 0:f67a8fffd94a 95 protected:
jocis 0:f67a8fffd94a 96 Serial _serial;
jocis 0:f67a8fffd94a 97 bool _bSpaceOrb;
jocis 0:f67a8fffd94a 98 float _fScale;
jocis 0:f67a8fffd94a 99
jocis 2:a7c0fcd157f7 100 int _axis[6]; /* last translational data received */
jocis 2:a7c0fcd157f7 101 int _buttons; /* current button status */
jocis 0:f67a8fffd94a 102
jocis 0:f67a8fffd94a 103 void SerialISR(void);
jocis 0:f67a8fffd94a 104 void Process ( char c );
jocis 0:f67a8fffd94a 105
jocis 0:f67a8fffd94a 106 virtual void DoChangedAxis (void) {};
jocis 0:f67a8fffd94a 107 virtual void DoChangedButtons (void) {};
jocis 0:f67a8fffd94a 108
jocis 0:f67a8fffd94a 109 private:
jocis 0:f67a8fffd94a 110 int m_erroroccured; /* if set, we've received an error packet or packets */
jocis 0:f67a8fffd94a 111 int m_resetoccured; /* if set, ball was reset, so have to reinitialize it */
jocis 0:f67a8fffd94a 112 int m_spaceball4000; /* if set, its a Spaceball 4000 */
jocis 0:f67a8fffd94a 113 int m_leftymode4000; /* if set, Spaceball 4000 in "lefty" orientation */
jocis 0:f67a8fffd94a 114
jocis 1:e6282b645d9b 115 bool _escape;
jocis 1:e6282b645d9b 116 int _idx;
jocis 1:e6282b645d9b 117 char _data[SPACEBALL_MAX_LENGTH];
jocis 2:a7c0fcd157f7 118
jocis 2:a7c0fcd157f7 119 float _fScaleR;
jocis 2:a7c0fcd157f7 120 float _fScaleT;
jocis 2:a7c0fcd157f7 121 int _mapping;
jocis 1:e6282b645d9b 122
jocis 1:e6282b645d9b 123 void InitSB();
jocis 1:e6282b645d9b 124 void InitSO();
jocis 0:f67a8fffd94a 125
jocis 0:f67a8fffd94a 126 void ProcessSB ( char c );
jocis 0:f67a8fffd94a 127 void ProcessSO ( char c );
jocis 1:e6282b645d9b 128
jocis 1:e6282b645d9b 129 void ProcessPacketSB ( void );
jocis 1:e6282b645d9b 130 void ProcessPacketSO ( void );
jocis 1:e6282b645d9b 131
jocis 0:f67a8fffd94a 132 };