View difference between Paste ID: AVqshwJW and erhTgRBH
SHOW: | | - or go back to the newest paste.
1
//The code below is a combination of code written by a guest Pastebin user, and the source code for the Space-Mushroom project by 'Shiura' on thingiverse and instructables. Thank you for creating this project!! Amazing work!
2
//Also note, this is my blind attempt at splicing the two bits of code together until they work. It is definitely not perfect, or tidy, but it works for me at the moment. I will look at tidying up the code and possibly streamlining the operation at a later date.
3
4
// This code makes your Arduino act as a 3DConnexion SpaceMouse (32u4-based board required).
5
// To make this work you also need to set the USB Vendor ID and Product ID to values matching a real 3DConnexion device.
6
// You can do this by editing appropriate entries in the boards.txt file in your Arduino installation.
7
// Example values: vid=0x256f, pid=0xc631 (SpaceMouse Pro Wireless (cabled))
8
// Then install the 3DxWare software from 3DConnexion on your computer and you can use you Arduino device in software like Fusion 360 as it it were a real SpaceMouse.
9
 
10
#include "HID.h"
11
 
12
static const uint8_t _hidReportDescriptor[] PROGMEM = {
13
  0x05, 0x01,           //  Usage Page (Generic Desktop)
14
  0x09, 0x08,           //  0x08: Usage (Multi-Axis)
15
  0xa1, 0x01,           //  Collection (Application)
16
  0xa1, 0x00,           // Collection (Physical)
17
  0x85, 0x01,           //  Report ID
18
  0x16, 0x00, 0x80,     //logical minimum (-500)
19
  0x26, 0xff, 0x7f,     //logical maximum (500)
20
  0x36, 0x00, 0x80,     //Physical Minimum (-32768)
21
  0x46, 0xff, 0x7f,     //Physical Maximum (32767)
22
  0x09, 0x30,           //    Usage (X)
23
  0x09, 0x31,           //    Usage (Y)
24
  0x09, 0x32,           //    Usage (Z)
25
  0x75, 0x10,           //    Report Size (16)
26
  0x95, 0x03,           //    Report Count (3)
27
  0x81, 0x02,           //    Input (variable,absolute)
28
  0xC0,                 //  End Collection
29
  0xa1, 0x00,           // Collection (Physical)
30
  0x85, 0x02,           //  Report ID
31
  0x16, 0x00, 0x80,     //logical minimum (-500)
32
  0x26, 0xff, 0x7f,     //logical maximum (500)
33
  0x36, 0x00, 0x80,     //Physical Minimum (-32768)
34
  0x46, 0xff, 0x7f,     //Physical Maximum (32767)
35
  0x09, 0x33,           //    Usage (RX)
36
  0x09, 0x34,           //    Usage (RY)
37
  0x09, 0x35,           //    Usage (RZ)
38
  0x75, 0x10,           //    Report Size (16)
39
  0x95, 0x03,           //    Report Count (3)
40
  0x81, 0x02,           //    Input (variable,absolute)
41
  0xC0,                 //  End Collection
42
 
43
  0xa1, 0x00,           // Collection (Physical)
44
  0x85, 0x03,           //  Report ID
45
  0x15, 0x00,           //   Logical Minimum (0)
46
  0x25, 0x01,           //    Logical Maximum (1)
47
  0x75, 0x01,           //    Report Size (1)
48
  0x95, 32,             //    Report Count (24)
49
  0x05, 0x09,           //    Usage Page (Button)
50
  0x19, 1,              //    Usage Minimum (Button #1)
51
  0x29, 32,             //    Usage Maximum (Button #24)
52
  0x81, 0x02,           //    Input (variable,absolute)
53
  0xC0,
54
  0xC0
55
};
56
 
57
#define DOF 6
58
#define TX 0 // translation X
59
#define TY 1 // translation Y
60
#define TZ 2 // translation Z
61
#define RX 3 // rotation X
62
#define RY 4 // rotation Y
63
#define RZ 5 // rotation Z
64
 
65
/// hardware 
66
#define DEAD_THRESH 2 //Deazone for ignoring small movement
67
#define SPEED_PARAM 40 // larger is slower
68
69
 
70
// ports of analog input for joysticks
71
int port[DOF] = {A0, A2, A6, A1, A3, A7};
72
 
73
// conversion matrix from sensor input to rigid motion
74
int coeff[DOF][DOF] = {
75
  { 0,  0,  0,-20,-20, 40}, // TX
76
  { 0,  0,  0,-17, 17,  0}, // TY
77
  {-3, -3, -3,  0,  0,  0}, // TZ
78
  {-6,  6,  0,  0,  0,  0}, // RY
79
  { 3,  3, -6,  0,  0,  0}, // RX
80
  { 0,  0,  0,  2,  2,  2}, // RZ
81
};
82
 
83
#define abs(x) ((x)<0?(-x):(x))
84
 
85
int origin[DOF]; // initial sensor values
86
 
87
void setup() {
88
  static HIDSubDescriptor node(_hidReportDescriptor, sizeof(_hidReportDescriptor));
89
  HID().AppendDescriptor(&node);
90
 
91
  for(int i = 0; i < DOF; i++) {
92
    origin[i] = analogRead(port[i]);
93
  }
94
}
95
 
96
void send_command(int16_t rx, int16_t ry, int16_t rz, int16_t x, int16_t y, int16_t z) {
97
  uint8_t trans[6] = { x & 0xFF, x >> 8, y & 0xFF, y >> 8, z & 0xFF, z >> 8 };
98
  HID().SendReport(1, trans, 6);
99
  uint8_t rot[6] = { rx & 0xFF, rx >> 8, ry & 0xFF, ry >> 8, rz & 0xFF, rz >> 8 };
100
  HID().SendReport(2, rot, 6);
101
}
102
 
103
void loop() {
104
  int sv[DOF]; // sensor value
105
  int mv[DOF]; // motion vector
106
  
107
  // read sensor value and subtract original position
108
  for(int i = 0; i < DOF; i++) {
109
    sv[i] = analogRead(port[i]) - origin[i];
110
  }
111
 
112
  // calculate the motion of the "mushroom" knob
113
  for(int i = 0; i < DOF; i++) {
114
    mv[i] = 0;
115
    for(int j = 0; j < DOF; j++) {
116
      mv[i] += coeff[i][j] * sv[j];
117
    }
118
    
119
    mv[i] /= SPEED_PARAM;
120
    
121
    if((mv[i] > -DEAD_THRESH) && (mv[i] < DEAD_THRESH)){
122
      mv[i] = 0;
123
    }
124
    
125
    else if(mv[i] > 500) {
126
      mv[i] = 500;
127
    }
128
    else if(mv[i] < -500) {
129
      mv[i] = -500;
130
    }
131
  }
132
133
  bool Movement = false;
134
  for(int i = 0; i < DOF; i++) {
135
    if(mv[i] != 0){
136
      Movement = true;
137
    }
138
  }
139
140
  if(Movement = true){
141
    send_command(mv[4], -mv[3], -mv[5], mv[0], mv[1], mv[2]);
142
  }
143
}