Guest User

Untitled

a guest
Jul 20th, 2018
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.72 KB | None | 0 0
  1. /* S107G IR packet transmitter (ver 1.3)
  2. 0-07 MAY 2011 (Aqualung)
  3. 1-14 MAY 2011 - replaced digitalWrites with port operations
  4. 2-15 MAY 2011 - added pre-defined bit pattern to eliminate
  5. the need to rotate the bit into position
  6. 3-05 MAY 2011 - added safe restart state 7
  7. */
  8.  
  9. /*
  10.  
  11. Uses ATmega328 @ 16MHz (your mileage may vary)
  12. Connect anode (+) of IR LED to 5V and connect
  13. cathode (-) to pin 8 using a 100 ohm resistor
  14.  
  15. The ISR is called every 13us and is implemented as a state
  16. machine:
  17.  
  18. state 0 idle
  19. state 1 start pulses
  20. state 2 start pause
  21. state 3 mark pulses states 3 and 4
  22. state 4 data pause(s) repeat 32 times
  23. state 5 stop pulses
  24. state 6 inter-packet pause (!busy during this time)
  25. state 7 safe start state (use after state 0 is set)
  26.  
  27. During the loop() function, the busy flag should be used to
  28. know when it's okay to update data values - updating the
  29. values during transmission may corrupt the data - setting
  30. the state to 0 effectively disables transmission of data -
  31. setting it to 7 will safely restart the next packet sequence.
  32.  
  33. Data values are 7-bits in length - the yaw, pitch, and
  34. adjustment (yaw offset) values are centered at 63/64 -
  35. a range of 64->127 will increase in one direction while
  36. a range of 63->0 will increase in the opposite direction -
  37. the throttle values range from 0->127 and increase as the
  38. value increases.
  39.  
  40. Setting state to 0 and immediately setting it back to 1 can
  41. possibly send data sooner than intended. Setting state to 0
  42. while busy can cause counter values to be corrupted and send
  43. the state machine into a black hole. After setting the state
  44. to 0, restart the state machine by setting the state to 7.
  45. */
  46.  
  47. #define LED 8
  48. #define PORT PORTB
  49. #define PIN 1<<PORTB0
  50. #define STARTL 153
  51. #define STARTH 153
  52. #define MARKL 23
  53. #define DATAC0 21
  54. #define DATAC1 51
  55. #define STOPL 23
  56. #define SPACEH 15385
  57. #define TCOUNT 92
  58.  
  59. volatile byte state,startH,startL,markL,stopL,dataC,countP,countR;
  60. volatile unsigned int spaceH;
  61. volatile bool busy;
  62. // maskB[] contains bit mask values
  63. const volatile byte maskB[] = {128,64,32,16,8,4,2,1};
  64. // dataP[] has four 7-bit packet values
  65. // dataP[0] = yaw 63->0 / 64->127
  66. // dataP[1] = pitch 63->0 / 64->127
  67. // dataP[2] = throttle 0->127
  68. // dataP[3] = offset 63->0 / 64->127
  69. volatile byte dataP[] = {63,63,0,63};
  70.  
  71. void setup()
  72. {
  73. pinMode(LED,OUTPUT);
  74. digitalWrite(LED,HIGH);
  75. Serial.begin(9600);
  76. // Disable the timer2 overflow interrupt
  77. TIMSK2 &= ~(1<<TOIE2);
  78. // Configure timer2 in normal mode
  79. TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
  80. TCCR2B &= ~(1<<WGM22);
  81. // Select internal clock source
  82. ASSR &= ~(1<<AS2);
  83. // Disable compMatchA interrupt
  84. TIMSK2 &= ~(1<<OCIE2A);
  85. // Disable pre-scaler (use system clock)
  86. TCCR2B |= (1<<CS20);
  87. TCCR2B &= ~((1<<CS22) | (1<<CS21));
  88. // Set the initial values - all cycle count values must be odd
  89. startL = STARTL;
  90. startH = STARTH;
  91. markL = MARKL;
  92. stopL = STOPL;
  93. spaceH = SPACEH;
  94. //------------
  95. countP = 4;
  96. countR = 8;
  97. state = 1;
  98. busy = true;
  99. Serial.println("Starting ... 5 second delay");
  100. delay(5000);
  101. // Load timer counter and enable the timer
  102. TCNT2 = TCOUNT;
  103. TIMSK2 |= (1<<TOIE2);
  104. }
  105.  
  106. void loop()
  107. {
  108. if(!busy)
  109. {
  110. // --- approximately 165ms is available ---
  111. // set dataP[0] to new yaw value
  112. // dataP[0] = 77;
  113. // set dataP[1] to new pitch value
  114. // dataP[1] += 3;
  115. // set dataP[2] to new throttle value
  116. // dataP[2]--;
  117. // set dataP[3] to new adjustment value
  118. // dataP[3] = dataP[2] / 32;
  119. // make sure to set the busy flag to avoid the
  120. // next pass through the loop
  121. busy = true;
  122. }
  123. }
  124.  
  125. ISR(TIMER2_OVF_vect)
  126. {
  127. TCNT2 = TCOUNT;
  128. switch(state)
  129. {
  130. case 0: // idle state
  131. {
  132. PORT |= PIN; // make sure LED is turned off
  133. }
  134. break;
  135.  
  136. case 1: // startL (low)
  137. spaceH--;
  138. if(startL--)
  139. {
  140. if(startL & 1)
  141. {
  142. PORT |= PIN;
  143. }
  144. else
  145. {
  146. PORT &= ~PIN;
  147. }
  148. }
  149. else
  150. {
  151. PORT |= PIN;
  152. startL = STARTL;
  153. state = 2;
  154. }
  155. break;
  156.  
  157. case 2: // startH (high)
  158. spaceH--;
  159. if(!startH--)
  160. {
  161. startH = STARTH;
  162. countP = 4;
  163. state = 3;
  164. }
  165. break;
  166.  
  167. case 3: // markL (low)
  168. spaceH--;
  169. if(markL--)
  170. {
  171. if(markL & 1)
  172. {
  173. PORT |= PIN;
  174. }
  175. else
  176. {
  177. PORT &= ~PIN;
  178. }
  179. }
  180. else
  181. {
  182. PORT |= PIN;
  183. if(dataP[4-countP] & maskB[8-(countR--)])
  184. {
  185. dataC = DATAC1;
  186. }
  187. else
  188. {
  189. dataC = DATAC0;
  190. }
  191. markL = MARKL;
  192. state = 4;
  193. }
  194. break;
  195.  
  196. case 4: // dataH (high)
  197. spaceH--;
  198. if(!dataC--)
  199. {
  200. if(!countR)
  201. {
  202. countR = 8;
  203. countP--;
  204. }
  205. if(!countP)
  206. {
  207. state = 5;
  208. }
  209. else
  210. {
  211. state = 3;
  212. }
  213. }
  214. break;
  215.  
  216. case 5: // stopL (low)
  217. spaceH--;
  218. if(stopL--)
  219. {
  220. if(stopL & 1)
  221. {
  222. PORT |= PIN;
  223. }
  224. else
  225. {
  226. PORT &= ~PIN;
  227. }
  228. }
  229. else
  230. {
  231. PORT |= PIN;
  232. stopL = STOPL;
  233. busy = false;
  234. state = 6;
  235. }
  236. break;
  237.  
  238. case 6: // spaceH (high)
  239. if(!spaceH--)
  240. {
  241. spaceH = SPACEH;
  242. busy = true;
  243. state = 1;
  244. }
  245. break;
  246.  
  247. case 7: // safe start (set state to 7 to restart state machine after setting state to 0)
  248. {
  249. startL = STARTL;
  250. startH = STARTH;
  251. markL = MARKL;
  252. stopL = STOPL;
  253. countP = 4;
  254. countR = 8;
  255. state = 6;
  256. }
  257. break;
  258. }
  259. }
Add Comment
Please, Sign In to add comment