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 18:23:50 2012 +0000
Revision:
1:e6282b645d9b
Child:
2:a7c0fcd157f7
Implemented SpaceMouse and SpaceOrb

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jocis 1:e6282b645d9b 1 #include "SpaceBall.h"
jocis 1:e6282b645d9b 2
jocis 1:e6282b645d9b 3 #define Sleep(x) wait_ms(x*10)
jocis 1:e6282b645d9b 4
jocis 1:e6282b645d9b 5 extern Serial pc;
jocis 1:e6282b645d9b 6
jocis 1:e6282b645d9b 7 ///////////////////////////////////////////////////////////////////////////////
jocis 1:e6282b645d9b 8
jocis 1:e6282b645d9b 9 static unsigned char spaceorb_xor[] = "SpaceWare";
jocis 1:e6282b645d9b 10
jocis 1:e6282b645d9b 11 static unsigned char spaceorb_errors[][32] = {
jocis 1:e6282b645d9b 12 "EEPROM storing 0 failed", "Receive queue overflow", "Transmit queue timeout",
jocis 1:e6282b645d9b 13 "Bad packet", "Power brown-out", "EEPROM checksum error", "Hardware fault" };
jocis 1:e6282b645d9b 14
jocis 1:e6282b645d9b 15
jocis 1:e6282b645d9b 16 void SpaceBall::InitSO()
jocis 1:e6282b645d9b 17 {
jocis 1:e6282b645d9b 18
jocis 1:e6282b645d9b 19 // pc.printf("Sending initialization sequence to spaceball...\n");
jocis 1:e6282b645d9b 20
jocis 1:e6282b645d9b 21 // _serial.printf ( "CB\r" );
jocis 1:e6282b645d9b 22 Sleep(10);
jocis 1:e6282b645d9b 23 }
jocis 1:e6282b645d9b 24
jocis 1:e6282b645d9b 25 ///////////////////////////////////////////////////////////////////////////////
jocis 1:e6282b645d9b 26
jocis 1:e6282b645d9b 27 void SpaceBall::ProcessSO ( char data )
jocis 1:e6282b645d9b 28 {
jocis 1:e6282b645d9b 29 if (~data & 0x80) {
jocis 1:e6282b645d9b 30 _data[_idx] = 0;
jocis 1:e6282b645d9b 31 if (_idx)
jocis 1:e6282b645d9b 32 ProcessPacketSO();
jocis 1:e6282b645d9b 33 _idx = 0;
jocis 1:e6282b645d9b 34 }
jocis 1:e6282b645d9b 35 if (_idx < SPACEBALL_MAX_LENGTH)
jocis 1:e6282b645d9b 36 _data[_idx++] = data & 0x7f;
jocis 1:e6282b645d9b 37
jocis 1:e6282b645d9b 38 }
jocis 1:e6282b645d9b 39
jocis 1:e6282b645d9b 40 ///////////////////////////////////////////////////////////////////////////////
jocis 1:e6282b645d9b 41
jocis 1:e6282b645d9b 42 void SpaceBall::ProcessPacketSO ( void )
jocis 1:e6282b645d9b 43 {
jocis 1:e6282b645d9b 44 int i;
jocis 1:e6282b645d9b 45 char c = 0;
jocis 1:e6282b645d9b 46
jocis 1:e6282b645d9b 47 if (_idx < 2) return;
jocis 1:e6282b645d9b 48 for (i = 0; i < _idx; i++) c ^= _data[i];
jocis 1:e6282b645d9b 49 if (c) return;
jocis 1:e6282b645d9b 50
jocis 1:e6282b645d9b 51 switch (_data[0]) {
jocis 1:e6282b645d9b 52
jocis 1:e6282b645d9b 53 case 'R': /* Reset packet */
jocis 1:e6282b645d9b 54 //spaceorb->data[spaceorb->idx - 1] = 0;
jocis 1:e6282b645d9b 55 //for (i = 1; i < spaceorb->idx && spaceorb->data[i] == ' '; i++);
jocis 1:e6282b645d9b 56 //printk(KERN_INFO "input: %s [%s] on %s\n",
jocis 1:e6282b645d9b 57 // spaceorb_name, spaceorb->data + i, spaceorb->serio->phys);
jocis 1:e6282b645d9b 58 break;
jocis 1:e6282b645d9b 59
jocis 1:e6282b645d9b 60 case 'D': /* Ball + button data */
jocis 1:e6282b645d9b 61 {
jocis 1:e6282b645d9b 62 short axes[6];
jocis 1:e6282b645d9b 63
jocis 1:e6282b645d9b 64 if (_idx != 12) return;
jocis 1:e6282b645d9b 65 for (i = 0; i < 9; i++) _data[i+2] ^= spaceorb_xor[i];
jocis 1:e6282b645d9b 66 axes[0] = ( _data[2] << 3) | (_data[ 3] >> 4);
jocis 1:e6282b645d9b 67 axes[1] = ((_data[3] & 0x0f) << 6) | (_data[ 4] >> 1);
jocis 1:e6282b645d9b 68 axes[2] = ((_data[4] & 0x01) << 9) | (_data[ 5] << 2) | (_data[4] >> 5);
jocis 1:e6282b645d9b 69 axes[3] = ((_data[6] & 0x1f) << 5) | (_data[ 7] >> 2);
jocis 1:e6282b645d9b 70 axes[4] = ((_data[7] & 0x03) << 8) | (_data[ 8] << 1) | (_data[7] >> 6);
jocis 1:e6282b645d9b 71 axes[5] = ((_data[9] & 0x3f) << 4) | (_data[10] >> 3);
jocis 1:e6282b645d9b 72 for (i = 0; i < 6; i++)
jocis 1:e6282b645d9b 73 m_axis[i] = axes[i] - ((axes[i] & 0x200) ? 1024 : 0);
jocis 1:e6282b645d9b 74 m_buttons = _data[1];
jocis 1:e6282b645d9b 75 DoChangedAxis();
jocis 1:e6282b645d9b 76 DoChangedButtons();
jocis 1:e6282b645d9b 77 }
jocis 1:e6282b645d9b 78 break;
jocis 1:e6282b645d9b 79
jocis 1:e6282b645d9b 80 case 'K': /* Button data */
jocis 1:e6282b645d9b 81 if (_idx != 5) return;
jocis 1:e6282b645d9b 82 m_buttons = _data[2];
jocis 1:e6282b645d9b 83 DoChangedButtons();
jocis 1:e6282b645d9b 84 break;
jocis 1:e6282b645d9b 85
jocis 1:e6282b645d9b 86 case 'E': /* Error packet */
jocis 1:e6282b645d9b 87 if (_idx != 4) return;
jocis 1:e6282b645d9b 88 //printk(KERN_ERR "joy-spaceorb: Device error. [ ");
jocis 1:e6282b645d9b 89 //for (i = 0; i < 7; i++) if (data[1] & (1 << i)) printk("%s ", spaceorb_errors[i]);
jocis 1:e6282b645d9b 90 //printk("]\n");
jocis 1:e6282b645d9b 91 break;
jocis 1:e6282b645d9b 92
jocis 1:e6282b645d9b 93 case '?': /* Version number follows */
jocis 1:e6282b645d9b 94 /* eat and ignore these packets */
jocis 1:e6282b645d9b 95 break;
jocis 1:e6282b645d9b 96
jocis 1:e6282b645d9b 97 default:
jocis 1:e6282b645d9b 98 pc.printf("<%s>\r\n",_data);
jocis 1:e6282b645d9b 99 break;
jocis 1:e6282b645d9b 100
jocis 1:e6282b645d9b 101 }
jocis 1:e6282b645d9b 102
jocis 1:e6282b645d9b 103 }
jocis 1:e6282b645d9b 104
jocis 1:e6282b645d9b 105 ///////////////////////////////////////////////////////////////////////////////
jocis 1:e6282b645d9b 106 ///////////////////////////////////////////////////////////////////////////////
jocis 1:e6282b645d9b 107 ///////////////////////////////////////////////////////////////////////////////