|
- /*
- * ladder.c:
- *
- * Gordon Henderson, June 2012
- ***********************************************************************
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <math.h>
-
- #include <wiringPi.h>
- #include <piFace.h>
-
- #ifndef TRUE
- # define TRUE (1==1)
- # define FALSE (1==2)
- #endif
-
- #undef DEBUG
-
- #define NUM_LEDS 8
-
-
- // Map the LEDs to the hardware pins
- // using PiFace pin numbers here
-
- #define PIFACE 200
-
- const int ledMap [NUM_LEDS] =
- {
- // 0, 1, 2, 3, 4, 5, 6, 7, 8
- 200, 201, 202, 203, 204, 205, 206, 207
- } ;
-
-
- // Some constants for our circuit simulation
-
- const double vBatt = 9.0 ; // Volts (ie. a PP3)
- const double capacitor = 0.001 ; // 1000uF
- const double rCharge = 2200.0 ; // ohms
- const double rDischarge = 68000.0 ; // ohms
- const double timeInc = 0.01 ; // Seconds
-
- double vCharge, vCap, vCapLast ;
-
-
-
- /*
- * setup:
- * Program the GPIO correctly and initialise the lamps
- ***********************************************************************
- */
-
- void setup (void)
- {
- int i ;
-
- wiringPiSetupSys () ;
-
- if (piFaceSetup (200) == -1)
- exit (1) ;
-
- // Enable internal pull-ups
-
- for (i = 0 ; i < 8 ; ++i)
- pullUpDnControl (PIFACE + i, PUD_UP) ;
-
- // Calculate the actual charging voltage - standard calculation of
- // vCharge = r2 / (r1 + r2) * vBatt
- //
- //
- // -----+--- vBatt
- // |
- // R1
- // |
- // +---+---- vCharge
- // | |
- // R2 C
- // | |
- // -----+---+-----
-
- vCharge = rDischarge / (rCharge + rDischarge) * vBatt ;
-
- // Start with no charge
-
- vCap = vCapLast = 0.0 ;
- }
-
-
- /*
- * introLeds
- * Put a little pattern on the LEDs to start with
- *********************************************************************************
- */
-
- void introLeds (void)
- {
- int i, j ;
-
-
- printf ("Pi Ladder\n") ;
- printf ("=========\n\n") ;
- printf (" vBatt: %6.2f volts\n", vBatt) ;
- printf (" rCharge: %6.0f ohms\n", rCharge) ;
- printf (" rDischarge: %6.0f ohms\n", rDischarge) ;
- printf (" vCharge: %6.2f volts\n", vCharge) ;
- printf (" capacitor: %6.0f uF\n", capacitor * 1000.0) ;
-
- // Flash 3 times:
-
- for (j = 0 ; j < 3 ; ++j)
- {
- for (i = 0 ; i < NUM_LEDS ; ++i)
- digitalWrite (ledMap [i], 1) ;
- delay (500) ;
- for (i = 0 ; i < NUM_LEDS ; ++i)
- digitalWrite (ledMap [i], 0) ;
- delay (100) ;
- }
-
- // All On
-
- for (i = 0 ; i < NUM_LEDS ; ++i)
- digitalWrite (ledMap [i], 1) ;
- delay (500) ;
-
- // Countdown...
-
- for (i = NUM_LEDS - 1 ; i >= 0 ; --i)
- {
- digitalWrite (ledMap [i], 0) ;
- delay (100) ;
- }
- delay (500) ;
- }
-
-
- /*
- * winningLeds
- * Put a little pattern on the LEDs to start with
- *********************************************************************************
- */
-
- void winningLeds (void)
- {
- int i, j ;
-
- // Flash 3 times:
-
- for (j = 0 ; j < 3 ; ++j)
- {
- for (i = 0 ; i < NUM_LEDS ; ++i)
- digitalWrite (ledMap [i], 1) ;
- delay (500) ;
- for (i = 0 ; i < NUM_LEDS ; ++i)
- digitalWrite (ledMap [i], 0) ;
- delay (100) ;
- }
-
- // All On
-
- for (i = 0 ; i < NUM_LEDS ; ++i)
- digitalWrite (ledMap [i], 1) ;
- delay (500) ;
-
- // Countup...
-
- for (i = 0 ; i < NUM_LEDS ; ++i)
- {
- digitalWrite (ledMap [i], 0) ;
- delay (100) ;
- }
- delay (500) ;
- }
-
-
- /*
- * chargeCapacitor: dischargeCapacitor:
- * Add or remove charge to the capacitor.
- * Standard capacitor formulae.
- *********************************************************************************
- */
-
- void chargeCapacitor (void)
- {
- vCap = (vCapLast - vCharge) *
- exp (- timeInc / (rCharge * capacitor)) + vCharge ;
-
- #ifdef DEBUG
- printf ("+vCap: %7.4f\n", vCap) ;
- #endif
-
- vCapLast = vCap ;
- }
-
- void dischargeCapacitor (void)
- {
- vCap = vCapLast *
- exp (- timeInc / (rDischarge * capacitor)) ;
-
- #ifdef DEBUG
- printf ("-vCap: %7.4f\n", vCap) ;
- #endif
-
- vCapLast = vCap ;
- }
-
-
- /*
- * ledBargraph:
- * Output the supplied number as a bargraph on the LEDs
- *********************************************************************************
- */
-
- void ledBargraph (double value, int topLedOn)
- {
- int topLed = (int)floor (value / vCharge * (double)NUM_LEDS) + 1 ;
- int i ;
-
- if (topLed > NUM_LEDS)
- topLed = NUM_LEDS ;
-
- if (!topLedOn)
- --topLed ;
-
- for (i = 0 ; i < topLed ; ++i)
- digitalWrite (ledMap [i], 1) ;
-
- for (i = topLed ; i < NUM_LEDS ; ++i)
- digitalWrite (ledMap [i], 0) ;
- }
-
-
- /*
- * ledOnAction:
- * Make sure the leading LED is on and check the button
- *********************************************************************************
- */
-
- void ledOnAction (void)
- {
- if (digitalRead (PIFACE) == LOW)
- {
- chargeCapacitor () ;
- ledBargraph (vCap, TRUE) ;
- }
- }
-
-
- /*
- * ledOffAction:
- * Make sure the leading LED is off and check the button
- *********************************************************************************
- */
-
- void ledOffAction (void)
- {
- dischargeCapacitor () ;
-
- // Are we still pushing the button?
-
- if (digitalRead (PIFACE) == LOW)
- {
- vCap = vCapLast = 0.0 ;
- ledBargraph (vCap, FALSE) ;
-
- // Wait until we release the button
-
- while (digitalRead (PIFACE) == LOW)
- delay (10) ;
- }
- }
-
-
- /*
- ***********************************************************************
- * The main program
- ***********************************************************************
- */
-
- int main (void)
- {
- unsigned int then, ledOnTime, ledOffTime ;
- unsigned int ourDelay = (int)(1000.0 * timeInc) ;
-
- setup () ;
- introLeds () ;
-
- // Setup the LED times - TODO reduce the ON time as the game progresses
-
- ledOnTime = 1000 ;
- ledOffTime = 1000 ;
-
- // This is our Gate/Squarewave loop
-
- for (;;)
- {
-
- // LED ON:
-
- (void)ledBargraph (vCap, TRUE) ;
- then = millis () + ledOnTime ;
- while (millis () < then)
- {
- ledOnAction () ;
- delay (ourDelay) ;
- }
-
- // Have we won yet?
- // We need vCap to be in the top NUM_LEDS of the vCharge
-
- if (vCap > ((double)(NUM_LEDS - 1) / (double)NUM_LEDS * vCharge)) // Woo hoo!
- {
- winningLeds () ;
- while (digitalRead (PIFACE) == HIGH)
- delay (10) ;
- while (digitalRead (PIFACE) == LOW)
- delay (10) ;
- vCap = vCapLast = 0.0 ;
- }
-
- // LED OFF:
-
- (void)ledBargraph (vCap, FALSE) ;
- then = millis () + ledOffTime ;
- while (millis () < then)
- {
- ledOffAction () ;
- delay (ourDelay) ;
- }
-
- }
-
- return 0 ;
- }
|