|
| 1 | +/* |
| 2 | +* |
| 3 | +* A very trivial PPM to USB Joystick converter, for teensy controllers |
| 4 | +* Time between falling edges is measured and converted to joystick axis. |
| 5 | +* Additionnally, the ranges are auto scaled. |
| 6 | +* |
| 7 | +*/ |
| 8 | + |
| 9 | +// Maximum number of channels |
| 10 | +#define NB_PEAKS 15 |
| 11 | +#define PPM_PIN 2 |
| 12 | + |
| 13 | +unsigned long int before; |
| 14 | + |
| 15 | +typedef struct { |
| 16 | + int val; |
| 17 | + int min; |
| 18 | + int max; |
| 19 | +} PEAK; |
| 20 | + |
| 21 | +PEAK peaks[NB_PEAKS]; |
| 22 | + |
| 23 | +//specifing arrays and variables to store values |
| 24 | + |
| 25 | +void readPin() { |
| 26 | + |
| 27 | + static int i = 0; |
| 28 | + unsigned int now = micros(); //store time value a when pin value is falling |
| 29 | + unsigned diff = now-before; //calculating time inbetween two peaks |
| 30 | + before = now; // |
| 31 | + |
| 32 | + if (diff > 6000) { |
| 33 | + i=0; |
| 34 | + return; |
| 35 | + } |
| 36 | + |
| 37 | + if (i++>NB_PEAKS) |
| 38 | + i = 0; |
| 39 | + |
| 40 | + peaks[i].val=diff; |
| 41 | + |
| 42 | +} |
| 43 | + |
| 44 | +unsigned int valToPos(int i) { |
| 45 | + PEAK * pPeak = &peaks[i]; |
| 46 | + int range = pPeak->max-pPeak->min; |
| 47 | + |
| 48 | + if (range == 0) |
| 49 | + return 0; |
| 50 | + |
| 51 | + return ((pPeak->val-pPeak->min)*1024)/range; |
| 52 | +} |
| 53 | + |
| 54 | +bool valToButton(int i) { |
| 55 | + int v = valToPos(i); |
| 56 | + if (v > 512) |
| 57 | + return true; |
| 58 | + else |
| 59 | + return false; |
| 60 | +} |
| 61 | + |
| 62 | +void getPeaks(){ |
| 63 | + |
| 64 | + for (int i=0;i<NB_PEAKS;i++) { |
| 65 | + PEAK * pPeak = &peaks[i]; |
| 66 | + if (pPeak->min>pPeak->val && pPeak->val != 0) |
| 67 | + pPeak->min = pPeak->val; |
| 68 | + |
| 69 | + if (pPeak->max < pPeak->val) |
| 70 | + pPeak->max = pPeak->val; |
| 71 | + |
| 72 | + #ifdef DEBUG |
| 73 | + Serial.print(x[i]); |
| 74 | + |
| 75 | + Serial.print("("); |
| 76 | + Serial.print(xMin[i]); |
| 77 | + Serial.print(","); |
| 78 | + Serial.print(xMax[i]); |
| 79 | + Serial.print(")->"); |
| 80 | + Serial.print(valToPos(i)); |
| 81 | + |
| 82 | + Serial.print("\t"); |
| 83 | + #endif |
| 84 | + |
| 85 | + |
| 86 | + } |
| 87 | +#ifdef DEBUG |
| 88 | + Serial.println(""); |
| 89 | +#endif // DEBUG |
| 90 | + |
| 91 | + Joystick.X(valToPos(1)); |
| 92 | + Joystick.Y(valToPos(2)); |
| 93 | + Joystick.Z(valToPos(3)); |
| 94 | + Joystick.Zrotate(valToPos(4)); |
| 95 | + |
| 96 | + Joystick.sliderLeft(valToPos(5)); |
| 97 | + Joystick.sliderRight(valToPos(6)); |
| 98 | + |
| 99 | + Joystick.button(1, valToButton(7)); |
| 100 | + Joystick.button(2, valToButton(8)); |
| 101 | + Joystick.button(3, valToButton(9)); |
| 102 | + |
| 103 | + |
| 104 | +} |
| 105 | + |
| 106 | + |
| 107 | +void setup() |
| 108 | +{ |
| 109 | +#ifdef DEBUG |
| 110 | + Serial.begin(9600); |
| 111 | +#endif // DEBUG |
| 112 | + pinMode(PPM_PIN, INPUT_PULLUP); |
| 113 | + Joystick.useManualSend(true); |
| 114 | + for (int i=0; i<NB_PEAKS;i++) { |
| 115 | + PEAK * pPeak = &peaks[i]; |
| 116 | + pPeak->min=1000; |
| 117 | + pPeak->max=2000; |
| 118 | + } |
| 119 | + |
| 120 | + attachInterrupt(digitalPinToInterrupt(2), readPin , FALLING); |
| 121 | +} |
| 122 | + |
| 123 | +void loop() |
| 124 | +{ |
| 125 | + getPeaks(); |
| 126 | + |
| 127 | + Joystick.send_now(); |
| 128 | + |
| 129 | + delay(20); // do not print too fast! |
| 130 | +} |
0 commit comments