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