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

SO.cpp

Committer:
jocis
Date:
2012-12-01
Revision:
1:e6282b645d9b
Child:
2:a7c0fcd157f7

File content as of revision 1:e6282b645d9b:

#include "SpaceBall.h"

#define Sleep(x) wait_ms(x*10)

extern Serial pc;

///////////////////////////////////////////////////////////////////////////////

static unsigned char spaceorb_xor[] = "SpaceWare";

static unsigned char spaceorb_errors[][32] = { 
    "EEPROM storing 0 failed", "Receive queue overflow", "Transmit queue timeout",
    "Bad packet", "Power brown-out", "EEPROM checksum error", "Hardware fault" };


void SpaceBall::InitSO()
{

   // pc.printf("Sending initialization sequence to spaceball...\n");

//    _serial.printf ( "CB\r" );
    Sleep(10);
}

///////////////////////////////////////////////////////////////////////////////

void SpaceBall::ProcessSO ( char data )
{
    if (~data & 0x80) {
        _data[_idx] = 0;
        if (_idx)
            ProcessPacketSO();
        _idx = 0;
    }
    if (_idx < SPACEBALL_MAX_LENGTH)
        _data[_idx++] = data & 0x7f;

}

///////////////////////////////////////////////////////////////////////////////

void SpaceBall::ProcessPacketSO ( void )
{
    int i;
    char c = 0;

    if (_idx < 2) return;
    for (i = 0; i < _idx; i++) c ^= _data[i];
    if (c) return;

    switch (_data[0]) {

        case 'R':               /* Reset packet */
            //spaceorb->data[spaceorb->idx - 1] = 0;
            //for (i = 1; i < spaceorb->idx && spaceorb->data[i] == ' '; i++);
            //printk(KERN_INFO "input: %s [%s] on %s\n",
            //     spaceorb_name, spaceorb->data + i, spaceorb->serio->phys);
            break;

        case 'D':               /* Ball + button data */
        {
            short axes[6];
            
            if (_idx != 12) return;
            for (i = 0; i < 9; i++) _data[i+2] ^= spaceorb_xor[i];
            axes[0] = ( _data[2]  << 3) | (_data[ 3] >> 4);
            axes[1] = ((_data[3] & 0x0f) << 6) | (_data[ 4] >> 1);
            axes[2] = ((_data[4] & 0x01) << 9) | (_data[ 5] << 2) | (_data[4] >> 5);
            axes[3] = ((_data[6] & 0x1f) << 5) | (_data[ 7] >> 2);
            axes[4] = ((_data[7] & 0x03) << 8) | (_data[ 8] << 1) | (_data[7] >> 6);
            axes[5] = ((_data[9] & 0x3f) << 4) | (_data[10] >> 3);
            for (i = 0; i < 6; i++)
                m_axis[i] = axes[i] - ((axes[i] & 0x200) ? 1024 : 0);
            m_buttons = _data[1];
            DoChangedAxis();
            DoChangedButtons();
            }
            break;

        case 'K':               /* Button data */
            if (_idx != 5) return;
            m_buttons = _data[2];
            DoChangedButtons();
            break;

        case 'E':               /* Error packet */
            if (_idx != 4) return;
            //printk(KERN_ERR "joy-spaceorb: Device error. [ ");
            //for (i = 0; i < 7; i++) if (data[1] & (1 << i)) printk("%s ", spaceorb_errors[i]);
            //printk("]\n");
            break;

        case '?': /* Version number follows */
            /* eat and ignore these packets */
            break;
            
        default:
            pc.printf("<%s>\r\n",_data);
            break;

    }

}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////