Guest User

Untitled

a guest
Feb 24th, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.28 KB | None | 0 0
  1. /* Sample RC servo input for 4 channels using Input Capture hardware perihperal and interrupts
  2. Written for Rick Anderson by Brian Schmalz
  3. 11/11/2017
  4. This software is put in the public domain.
  5. This sketch is means for a chipKIT Fubarino SD board, but can be easily adpated to any PIC32 based Arduino compatible board.
  6. */
  7.  
  8. /* Fubarino SD can only use pins 0, 1, 2, 3, and 10 as Input Capture.
  9. On any chipKIT board with PPS (like Fubarino Mini) additional setup is necessary to map the Input Capture
  10. peripherals to speciffic I/O pins, but you have much more flexibility in pin assignments.
  11. */
  12.  
  13. #include "Mouse.h"
  14.  
  15. // Which pins correspond to which RC input channel?
  16. #define RC_INPUT_1 0
  17. #define RC_INPUT_2 1
  18. #define RC_INPUT_3 2
  19. #define RC_INPUT_4 3
  20. // How many RC input channels are there?
  21. #define RC_INPUT_COUNT 4
  22.  
  23. // These two arrays hold the latest pulse measurements for each RC input channel
  24. volatile uint16_t pulseHighTime[RC_INPUT_COUNT];
  25. volatile uint16_t pulseLowTime[RC_INPUT_COUNT];
  26.  
  27. /* Four Input Capture Interrupt Service Routines
  28. These functions get called on each rising and falling edge. They check to see
  29. if a rising edge or falling edge just happened, then read out the Timer2 value that
  30. got latched on the edge, and calculate the high and low pulse times, then stick those
  31. times in the proper array.
  32. */
  33. void __USER_ISR InputCatpure1_ISR(void) {
  34. static uint16_t risingEdgeTime = 0;
  35. static uint16_t fallingEdgeTime = 0;
  36.  
  37. clearIntFlag(_INPUT_CAPTURE_1_IRQ);
  38. if (IC1CONbits.ICBNE == 1)
  39. {
  40. if (digitalRead(RC_INPUT_1) == HIGH)
  41. {
  42. risingEdgeTime = IC1BUF;
  43. pulseLowTime[0] = risingEdgeTime - fallingEdgeTime;
  44. }
  45. else
  46. {
  47. fallingEdgeTime = IC1BUF;
  48. pulseHighTime[0] = fallingEdgeTime - risingEdgeTime;
  49. }
  50. }
  51. }
  52.  
  53. void __USER_ISR InputCatpure2_ISR(void) {
  54. static uint16_t risingEdgeTime = 0;
  55. static uint16_t fallingEdgeTime = 0;
  56.  
  57. clearIntFlag(_INPUT_CAPTURE_2_IRQ);
  58. if (IC2CONbits.ICBNE == 1)
  59. {
  60. if (digitalRead(RC_INPUT_2) == HIGH)
  61. {
  62. risingEdgeTime = IC2BUF;
  63. pulseLowTime[1] = risingEdgeTime - fallingEdgeTime;
  64. }
  65. else
  66. {
  67. fallingEdgeTime = IC2BUF;
  68. pulseHighTime[1] = fallingEdgeTime - risingEdgeTime;
  69. }
  70. }
  71. }
  72.  
  73. void __USER_ISR InputCatpure3_ISR(void) {
  74. static uint16_t risingEdgeTime = 0;
  75. static uint16_t fallingEdgeTime = 0;
  76.  
  77. clearIntFlag(_INPUT_CAPTURE_3_IRQ);
  78. if (IC3CONbits.ICBNE == 1)
  79. {
  80. if (digitalRead(RC_INPUT_3) == HIGH)
  81. {
  82. risingEdgeTime = IC3BUF;
  83. pulseLowTime[2] = risingEdgeTime - fallingEdgeTime;
  84. }
  85. else
  86. {
  87. fallingEdgeTime = IC3BUF;
  88. pulseHighTime[2] = fallingEdgeTime - risingEdgeTime;
  89. }
  90. }
  91. }
  92.  
  93. void __USER_ISR InputCatpure4_ISR(void) {
  94. static uint16_t risingEdgeTime = 0;
  95. static uint16_t fallingEdgeTime = 0;
  96.  
  97. clearIntFlag(_INPUT_CAPTURE_4_IRQ);
  98. if (IC4CONbits.ICBNE == 1)
  99. {
  100. if (digitalRead(RC_INPUT_4) == HIGH)
  101. {
  102. risingEdgeTime = IC4BUF;
  103. pulseLowTime[3] = risingEdgeTime - fallingEdgeTime;
  104. }
  105. else
  106. {
  107. fallingEdgeTime = IC4BUF;
  108. pulseHighTime[3] = fallingEdgeTime - risingEdgeTime;
  109. }
  110. }
  111. }
  112.  
  113. void setup() {
  114. Serial.begin(9600);
  115. delay(3000);
  116. Serial.println("OK we are starting now");
  117. Mouse.begin();
  118.  
  119.  
  120. /* Set up each of the four Input Capture modules
  121. We want them to generate an interrupt on each rising and falling edge of the input
  122. We also want them all to use Timer2 as their timebase timer
  123. */
  124. IC1CON = 0;
  125. IC1CONbits.ICM = 1; // Captured and interrupt on every rising and falling edge
  126. IC1CONbits.ICTMR = 1; // Set to user Timer2
  127. IC1CONbits.ON = 1; // Turn IC1 on
  128.  
  129. IC2CON = 0;
  130. IC2CONbits.ICM = 1; // Captured and interrupt on every rising and falling edge
  131. IC2CONbits.ICTMR = 1; // Set to user Timer2
  132. IC2CONbits.ON = 1; // Turn IC2 on
  133.  
  134. IC3CON = 0;
  135. IC3CONbits.ICM = 1; // Captured and interrupt on every rising and falling edge
  136. IC3CONbits.ICTMR = 1; // Set to user Timer2
  137. IC3CONbits.ON = 1; // Turn IC3 on
  138.  
  139. IC4CON = 0;
  140. IC4CONbits.ICM = 1; // Captured and interrupt on every rising and falling edge
  141. IC4CONbits.ICTMR = 1; // Set to user Timer2
  142. IC4CONbits.ON = 1; // Turn IC4 on
  143.  
  144. /* Set up Timer2: We want it to simply count up. We set the prescaler to 1:64
  145. so that the 40MHz PCLK gets divided down to 1.25Mhz. This is nice because
  146. then it gives us both high and low periods under 65535 for normal RC servo
  147. times (0-3 ms high time and 17-20ms low time)
  148. */
  149. PR2 = 0xFFFF; // Run from 0 to 0xFFFF
  150. T2CONbits.TCKPS = 5; // 1:32 prescale, which means 40MHz/64 or 1.25MHz clock rate
  151. T2CONbits.TON = 1; // Turn on Timer2
  152.  
  153. // Set all input captures as inputs
  154. pinMode(RC_INPUT_1, INPUT);
  155. pinMode(RC_INPUT_2, INPUT);
  156. pinMode(RC_INPUT_3, INPUT);
  157. pinMode(RC_INPUT_4, INPUT);
  158. Serial.println("ready");
  159.  
  160. // Set each Input Capture up to use its ISR routine
  161. setIntVector(_INPUT_CAPTURE_1_VECTOR, InputCatpure1_ISR);
  162. setIntPriority(_INPUT_CAPTURE_1_VECTOR, 4, 0);
  163. clearIntFlag(_INPUT_CAPTURE_1_IRQ);
  164. setIntEnable(_INPUT_CAPTURE_1_IRQ);
  165.  
  166. setIntVector(_INPUT_CAPTURE_2_VECTOR, InputCatpure2_ISR);
  167. setIntPriority(_INPUT_CAPTURE_2_VECTOR, 4, 0);
  168. clearIntFlag(_INPUT_CAPTURE_2_IRQ);
  169. setIntEnable(_INPUT_CAPTURE_2_IRQ);
  170.  
  171. setIntVector(_INPUT_CAPTURE_3_VECTOR, InputCatpure3_ISR);
  172. setIntPriority(_INPUT_CAPTURE_3_VECTOR, 4, 0);
  173. clearIntFlag(_INPUT_CAPTURE_3_IRQ);
  174. setIntEnable(_INPUT_CAPTURE_3_IRQ);
  175.  
  176. setIntVector(_INPUT_CAPTURE_4_VECTOR, InputCatpure4_ISR);
  177. setIntPriority(_INPUT_CAPTURE_4_VECTOR, 4, 0);
  178. clearIntFlag(_INPUT_CAPTURE_4_IRQ);
  179. setIntEnable(_INPUT_CAPTURE_4_IRQ);
  180. }
  181.  
  182. void loop() {
  183. static uint32_t lastPrintTime = 0;
  184. float uSscale = 0.4;
  185.  
  186. /* So the way things work, the ISRs will get called and they will constantly update
  187. the pulseHighTime and pulseLowTime arrays "in the background". In other words the
  188. mainline code here doesn't ever have to do anything other than simply read out
  189. the values in the arrays, and those values will always be the most recent pulse
  190. measurements. If you care about converting the values to real time (like in
  191. microsconds), the units for these values are in 1.25MHz 'counts'. So 1ms = 1250
  192. 'counts'.
  193. */
  194. // To demo things, simply print out all 4 high and low pulse times every half second
  195. if ((millis() - lastPrintTime) > 500)
  196. {
  197. lastPrintTime = millis();
  198. char pulses[100];
  199. char micros[100];
  200. sprintf(pulses, "high1: %05u low1: %05u high2: %05u low2: %05u high3: %05u low3: %05u high4: %05u low4: %05u\n",
  201. pulseHighTime[0],
  202. pulseLowTime[0],
  203. pulseHighTime[1],
  204. pulseLowTime[1],
  205. pulseHighTime[2],
  206. pulseLowTime[2],
  207. pulseHighTime[3],
  208. pulseLowTime[3]
  209. );
  210. Serial.print(pulses);
  211. sprintf(micros, "ch1: %05u ch2: %05u ch3: %05u ch4: %05u\n",
  212. (int) (pulseHighTime[0] * uSscale),
  213. (int) (pulseHighTime[1] * uSscale),
  214. (int) (pulseHighTime[2] * uSscale),
  215. (int) (pulseHighTime[3] * uSscale)
  216. );
  217.  
  218. Serial.print(micros);
  219.  
  220. }
  221. if ( (int) (pulseHighTime[2] * uSscale) > 1500 ) {
  222. int xReading = map( (int) (pulseHighTime[0] * uSscale), 1000, 2000, -6, 6);
  223. int yReading = map( (int) (pulseHighTime[1] * uSscale), 1000, 2000, -6, 6);
  224.  
  225. Mouse.move(xReading, yReading, 0);
  226. }
  227. }
Add Comment
Please, Sign In to add comment