ladder.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /*
  2. * ladder.c:
  3. *
  4. * Gordon Henderson, June 2012
  5. ***********************************************************************
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10. #include <math.h>
  11. #include <wiringPi.h>
  12. #include <piFace.h>
  13. #ifndef TRUE
  14. # define TRUE (1==1)
  15. # define FALSE (1==2)
  16. #endif
  17. #undef DEBUG
  18. #define NUM_LEDS 8
  19. // Map the LEDs to the hardware pins
  20. // using PiFace pin numbers here
  21. #define PIFACE 200
  22. const int ledMap [NUM_LEDS] =
  23. {
  24. // 0, 1, 2, 3, 4, 5, 6, 7, 8
  25. 200, 201, 202, 203, 204, 205, 206, 207
  26. } ;
  27. // Some constants for our circuit simulation
  28. const double vBatt = 9.0 ; // Volts (ie. a PP3)
  29. const double capacitor = 0.001 ; // 1000uF
  30. const double rCharge = 2200.0 ; // ohms
  31. const double rDischarge = 68000.0 ; // ohms
  32. const double timeInc = 0.01 ; // Seconds
  33. double vCharge, vCap, vCapLast ;
  34. /*
  35. * setup:
  36. * Program the GPIO correctly and initialise the lamps
  37. ***********************************************************************
  38. */
  39. void setup (void)
  40. {
  41. int i ;
  42. wiringPiSetupSys () ;
  43. if (piFaceSetup (200) == -1)
  44. exit (1) ;
  45. // Enable internal pull-ups
  46. for (i = 0 ; i < 8 ; ++i)
  47. pullUpDnControl (PIFACE + i, PUD_UP) ;
  48. // Calculate the actual charging voltage - standard calculation of
  49. // vCharge = r2 / (r1 + r2) * vBatt
  50. //
  51. //
  52. // -----+--- vBatt
  53. // |
  54. // R1
  55. // |
  56. // +---+---- vCharge
  57. // | |
  58. // R2 C
  59. // | |
  60. // -----+---+-----
  61. vCharge = rDischarge / (rCharge + rDischarge) * vBatt ;
  62. // Start with no charge
  63. vCap = vCapLast = 0.0 ;
  64. }
  65. /*
  66. * introLeds
  67. * Put a little pattern on the LEDs to start with
  68. *********************************************************************************
  69. */
  70. void introLeds (void)
  71. {
  72. int i, j ;
  73. printf ("Pi Ladder\n") ;
  74. printf ("=========\n\n") ;
  75. printf (" vBatt: %6.2f volts\n", vBatt) ;
  76. printf (" rCharge: %6.0f ohms\n", rCharge) ;
  77. printf (" rDischarge: %6.0f ohms\n", rDischarge) ;
  78. printf (" vCharge: %6.2f volts\n", vCharge) ;
  79. printf (" capacitor: %6.0f uF\n", capacitor * 1000.0) ;
  80. // Flash 3 times:
  81. for (j = 0 ; j < 3 ; ++j)
  82. {
  83. for (i = 0 ; i < NUM_LEDS ; ++i)
  84. digitalWrite (ledMap [i], 1) ;
  85. delay (500) ;
  86. for (i = 0 ; i < NUM_LEDS ; ++i)
  87. digitalWrite (ledMap [i], 0) ;
  88. delay (100) ;
  89. }
  90. // All On
  91. for (i = 0 ; i < NUM_LEDS ; ++i)
  92. digitalWrite (ledMap [i], 1) ;
  93. delay (500) ;
  94. // Countdown...
  95. for (i = NUM_LEDS - 1 ; i >= 0 ; --i)
  96. {
  97. digitalWrite (ledMap [i], 0) ;
  98. delay (100) ;
  99. }
  100. delay (500) ;
  101. }
  102. /*
  103. * winningLeds
  104. * Put a little pattern on the LEDs to start with
  105. *********************************************************************************
  106. */
  107. void winningLeds (void)
  108. {
  109. int i, j ;
  110. // Flash 3 times:
  111. for (j = 0 ; j < 3 ; ++j)
  112. {
  113. for (i = 0 ; i < NUM_LEDS ; ++i)
  114. digitalWrite (ledMap [i], 1) ;
  115. delay (500) ;
  116. for (i = 0 ; i < NUM_LEDS ; ++i)
  117. digitalWrite (ledMap [i], 0) ;
  118. delay (100) ;
  119. }
  120. // All On
  121. for (i = 0 ; i < NUM_LEDS ; ++i)
  122. digitalWrite (ledMap [i], 1) ;
  123. delay (500) ;
  124. // Countup...
  125. for (i = 0 ; i < NUM_LEDS ; ++i)
  126. {
  127. digitalWrite (ledMap [i], 0) ;
  128. delay (100) ;
  129. }
  130. delay (500) ;
  131. }
  132. /*
  133. * chargeCapacitor: dischargeCapacitor:
  134. * Add or remove charge to the capacitor.
  135. * Standard capacitor formulae.
  136. *********************************************************************************
  137. */
  138. void chargeCapacitor (void)
  139. {
  140. vCap = (vCapLast - vCharge) *
  141. exp (- timeInc / (rCharge * capacitor)) + vCharge ;
  142. #ifdef DEBUG
  143. printf ("+vCap: %7.4f\n", vCap) ;
  144. #endif
  145. vCapLast = vCap ;
  146. }
  147. void dischargeCapacitor (void)
  148. {
  149. vCap = vCapLast *
  150. exp (- timeInc / (rDischarge * capacitor)) ;
  151. #ifdef DEBUG
  152. printf ("-vCap: %7.4f\n", vCap) ;
  153. #endif
  154. vCapLast = vCap ;
  155. }
  156. /*
  157. * ledBargraph:
  158. * Output the supplied number as a bargraph on the LEDs
  159. *********************************************************************************
  160. */
  161. void ledBargraph (double value, int topLedOn)
  162. {
  163. int topLed = (int)floor (value / vCharge * (double)NUM_LEDS) + 1 ;
  164. int i ;
  165. if (topLed > NUM_LEDS)
  166. topLed = NUM_LEDS ;
  167. if (!topLedOn)
  168. --topLed ;
  169. for (i = 0 ; i < topLed ; ++i)
  170. digitalWrite (ledMap [i], 1) ;
  171. for (i = topLed ; i < NUM_LEDS ; ++i)
  172. digitalWrite (ledMap [i], 0) ;
  173. }
  174. /*
  175. * ledOnAction:
  176. * Make sure the leading LED is on and check the button
  177. *********************************************************************************
  178. */
  179. void ledOnAction (void)
  180. {
  181. if (digitalRead (PIFACE) == LOW)
  182. {
  183. chargeCapacitor () ;
  184. ledBargraph (vCap, TRUE) ;
  185. }
  186. }
  187. /*
  188. * ledOffAction:
  189. * Make sure the leading LED is off and check the button
  190. *********************************************************************************
  191. */
  192. void ledOffAction (void)
  193. {
  194. dischargeCapacitor () ;
  195. // Are we still pushing the button?
  196. if (digitalRead (PIFACE) == LOW)
  197. {
  198. vCap = vCapLast = 0.0 ;
  199. ledBargraph (vCap, FALSE) ;
  200. // Wait until we release the button
  201. while (digitalRead (PIFACE) == LOW)
  202. delay (10) ;
  203. }
  204. }
  205. /*
  206. ***********************************************************************
  207. * The main program
  208. ***********************************************************************
  209. */
  210. int main (void)
  211. {
  212. unsigned int then, ledOnTime, ledOffTime ;
  213. unsigned int ourDelay = (int)(1000.0 * timeInc) ;
  214. setup () ;
  215. introLeds () ;
  216. // Setup the LED times - TODO reduce the ON time as the game progresses
  217. ledOnTime = 1000 ;
  218. ledOffTime = 1000 ;
  219. // This is our Gate/Squarewave loop
  220. for (;;)
  221. {
  222. // LED ON:
  223. (void)ledBargraph (vCap, TRUE) ;
  224. then = millis () + ledOnTime ;
  225. while (millis () < then)
  226. {
  227. ledOnAction () ;
  228. delay (ourDelay) ;
  229. }
  230. // Have we won yet?
  231. // We need vCap to be in the top NUM_LEDS of the vCharge
  232. if (vCap > ((double)(NUM_LEDS - 1) / (double)NUM_LEDS * vCharge)) // Woo hoo!
  233. {
  234. winningLeds () ;
  235. while (digitalRead (PIFACE) == HIGH)
  236. delay (10) ;
  237. while (digitalRead (PIFACE) == LOW)
  238. delay (10) ;
  239. vCap = vCapLast = 0.0 ;
  240. }
  241. // LED OFF:
  242. (void)ledBargraph (vCap, FALSE) ;
  243. then = millis () + ledOffTime ;
  244. while (millis () < then)
  245. {
  246. ledOffAction () ;
  247. delay (ourDelay) ;
  248. }
  249. }
  250. return 0 ;
  251. }