-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathUSB_PPM_Joystick.ino
114 lines (95 loc) · 2.63 KB
/
USB_PPM_Joystick.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
Anschluss:
D+ auf D2
D- auf D3
1.5k D- PullUp auf D4
PPM-In auf D8
*/
#include "UsbJoystick.h"
#define CHANNELS 8
#define READ_PIN 8
unsigned short a2dValue;
unsigned char high;
unsigned char low;
unsigned char temp;
unsigned char report[8];
unsigned int channel[CHANNELS];
unsigned int lastReadChannel[CHANNELS];
unsigned int counter=0;
unsigned int pulseUpTime, pulseLowTime;
boolean lastPinState = LOW;
int numCurPulse=-1;
void setup() {
pinMode (READ_PIN, INPUT);
usbDeviceConnect();
lastPinState = digitalRead(READ_PIN);
}
void loop () {
UsbJoystick.refresh(); // Let the AVRUSB driver do some houskeeping
calculateReport(); // Jump to our port read routine that orders the values
UsbJoystick.sendJoystick(report[0],report[1],report[2],report[3],report[4],report[5],report[6],report[7]); // send the values
}
void calculateReport() { //The values read from the analog ports have to be ordered in a way the HID protocol wants it; a bit confusing.
boolean curPinState = digitalRead(READ_PIN);
// slope change
if (curPinState != lastPinState) {
unsigned long pulseLength;
// rising
if (curPinState==HIGH && lastPinState==LOW) {
pulseUpTime=micros();
pulseLength=pulseUpTime-pulseLowTime;
}
else { // falling: curPinState==LOW && lastPinState==HIGH
pulseLowTime=micros();
pulseLength=pulseLowTime-pulseUpTime;
}
// rising und pause > 3000µs
if (pulseLength>3000 && curPinState==HIGH) {
numCurPulse=0;
}
else if (curPinState == HIGH && numCurPulse < CHANNELS && pulseLength<2000) {
unsigned int newValue = constrain(pulseLength-450,1,1023);
if (abs((int)newValue-(int)channel[numCurPulse])<300 || channel[numCurPulse]==0) {
channel[numCurPulse] = newValue;
}
numCurPulse += 1;
}
}
lastPinState = curPinState;
a2dValue = channel[1];
high = a2dValue >> 8;
low = a2dValue & 255;
report[0] = low;
temp = high;
a2dValue = channel[0];
high = a2dValue >> 6;
low = a2dValue & 63;
report[1] = (low << 2) + temp;
temp = high;
a2dValue =channel[2];
high = a2dValue >> 4;
low = a2dValue & 15;
report[2] = (low << 4) + temp;
temp = high;
a2dValue = channel[3];
high = a2dValue >> 2;
low = a2dValue & 3;
report[3] = (low << 6) + temp;
temp = high;
high = 0;
low = 0;
report[4] = temp;
temp = high;
a2dValue = channel[4];
high = a2dValue >> 8;
low = a2dValue & 255;
report[5] = low + temp;
temp = high;
a2dValue = channel[5];
high = a2dValue >> 6;
low = a2dValue & 63;
report[6] = (low << 2) + temp;
temp = high;
// 4 buttons , tossed around
report[7] = (temp & 15);
}