Gordons Projects

--> Projects Top-Level GIT

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