Gordons Projects

--> Projects Top-Level GIT

Initial move to GIT for the gpioExamples
authorGordon Henderson <gordon@drogon.net>
Sat, 18 Aug 2012 17:06:40 +0000 (18:06 +0100)
committerGordon Henderson <gordon@drogon.net>
Sat, 18 Aug 2012 17:06:40 +0000 (18:06 +0100)
ladder/Makefile [new file with mode: 0644]
ladder/ladder-test.sh [new file with mode: 0755]
ladder/ladder.c [new file with mode: 0644]
lcd/Makefile [new file with mode: 0644]
lcd/lcd.c [new file with mode: 0644]
tuxx/Makefile [new file with mode: 0644]
tuxx/tuxx.c [new file with mode: 0644]
tuxx/tuxx.sh [new file with mode: 0755]

diff --git a/ladder/Makefile b/ladder/Makefile
new file mode 100644 (file)
index 0000000..ac33f2f
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Makefile:
+#      wiringPi - Wiring Compatable library for the Raspberry Pi
+#      https://projects.drogon.net/wiring-pi
+#
+#      Copyright (c) 2012 Gordon Henderson
+#################################################################################
+# This file is part of wiringPi:
+#      Wiring Compatable library for the Raspberry Pi
+#
+#    wiringPi is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    wiringPi is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+#################################################################################
+
+
+#DEBUG = -g -O0
+DEBUG  = -O3
+CC     = gcc
+INCLUDE        = -I/usr/local/include
+CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
+
+LDFLAGS        = -L/usr/local/lib
+LIBS    = -lwiringPi -lm
+
+# Should not alter anything below this line
+###############################################################################
+
+SRC    =       ladder.c
+
+OBJ    =       ladder.o
+
+all:           ladder
+
+ladder:        ladder.o
+       @echo [link]
+       $(CC) -o $@ ladder.o $(LDFLAGS) $(LIBS)
+       
+.c.o:
+       @echo [CC] $<
+       @$(CC) -c $(CFLAGS) $< -o $@
+
+clean:
+       rm -f $(OBJ) *~ core tags ladder
+
+tags:  $(SRC)
+       @echo [ctags]
+       @ctags $(SRC)
+
+depend:
+       makedepend -Y $(SRC)
+
+# DO NOT DELETE
diff --git a/ladder/ladder-test.sh b/ladder/ladder-test.sh
new file mode 100755 (executable)
index 0000000..48b7e1a
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+setup ()
+{
+  echo Setup
+  for i in 0 1 2 3 4 5 6 7 10 11 12 13 ; do gpio mode  $i out ; done
+}
+
+setup
+while true; do
+  for i in 0 1 2 3 4 5 6 7 10 11 12 13 ; do
+    gpio write $i   0
+    sleep 0.1
+  done
+  for i in 0 1 2 3 4 5 6 7 10 11 12 13 ; do
+    gpio write $i   1
+    sleep 0.1
+  done
+done
diff --git a/ladder/ladder.c b/ladder/ladder.c
new file mode 100644 (file)
index 0000000..5afd677
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ * ladder.c:
+ *
+ *     Gordon Henderson, June 2012
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+
+#include <wiringPi.h>
+
+#ifndef        TRUE
+#  define      TRUE    (1==1)
+#  define      FALSE   (1==2)
+#endif
+
+#undef DEBUG
+
+// The input button
+
+#define        BUTTON          8
+
+
+// Map the LEDs to the hardware pins
+//     using wiringPi pin numbers here
+
+const int ledMap [12] =
+{
+  13, 12, 11, 10, 7, 6, 5, 4, 3, 2, 1, 0
+} ;
+
+
+// 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 ;
+
+  if (geteuid () != 0)
+  {
+    fprintf (stderr, "ladder: Need to be root to run (sudo?)\n") ;
+    exit (0) ;
+  }
+
+  if (wiringPiSetup () == -1)
+    exit (1) ;
+
+  for (i = 0 ; i < 12 ; ++i)
+  {
+    digitalWrite (ledMap [i], 0) ;
+    pinMode (ledMap [i], OUTPUT) ;
+  }
+
+  pinMode (BUTTON, INPUT) ;
+
+// 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 < 12 ; ++i)
+      digitalWrite (ledMap [i], 1) ;
+    delay (500) ;
+    for (i = 0 ; i < 12 ; ++i)
+      digitalWrite (ledMap [i], 0) ;
+    delay (100) ;
+  }
+
+// All On
+
+  for (i = 0 ; i < 12 ; ++i)
+    digitalWrite (ledMap [i], 1) ;
+  delay (500) ;
+
+// Countdown...
+
+  for (i = 11 ; 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 < 12 ; ++i)
+      digitalWrite (ledMap [i], 1) ;
+    delay (500) ;
+    for (i = 0 ; i < 12 ; ++i)
+      digitalWrite (ledMap [i], 0) ;
+    delay (100) ;
+  }
+
+// All On
+
+  for (i = 0 ; i < 12 ; ++i)
+    digitalWrite (ledMap [i], 1) ;
+  delay (500) ;
+
+// Countup...
+
+  for (i = 0 ; i < 12 ; ++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 * 12.0) + 1 ;
+  int i ;
+
+  if (topLed > 12)
+    topLed = 12 ;
+
+  if (!topLedOn)
+    --topLed ;
+
+  for (i = 0 ; i < topLed ; ++i)
+    digitalWrite (ledMap [i], 1) ;
+
+  for (i = topLed ; i < 12 ; ++i)
+    digitalWrite (ledMap [i], 0) ;
+}
+
+
+/*
+ * ledOnAction:
+ *     Make sure the leading LED is on and check the button
+ *********************************************************************************
+ */
+
+void ledOnAction (void)
+{
+  if (digitalRead (BUTTON) == 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 (BUTTON) == LOW)
+  {
+    vCap = vCapLast = 0.0 ;
+    ledBargraph (vCap, FALSE) ;
+
+// Wait until we release the button
+
+    while (digitalRead (BUTTON) == 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 12th of the vCharge
+
+    if (vCap > (11.0 / 12.0 * vCharge))        // Woo hoo!
+    {
+      winningLeds () ;
+      while (digitalRead (BUTTON) == HIGH)
+       delay (10) ;
+      while (digitalRead (BUTTON) == LOW)
+       delay (10) ;
+      vCap = vCapLast = 0.0 ;
+    }
+
+// LED OFF:
+
+    (void)ledBargraph (vCap, FALSE) ;
+    then = millis () + ledOffTime ;
+    while (millis () < then)
+    {
+      ledOffAction () ;
+      delay        (ourDelay) ;
+    }
+
+  }
+
+  return 0 ;
+}
diff --git a/lcd/Makefile b/lcd/Makefile
new file mode 100644 (file)
index 0000000..541d234
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Makefile:
+#      wiringPi - Wiring Compatable library for the Raspberry Pi
+#      https://projects.drogon.net/wiring-pi
+#
+#      Copyright (c) 2012 Gordon Henderson
+#################################################################################
+# This file is part of wiringPi:
+#      Wiring Compatable library for the Raspberry Pi
+#
+#    wiringPi is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    wiringPi is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+#################################################################################
+
+
+#DEBUG = -g -O0
+DEBUG  = -O3
+CC     = gcc
+INCLUDE        = -I/usr/local/include
+CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
+
+LDFLAGS        = -L/usr/local/lib
+LIBS    = -lwiringPi
+
+# Should not alter anything below this line
+###############################################################################
+
+SRC    =       lcd.c
+
+OBJ    =       lcd.o
+
+all:           lcd
+
+lcd:   lcd.o
+       @echo [link]
+       $(CC) -o $@ lcd.o $(LDFLAGS) $(LIBS)
+       
+.c.o:
+       @echo [CC] $<
+       @$(CC) -c $(CFLAGS) $< -o $@
+
+clean:
+       rm -f $(OBJ) *~ core tags lcd
+
+tags:  $(SRC)
+       @echo [ctags]
+       @ctags $(SRC)
+
+depend:
+       makedepend -Y $(SRC)
+
+# DO NOT DELETE
diff --git a/lcd/lcd.c b/lcd/lcd.c
new file mode 100644 (file)
index 0000000..6c2f143
--- /dev/null
+++ b/lcd/lcd.c
@@ -0,0 +1,143 @@
+
+/*
+ * ldc.c:
+ *     Simple test program to drive LCD device
+ *
+ *     Gordon Henderson, gordon@drogon.net
+ */
+
+#include <wiringPi.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+// LCD pins
+
+#define        RS      8
+#define        STRB    9
+
+// commands
+
+#define        LCD_CLEAR       0x01
+#define        LCD_HOME        0x02
+#define        LCD_ENTRY       0x04
+#define        LCD_ON_OFF      0x08
+#define        LCD_CDSHIFT     0x10
+#define        LCD_FUNC        0x20
+#define        LCD_CGRAM       0x40
+#define        LCD_DGRAM       0x80
+
+#define        LCD_ENTRY_SH    0x01
+#define        LCD_ENTRY_ID    0x02
+
+#define        LCD_ON_OFF_B    0x01
+#define        LCD_ON_OFF_C    0x02
+#define        LCD_ON_OFF_D    0x04
+
+#define        LCD_FUNC_F      0x04
+#define        LCD_FUNC_N      0x08
+#define        LCD_FUNC_DL     0x10
+
+#define        LCD_CDSHIFT_RL  0x04
+
+
+void dataByte (uint8_t data)
+{
+  uint8_t i ;
+
+  for (i = 0 ; i < 8 ; ++i)
+  {
+    digitalWrite (i, (data & 1)) ;
+    data >>= 1 ;
+  }
+}
+
+void putCommand (uint8_t command)
+{
+  digitalWrite (RS,   0) ;
+  digitalWrite (STRB, 1) ;
+  dataByte     (command) ;
+  delay (1) ;
+  digitalWrite (STRB, 0) ;
+  delay (1) ;
+}
+
+void lcdPosition (int x, int y)
+{
+  uint8_t l2 = LCD_DGRAM ;
+
+  if (y == 1)
+    l2 |= 0x40 ;
+
+  l2 += x ;
+  putCommand (l2) ;
+}
+
+
+void lcdPutchar (uint8_t data)
+{
+  digitalWrite (RS,   1) ;
+  digitalWrite (STRB, 1) ;
+  dataByte     (data) ;
+  delay (1) ;
+  digitalWrite (STRB, 0) ;
+  delay (1) ;
+}
+
+void lcdPuts (char *string)
+{
+  while (*string)
+    lcdPutchar (*string++) ;
+}
+
+void setup (void)
+{
+  uint8_t i ;
+
+  if (wiringPiSetup () == -1)
+    exit (1) ;
+
+  for (i = 0 ; i < 8 ; ++i)
+  {
+    digitalWrite (i, 0) ;
+    pinMode      (i, OUTPUT) ;
+  }
+
+  digitalWrite (RS, 0) ;
+  pinMode      (RS, OUTPUT) ;
+
+  digitalWrite (STRB, 1) ;
+  pinMode      (STRB, OUTPUT) ;
+
+  delay (35) ; // mS
+  putCommand (LCD_FUNC | LCD_FUNC_DL | LCD_FUNC_N) ;
+  delay (5) ;
+  putCommand (LCD_FUNC | LCD_FUNC_DL | LCD_FUNC_N) ;
+  delay (5) ;
+  putCommand (LCD_FUNC | LCD_FUNC_DL | LCD_FUNC_N) ;
+  delay (5) ;
+
+  putCommand (LCD_ON_OFF | LCD_ON_OFF_D) ;
+  delay (2) ;
+  putCommand (LCD_ENTRY | LCD_ENTRY_ID) ;
+  delay (2) ;
+  putCommand (LCD_CDSHIFT | LCD_CDSHIFT_RL) ;
+  delay (2) ;
+  putCommand (LCD_CLEAR) ;
+  delay (5) ;
+}
+
+int main (void)
+{
+  printf ("Raspberry Pi LCD test program\n") ;
+
+  setup () ;
+
+  lcdPosition (0, 0) ; lcdPuts ("http://projects.") ;
+  delay (5) ;
+  lcdPosition (0, 1) ; lcdPuts ("  drogon.net/") ;
+  delay (5) ;
+
+  return 0 ;
+}
diff --git a/tuxx/Makefile b/tuxx/Makefile
new file mode 100644 (file)
index 0000000..c5082b4
--- /dev/null
@@ -0,0 +1,62 @@
+#
+# Makefile:
+#      wiringPi - Wiring Compatable library for the Raspberry Pi
+#      https://projects.drogon.net/wiring-pi
+#
+#      Copyright (c) 2012 Gordon Henderson
+#################################################################################
+# This file is part of wiringPi:
+#      Wiring Compatable library for the Raspberry Pi
+#
+#    wiringPi is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    wiringPi is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+#################################################################################
+
+
+#DEBUG = -g -O0
+DEBUG  = -O3
+CC     = gcc
+INCLUDE        = -I/usr/local/include
+CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
+
+LDFLAGS        = -L/usr/local/lib
+LIBS    = -lwiringPi
+
+# Should not alter anything below this line
+###############################################################################
+
+SRC    =       tuxx.c
+
+OBJ    =       tuxx.o
+
+all:           tuxx
+
+tuxx:  tuxx.o
+       @echo [link]
+       $(CC) -o $@ tuxx.o $(LDFLAGS) $(LIBS)
+       
+.c.o:
+       @echo [CC] $<
+       @$(CC) -c $(CFLAGS) $< -o $@
+
+clean:
+       rm -f $(OBJ) *~ core tags tuxx
+
+tags:  $(SRC)
+       @echo [ctags]
+       @ctags $(SRC)
+
+depend:
+       makedepend -Y $(SRC)
+
+# DO NOT DELETE
diff --git a/tuxx/tuxx.c b/tuxx/tuxx.c
new file mode 100644 (file)
index 0000000..2a0d59c
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * tuxx.c:
+ *
+ *     Tux Crossing. A variant on the UK "Pelican" crossing for
+ *     pedestrians going over roads.
+ *
+ *     There is a set of Red, Yellow (sometimes called amber) and
+ *     Green traffic lights to control the traffic, and a "Red Man"
+ *     and "Green Man" indicators for pedestrians, and a button for
+ *     them to push.
+ *     Push the button and the lights cycle to Red, then the Green Man
+ *     comes on (often with a beeping sound), then afte a short while
+ *     the Green man starts to flash, meaning to not start crossing,
+ *     and the Yellow traffic light flashes too - meaning that if the
+ *     crossing is clear, traffic can pass... Then after a few more seconds
+ *     the flashing stops and it revers to Go for traffic and Stop for
+ *     pedestrians.
+ *
+ *     Gordon Henderson, June 2012
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <wiringPi.h>
+
+// Our lamps:
+//     (These are wiringPi pin numbers)
+
+#define        RED             0
+#define        YELLOW          1
+#define        GREEN           2
+#define        RED_MAN         3
+#define        GREEN_MAN       4
+
+// The input button
+
+#define        BUTTON          8
+
+
+/*
+ * setup:
+ *     Program the GPIO correctly and initialise the lamps
+ ***********************************************************************
+ */
+
+void setup (void)
+{
+  int i ;
+
+  if (geteuid () != 0)
+  {
+    fprintf (stderr, "tuxx: Need to be root to run (sudo?)\n") ;
+    exit (0) ;
+  }
+
+  if (wiringPiSetup () == -1)
+    exit (1) ;
+
+  printf ("Setup ... ") ; fflush (stdout) ;
+  for (i = 0 ; i < 5 ; ++i)
+  {
+    pinMode (i, OUTPUT) ;
+    digitalWrite (i, 0) ;
+  }
+  digitalWrite (GREEN, 1) ;
+  digitalWrite (RED_MAN, 1) ;
+  pinMode (BUTTON, INPUT) ;
+
+  printf ("OK\n") ;
+}
+
+/*
+ * waitButton:
+ *     Wait for the button to be pressed. Because we have the GPIO
+ *     pin pulled high, we wait for it to go low to indicate a push.
+ ***********************************************************************
+ */
+
+void waitButton (void)
+{
+  printf ("Waiting for button ... ") ; fflush (stdout) ;
+  while (digitalRead (BUTTON) == HIGH)
+    delay (100) ;
+  printf ("Got it\n") ;
+}
+
+/*
+ * stopTraffic:
+ *     Cycle the traffic lights from Green to Red
+ ***********************************************************************
+ */
+
+void stopTraffic ()
+{
+  printf ("Stopping traffic ... ") ; fflush (stdout) ;
+  digitalWrite (GREEN,  0) ;
+  digitalWrite (YELLOW, 1) ;
+  delay (2000) ;
+  digitalWrite (YELLOW, 0) ;
+  digitalWrite (RED,    1) ;
+  delay (2000) ;
+  printf ("Stopped\n") ;
+}
+
+/*
+ * walk:
+ *     Signal the red/green man to walk and when time is up,
+ *     start the traffic light sequence to let the traffic move again
+ ***********************************************************************
+ */
+
+void walk ()
+{
+  printf ("Walk now ... ") ; fflush (stdout) ;
+
+  digitalWrite (RED_MAN,   0) ;
+  digitalWrite (GREEN_MAN, 1) ;
+  delay (10000) ;
+  digitalWrite (RED,    0) ;
+  digitalWrite (YELLOW, 1) ;
+
+  printf ("Walked\n") ;
+}
+
+/*
+ * graceTime:
+ *     This is the time when the green man is flashing, and the yellow
+ *     traffic light is also flashing - to signal to pedestrians to not
+ *     start to cross and to drivers that they can move on if the 
+ *     crossing is clear.
+ ***********************************************************************
+ */
+
+void graceTime ()
+{
+  int i ;
+
+  printf ("Grace time ... ") ; fflush (stdout) ;
+
+  for (i = 0 ; i < 8 ; ++i)
+  {
+    delay (500) ;
+    digitalWrite (GREEN_MAN, 0) ;
+    digitalWrite (YELLOW,    0) ;
+    delay (500) ;
+    digitalWrite (GREEN_MAN, 1) ;
+    digitalWrite (YELLOW,    1) ;
+  }
+  printf ("time up!\n") ;
+}
+
+/*
+ * startTraffic:
+ *     Back to the Red Man and Green traffic light
+ ***********************************************************************
+ */
+
+void startTraffic ()
+{
+  printf ("Starting traffic ... ") ; fflush (stdout) ;
+
+  digitalWrite (GREEN_MAN, 0) ;
+  digitalWrite (RED_MAN,   1) ;
+  delay (500) ;
+  digitalWrite (YELLOW, 0) ;
+  digitalWrite (GREEN,  1) ;
+
+  printf ("Going\n") ;
+}
+
+
+/*
+ ***********************************************************************
+ * The main program
+ *     Call our setup routing once, then sit in a loop, waiting for
+ *     the button to be pressed then executing the sequence.
+ ***********************************************************************
+ */
+
+int main (void)
+{
+  setup () ;
+  for (;;)
+  {
+    waitButton   () ;
+    stopTraffic  () ;
+    walk         () ;
+    graceTime    () ;
+    startTraffic () ;
+  }
+}
diff --git a/tuxx/tuxx.sh b/tuxx/tuxx.sh
new file mode 100755 (executable)
index 0000000..aa9b236
--- /dev/null
@@ -0,0 +1,145 @@
+#!/bin/bash
+
+# tuxx:
+#      Tux Crossing. A variant on the UK "Pelican" crossing for
+#      pedestrians going over roads.
+#
+#      There is a set of Red, Yellow (sometimes called amber) and
+#      Green traffic lights to control the traffic, and a "Red Man"
+#      and "Green Man" indicators for pedestrians, and a button for
+#      them to push.
+#      Push the button and the lights cycle to Red, then the Green Man
+#      comes on (often with a beeping sound), then afte a short while
+#      the Green man starts to flash, meaning to not start crossing,
+#      and the Yellow traffic light flashes too - meaning that if the
+#      crossing is clear, traffic can pass... Then after a few more seconds
+#      the flashing stops and it revers to Go for traffic and Stop for
+#      pedestrians.
+#
+#      Gordon Henderson, June 2012
+
+# Our lamps:
+#      (These are wiringPi pin numbers)
+
+     red=0
+  yellow=1
+   green=2
+  redMan=3
+greenMan=4
+
+# The input button
+
+button=8
+
+
+# setup:
+#      Program the GPIO correctly and initialise the lamps
+#######################################################################
+
+setup ()
+{
+  echo Setup
+  for i in $red $yellow $green $redMan $greenMan ; do gpio mode  $i out ; done
+  for i in $red $yellow $green $redMan $greenMan ; do gpio write $i   0 ; done
+  gpio write $green  1
+  gpio write $redMan 1
+  gpio mode  $button in
+}
+
+# waitButton:
+#      Wait for the button to be pressed. Because we have the GPIO
+#      pin pulled high, we wait for it to go low to indicate a push.
+#######################################################################
+
+waitButton ()
+{
+  echo -n "Waiting for button ... "
+  while [ `gpio read $button` = 1 ]; do
+    sleep 0.1
+  done
+  echo "Got it"
+}
+
+# stopTraffic:
+#      Cycle the traffic lights from Green to Red
+#######################################################################
+
+stopTraffic ()
+{
+  echo -n "Stopping traffic ... "
+  gpio write $green  0
+  gpio write $yellow 1
+  sleep 2
+  gpio write $yellow 0
+  gpio write $red    1
+  sleep 2
+  echo "Stopped"
+}
+
+# walk:
+#      Signal the red/green man to walk and when time is up,
+#      start the traffic light sequence to let the traffic move again
+#######################################################################
+
+walk ()
+{
+  echo "Walk now ... "
+  gpio write $redMan   0
+  gpio write $greenMan 1
+  sleep 10
+  gpio write $red    0
+  gpio write $yellow 1
+  echo "Walked"
+}
+
+# graceTime:
+#      This is the time when the green man is flashing, and the yellow
+#      traffic light is also flashing - to signal to pedestrians to not
+#      start to cross and to drivers that they can move on if the 
+#      crossing is clear.
+#######################################################################
+
+graceTime ()
+{
+  echo "Grace time ... "
+  for i in `seq 0 7` ; do
+    sleep 0.5
+    gpio write $greenMan 0
+    gpio write $yellow   0
+    sleep 0.5
+    gpio write $greenMan 1
+    gpio write $yellow   1
+  done
+  echo "time up!"
+}
+
+# startTraffic:
+#      Back to the Red Man and Green traffic light
+#######################################################################
+
+startTraffic ()
+{
+  echo "Starting traffic ... "
+  gpio write $greenMan 0
+  gpio write $redMan   1
+  sleep 0.5
+  gpio write $yellow 0
+  gpio write $green  1
+  echo "Going"
+}
+
+
+#######################################################################
+# The main program
+#      Call our setup routing once, then sit in a loop, waiting for
+#      the button to be pressed then executing the sequence.
+#######################################################################
+
+setup
+while true; do
+  waitButton
+  stopTraffic
+  walk
+  graceTime
+  startTraffic
+done