Gordons Projects

--> Projects Top-Level GIT

Initial GIT submission
authorGordon Henderson <projects@drogon.net>
Mon, 3 Mar 2014 12:16:09 +0000 (12:16 +0000)
committerGordon Henderson <projects@drogon.net>
Mon, 3 Mar 2014 12:16:09 +0000 (12:16 +0000)
Makefile [new file with mode: 0644]
ladder.c [new file with mode: 0755]
pibrella.h [new file with mode: 0644]
pwmTones [new file with mode: 0755]
pwmTones.c [new file with mode: 0644]
step1.c [new file with mode: 0755]
stepper.c [new file with mode: 0755]
tune.c [new file with mode: 0644]
tuxx.sh [new file with mode: 0755]
wire.c [new file with mode: 0755]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..89f5359
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,66 @@
+#
+# Makefile:
+#      For the Pibrella code
+#      Copyright (c) 2014 Gordon Henderson
+###############################################################################
+
+#DEBUG = -g -O0
+DEBUG  = -O2
+CC     = gcc
+CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe
+
+LIBS    = -lwiringPi -lm
+
+SRC    =       tune.c ladder.c stepper.c step1.c wire.c
+
+# May not need to  alter anything below this line
+###############################################################################
+
+OBJ    =       $(SRC:.c=.o)
+
+all:           tune ladder stepper step1 wire
+
+tune:  tune.o
+       @echo [Link]
+       @$(CC) -o $@ tune.o $(LDFLAGS) $(LIBS)
+
+ladder:        ladder.o
+       @echo [Link]
+       @$(CC) -o $@ ladder.o $(LDFLAGS) $(LIBS)
+
+stepper:       stepper.o
+       @echo [Link]
+       @$(CC) -o $@ stepper.o $(LDFLAGS) $(LIBS)
+
+step1: step1.o
+       @echo [Link]
+       @$(CC) -o $@ step1.o $(LDFLAGS) $(LIBS)
+
+wire:  wire.o
+       @echo [Link]
+       @$(CC) -o $@ wire.o $(LDFLAGS) $(LIBS)
+
+.c.o:
+       @echo [Compile] $<
+       @$(CC) -c $(CFLAGS) $< -o $@
+
+.PHONEY:       clean
+clean:
+       rm -f $(OBJ) wire tune ladder stepper step1 *~ core tags *.bak
+
+.PHONEY:       tags
+tags:  $(SRC)
+       @echo [ctags]
+       @ctags $(SRC)
+
+.PHONEY:       depend
+depend:
+       makedepend -Y $(SRC)
+
+# DO NOT DELETE
+
+tune.o: pibrella.h
+ladder.o: pibrella.h
+stepper.o: pibrella.h
+step1.o: pibrella.h
+wire.o: pibrella.h
diff --git a/ladder.c b/ladder.c
new file mode 100755 (executable)
index 0000000..f01b498
--- /dev/null
+++ b/ladder.c
@@ -0,0 +1,343 @@
+/*
+ * ladder.c:
+ *     Copyright (c) Gordon Henderson, June 2012-2014
+ ***********************************************************************
+ *    This is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as published by
+ *    the Free Software Foundation, either version 3 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This 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 Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public License
+ *    along with This.  If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+
+#include <wiringPi.h>
+
+#include "pibrella.h"
+
+#ifndef        TRUE
+#  define      TRUE    (1==1)
+#  define      FALSE   (1==2)
+#endif
+
+#undef DEBUG
+
+#define        NUM_LEDS         7
+
+
+// Map the LEDs to the hardware pins
+
+const int ledMap [NUM_LEDS] =
+{
+  PIBRELLA_OUT_3,
+  PIBRELLA_OUT_2,
+  PIBRELLA_OUT_1,
+  PIBRELLA_OUT_0,
+  PIBRELLA_GREEN,
+  PIBRELLA_YELLOW,
+  PIBRELLA_RED,
+} ;
+
+
+// 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)
+{
+  wiringPiSetup () ;
+  pibrellaSetup () ;
+
+// 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 (PIBRELLA_BUTTON) == HIGH)
+  {
+    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 (PIBRELLA_BUTTON) == HIGH)
+  {
+    vCap = vCapLast = 0.0 ;
+    ledBargraph (vCap, FALSE) ;
+
+// Wait until we release the button
+
+    while (digitalRead (PIBRELLA_BUTTON) == HIGH)
+      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 (PIBRELLA_BUTTON) == LOW)
+       delay (10) ;
+      while (digitalRead (PIBRELLA_BUTTON) == HIGH)
+       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/pibrella.h b/pibrella.h
new file mode 100644 (file)
index 0000000..529a446
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * pibrella.h:
+ *     wiringPi pin definitions for the Pibrella board
+ *
+ * Copyright (c) 2014 Gordon Henderson. <projects@drogon.net>
+ ***********************************************************************
+ * This file is part of wiringPi:
+ *      https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ *    wiringPi is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public License
+ *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+// The 3 big LEDs
+
+#define        PIBRELLA_RED             2
+#define        PIBRELLA_YELLOW          0
+#define        PIBRELLA_GREEN           7
+
+// The big red button
+
+#define        PIBRELLA_BUTTON         14
+
+// PWM/Tone output
+
+#define        PIBRELLA_SQUAWK          1
+
+// The 4 inputs:
+
+#define        PIBRELLA_IN_0           13
+#define        PIBRELLA_IN_1           11
+#define        PIBRELLA_IN_2           10
+#define        PIBRELLA_IN_3           12
+
+// The 4 outputs:
+
+#define        PIBRELLA_OUT_0           3
+#define        PIBRELLA_OUT_1           4
+#define        PIBRELLA_OUT_2           5
+#define        PIBRELLA_OUT_3           6
+
+// Same, using the Pibrella board labels:
+
+#define        PIBRELLA_IN_A           13
+#define        PIBRELLA_IN_B           11
+#define        PIBRELLA_IN_C           10
+#define        PIBRELLA_IN_D           12
+
+#define        PIBRELLA_OUT_E           3
+#define        PIBRELLA_OUT_F           4
+#define        PIBRELLA_OUT_G           5
+#define        PIBRELLA_OUT_H           6
+
+
+/*
+ * playTone:
+ *     Output the given frequency on the Pi's PWM pin
+ *********************************************************************************
+ */
+
+static void playTone (int freq)
+{
+  int range ;
+
+  if (freq == 0)
+    pwmWrite (PIBRELLA_SQUAWK, 0) ;            // Off
+  else
+  {
+    range = 600000 / freq ;
+    pwmSetRange (range) ;
+    pwmWrite    (PIBRELLA_SQUAWK, freq / 2) ;
+  }
+}
+
+
+/*
+ * pibrellaSetup:
+ *     Initialise the Pi's GPIO for the Pibrella board
+ *********************************************************************************
+ */
+
+void pibrellaSetup (void)
+{
+  pinMode (PIBRELLA_RED,       OUTPUT) ;
+  pinMode (PIBRELLA_YELLOW,    OUTPUT) ;
+  pinMode (PIBRELLA_GREEN,     OUTPUT) ;
+
+  pinMode (PIBRELLA_BUTTON,    INPUT) ;
+
+  pinMode (PIBRELLA_IN_0,      INPUT) ;
+  pinMode (PIBRELLA_IN_1,      INPUT) ;
+  pinMode (PIBRELLA_IN_2,      INPUT) ;
+  pinMode (PIBRELLA_IN_3,      INPUT) ;
+
+  pinMode (PIBRELLA_OUT_0,     OUTPUT) ;
+  pinMode (PIBRELLA_OUT_1,     OUTPUT) ;
+  pinMode (PIBRELLA_OUT_2,     OUTPUT) ;
+  pinMode (PIBRELLA_OUT_3,     OUTPUT) ;
+
+  digitalWrite (PIBRELLA_RED,    0) ;
+  digitalWrite (PIBRELLA_YELLOW, 0) ;
+  digitalWrite (PIBRELLA_GREEN,  0) ;
+
+  digitalWrite (PIBRELLA_OUT_0,  0) ;
+  digitalWrite (PIBRELLA_OUT_1,  0) ;
+  digitalWrite (PIBRELLA_OUT_2,  0) ;
+  digitalWrite (PIBRELLA_OUT_3,  0) ;
+
+  pullUpDnControl (PIBRELLA_BUTTON, PUD_DOWN) ;
+  pullUpDnControl (PIBRELLA_IN_0,   PUD_DOWN) ;
+  pullUpDnControl (PIBRELLA_IN_1,   PUD_DOWN) ;
+  pullUpDnControl (PIBRELLA_IN_2,   PUD_DOWN) ;
+  pullUpDnControl (PIBRELLA_IN_3,   PUD_DOWN) ;
+
+// Setup the PWM output to make the buzzer play tones
+
+  pinMode    (PIBRELLA_SQUAWK, PWM_OUTPUT) ;
+  pwmSetMode (PWM_MODE_MS) ;
+  playTone   (0) ;
+}
+
+
diff --git a/pwmTones b/pwmTones
new file mode 100755 (executable)
index 0000000..59b7af6
Binary files /dev/null and b/pwmTones differ
diff --git a/pwmTones.c b/pwmTones.c
new file mode 100644 (file)
index 0000000..3b4e999
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * pwmTones.c:
+ *      Demonstration of using the PWM generator on the Raspberry Pi
+ *     to play simple tunes.
+ *
+ * Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
+ ***********************************************************************
+ * This file is part of wiringPi:
+ *      https://projects.drogon.net/raspberry-pi/wiringpi/
+ *
+ *    wiringPi is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public License
+ *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <math.h>
+
+#include <wiringPi.h>
+
+// Beats per minute
+
+#define        TEMPO   120
+#define        MS_PER_BEAT     ((1000*60/TEMPO)/4)
+
+// Simple scale frequencies
+
+static const int scale [8] = { 262, 294, 330, 349, 392, 440, 494, 525 } ;
+
+// Calculated PWM Range values
+
+static int pwmR [8] ;
+
+// Our tune: Note followed by duration in quarter crotchets
+
+const int tune [] = 
+{
+  0,6, 1,2, 2,6, 0,2,          // Doe, a deer, a
+   2,4, 0,4, 2,8,              //   fe - male deer,
+  1,6, 2,2, 3,2, 3,2, 2,2, 1,2,        // ray, a drop of gold-en
+   3,14, -1,2,                 //   sun.
+  2,6, 3,2, 4,6, 2,2,          // Me, a name I
+   4,4, 2,4, 4,8,              //   call my - self
+  3,6, 4,2, 5,2, 5,2, 4,2, 3,2,        // Far, a long, long way to
+    5, 16,                     //  run.
+  4,6, 0,2, 1,2, 2,2, 3,2, 4,2,        // Sew, a nee - dle pull - ing
+    5,14, -1,2,                        // thread
+  5,6, 1,2, 2,2, 3,2, 4,2, 5,2,        // La, a note to fol - low
+   6,14, -1,2,                 //  so.
+  6,6, 2,2, 3,2, 4,2, 5,2, 6,2,        // Tea, a drink with jam and
+   7,12, -1,4,                 //  bread
+  6,2, 6,2, 5,4, 4,4, 6,4, 4,4,        // that will bring us back to
+  7,4, 4,4, 2,4, 1,4,          // do, oh, oh, oh!
+  
+  
+  -1, 16, -1, -1
+} ;
+
+static void revokeRoot (void)
+{
+  if (getuid () + geteuid () == 0)      // Really running as root
+    return ;
+
+  if (geteuid () == 0)                  // Running setuid root
+    seteuid (getuid ()) ;               // Change effective uid to the uid of the caller
+}
+
+
+// The works
+
+int main (void)
+{
+  int note, dur ;
+  int i ;
+
+  wiringPiSetup () ;
+  revokeRoot    () ;
+
+// PWM Setup
+
+  pinMode    (1, PWM_OUTPUT) ;
+  pwmSetMode (PWM_MODE_MS) ;
+  pwmWrite   (1, 0) ;          // Off
+
+// Calculate the pwmRange values based on the frequency table:
+
+  for (i = 0 ; i < 8 ; ++i)
+    pwmR [i] = (int)rint ( 600000 / (double)scale [i]) ;
+
+// Print out for reference:
+
+  printf ("Note/PWMR values:\n") ;
+  for (i = 0 ; i < 8 ; ++i)
+    printf ("%2d: %4d -> %4d\n", i, scale [i], pwmR [i]) ;
+
+
+// Play the tune
+
+  for (;;)
+  {
+    for (i = 0 ;; i += 2)
+    {
+      note = tune [i] ;
+      dur  = tune [i + 1] ;
+      if ((note == -1) && (dur == -1))
+       break ;
+
+      if (note == -1)  // Pause
+       printf ("Rest  ") ;
+      else
+      {
+       printf ("Note: %d  ", note) ;
+       pwmSetRange (pwmR [note]) ;
+       pwmWrite    (1, pwmR [note] / 2) ;
+      }
+
+// Delay for the note duration
+
+      printf ("Time: %4d\n", MS_PER_BEAT * dur) ;
+      delay (MS_PER_BEAT * dur - 5) ;
+
+// Stop sound for a few mS between notes
+
+      pwmWrite (1, 0) ;
+      delay (5) ;
+    }
+  }
+
+  return 0 ;
+}
diff --git a/step1.c b/step1.c
new file mode 100755 (executable)
index 0000000..0134e04
--- /dev/null
+++ b/step1.c
@@ -0,0 +1,135 @@
+/*
+ * step1.c:
+ *     Control a micro stepper motor off the Pibrella board
+ *     Single step mode.
+ *     Copyright (c) Gordon Henderson, 2014
+ ***********************************************************************
+ *    This is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as published by
+ *    the Free Software Foundation, either version 3 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This 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 Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public License
+ *    along with This.  If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+
+#include <wiringPi.h>
+
+#include "pibrella.h"
+
+#define        MAX_STEPS       8
+
+static int sequence [] =
+{
+  1, 0, 0, 0,
+  1, 1, 0, 0,
+  0, 1, 0, 0,
+  0, 1, 1, 0,
+  0, 0, 1, 0,
+  0, 0, 1, 1,
+  0, 0, 0, 1,
+  1, 0, 0, 1,
+} ;
+
+static int sequenceStep = 0 ;
+
+
+/*
+ * stepCW: stepACW:
+ *     Step the motor for the given number of steps clockwise or anticlockwise
+ *********************************************************************************
+ */
+
+static void stepCW (int steps)
+{
+  int i ;
+
+  for (i = 0 ; i < steps ; ++i)
+  {
+    sequenceStep -= 4 ;
+    if (sequenceStep < 0)
+      sequenceStep = MAX_STEPS * 4 - 4 ;
+
+    digitalWrite (PIBRELLA_OUT_0, sequence [sequenceStep+0]) ;
+    digitalWrite (PIBRELLA_OUT_1, sequence [sequenceStep+1]) ;
+    digitalWrite (PIBRELLA_OUT_2, sequence [sequenceStep+2]) ;
+    digitalWrite (PIBRELLA_OUT_3, sequence [sequenceStep+3]) ;
+
+    delay (1) ;
+  }
+}
+
+
+static void stepACW (int steps)
+{
+  int i ;
+
+  for (i = 0 ; i < steps ; ++i)
+  {
+    sequenceStep += 4 ;
+    if (sequenceStep >= (MAX_STEPS * 4))
+      sequenceStep = 0 ;
+
+    digitalWrite (PIBRELLA_OUT_0, sequence [sequenceStep+0]) ;
+    digitalWrite (PIBRELLA_OUT_1, sequence [sequenceStep+1]) ;
+    digitalWrite (PIBRELLA_OUT_2, sequence [sequenceStep+2]) ;
+    digitalWrite (PIBRELLA_OUT_3, sequence [sequenceStep+3]) ;
+
+    delay (1) ;
+  }
+}
+
+
+
+/*
+ * main:
+ ***********************************************************************
+ */
+
+int main (void)
+{
+  wiringPiSetup () ;
+  pibrellaSetup () ;
+
+  stepCW (1) ;
+  stepACW (1) ;
+
+  for (;;)
+  {
+
+// Wait for the button
+
+    while (digitalRead (PIBRELLA_BUTTON) == 0)
+      delay (1) ;
+
+// One step
+
+    stepCW (1) ;
+
+// Wait for the button to be released
+
+    for (;;)
+    {
+      while (digitalRead (PIBRELLA_BUTTON) == 1)
+       delay (1) ;
+
+      delay (20) ;     // Delay 20mS to make sure there is no bounce
+
+      if (digitalRead (PIBRELLA_BUTTON) == 0)  // Released
+       break ;
+    }
+  }
+
+  return 0 ;
+}
diff --git a/stepper.c b/stepper.c
new file mode 100755 (executable)
index 0000000..ec45281
--- /dev/null
+++ b/stepper.c
@@ -0,0 +1,113 @@
+/*
+ * stepper.c:
+ *     Controll a micro stepper motor off the Pibrella board
+ *     Copyright (c) Gordon Henderson, 2014
+ ***********************************************************************
+ *    This is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as published by
+ *    the Free Software Foundation, either version 3 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This 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 Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public License
+ *    along with This.  If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+
+#include <wiringPi.h>
+
+#include "pibrella.h"
+
+#define        MAX_STEPS       8
+
+static int sequence [] =
+{
+  1, 0, 0, 0,
+  1, 1, 0, 0,
+  0, 1, 0, 0,
+  0, 1, 1, 0,
+  0, 0, 1, 0,
+  0, 0, 1, 1,
+  0, 0, 0, 1,
+  1, 0, 0, 1,
+} ;
+
+static int sequenceStep = 0 ;
+
+
+/*
+ * stepCW: stepACW:
+ *     Step the motor for the given number of steps clockwise or anticlockwise
+ *********************************************************************************
+ */
+
+static void stepCW (int steps)
+{
+  int i ;
+
+  for (i = 0 ; i < steps ; ++i)
+  {
+    sequenceStep -= 4 ;
+    if (sequenceStep < 0)
+      sequenceStep = MAX_STEPS * 4 - 4 ;
+
+    digitalWrite (PIBRELLA_OUT_0, sequence [sequenceStep+0]) ;
+    digitalWrite (PIBRELLA_OUT_1, sequence [sequenceStep+1]) ;
+    digitalWrite (PIBRELLA_OUT_2, sequence [sequenceStep+2]) ;
+    digitalWrite (PIBRELLA_OUT_3, sequence [sequenceStep+3]) ;
+
+    delay (1) ;
+  }
+}
+
+
+static void stepACW (int steps)
+{
+  int i ;
+
+  for (i = 0 ; i < steps ; ++i)
+  {
+    sequenceStep += 4 ;
+    if (sequenceStep >= (MAX_STEPS * 4))
+      sequenceStep = 0 ;
+
+    digitalWrite (PIBRELLA_OUT_0, sequence [sequenceStep+0]) ;
+    digitalWrite (PIBRELLA_OUT_1, sequence [sequenceStep+1]) ;
+    digitalWrite (PIBRELLA_OUT_2, sequence [sequenceStep+2]) ;
+    digitalWrite (PIBRELLA_OUT_3, sequence [sequenceStep+3]) ;
+
+    delay (1) ;
+  }
+}
+
+
+
+/*
+ * main:
+ ***********************************************************************
+ */
+
+int main (void)
+{
+  wiringPiSetup () ;
+  pibrellaSetup () ;
+
+  for (;;)
+  {
+    stepCW (4096) ;
+    delay (100) ; 
+    stepACW (4096) ;
+    delay (100) ; 
+  }
+
+  return 0 ;
+}
diff --git a/tune.c b/tune.c
new file mode 100644 (file)
index 0000000..9ea8990
--- /dev/null
+++ b/tune.c
@@ -0,0 +1,108 @@
+/*
+ * tune.c:
+ *     Play a tune using the Pibrella buzzer
+ *
+ * Copyright (c) 2014 Gordon Henderson. <projects@drogon.net>
+ ***********************************************************************
+ *    This is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as published by
+ *    the Free Software Foundation, either version 3 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This 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 Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public License
+ *    along with This.  If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <math.h>
+
+#include <wiringPi.h>
+
+#include "pibrella.h"
+
+// Beats per minute
+
+#define        TEMPO   120
+#define        MS_PER_BEAT     ((1000*60/TEMPO)/4)
+
+// Simple scale frequencies
+
+static const int scale [8] = { 262, 294, 330, 349, 392, 440, 494, 525 } ;
+
+// Our tune: Note followed by duration in quarter crotchets
+
+const int tune [] = 
+{
+  0,6, 1,2, 2,6, 0,2,          // Doe, a deer, a
+   2,4, 0,4, 2,8,              //   fe - male deer,
+  1,6, 2,2, 3,2, 3,2, 2,2, 1,2,        // ray, a drop of gold-en
+   3,14, -1,2,                 //   sun.
+  2,6, 3,2, 4,6, 2,2,          // Me, a name I
+   4,4, 2,4, 4,8,              //   call my - self
+  3,6, 4,2, 5,2, 5,2, 4,2, 3,2,        // Far, a long, long way to
+    5, 16,                     //  run.
+  4,6, 0,2, 1,2, 2,2, 3,2, 4,2,        // Sew, a nee - dle pull - ing
+    5,14, -1,2,                        // thread
+  5,6, 1,2, 2,2, 3,2, 4,2, 5,2,        // La, a note to fol - low
+   6,14, -1,2,                 //  so.
+  6,6, 2,2, 3,2, 4,2, 5,2, 6,2,        // Tea, a drink with jam and
+   7,12, -1,4,                 //  bread
+  6,2, 6,2, 5,4, 4,4, 6,4, 4,4,        // that will bring us back to
+  7,4, 4,4, 2,4, 1,4,          // do, oh, oh, oh!
+  
+  -1, 16, -1, -1
+} ;
+
+
+/*
+ * main:
+ *********************************************************************************
+ */
+
+int main (void)
+{
+  int note, dur ;
+  int i ;
+
+  wiringPiSetup () ;
+  pibrellaSetup () ;
+
+// Play the tune
+
+  for (i = 0 ;; i += 2)
+  {
+    note = tune [i] ;
+    dur  = tune [i + 1] ;
+    if ((note == -1) && (dur == -1))
+      break ;
+
+    if (note == -1)    // Pause
+      printf ("Rest  ") ;
+    else
+    {
+      printf ("Note: %d  ", note) ;
+      playTone (scale [note]) ;
+    }
+
+// Delay for the note duration
+
+    printf ("Time: %4d\n", MS_PER_BEAT * dur) ;
+    delay (MS_PER_BEAT * dur - 5) ;
+
+// Stop sound for a few mS between notes
+
+    playTone (0) ;
+    delay    (5) ;
+  }
+
+  return 0 ;
+}
diff --git a/tuxx.sh b/tuxx.sh
new file mode 100755 (executable)
index 0000000..ef39e12
--- /dev/null
+++ b/tuxx.sh
@@ -0,0 +1,173 @@
+#!/bin/bash
+
+# tuxx:
+#      Tux Crossing. A variant on the UK "Pelican" crossing for
+#      pedestrians going over roads.
+#
+#      This version designed to be used with the Pibrella board.
+#
+#      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 (Updated 2014 for the Pibrella)
+
+red=2
+yellow=0
+green=7
+
+button=14
+
+# No separate red/green men - we'll use the secondary outputs which are
+#      white, but they'll have to do.
+
+redMan=3       # Top one
+greenMan=6     # Bottom one
+
+# tuxxSetup:
+#      Initialise the LEDs for the crossing
+#######################################################################
+
+tuxxSetup ()
+{
+  for led in $red yellow $green $greenMan $redMan
+  do
+    gpio mode $led out
+    gpio write $led 0
+  done
+
+  gpio mode $button in
+  gpio mode $button down       # Enable pull-down
+
+  gpio write $green    1
+  gpio write $redMan   1
+  gpio write $greenMan 0
+  gpio mode  1 pwm
+  gpio pwm-ms
+}
+
+
+# waitButton:
+#      Wait for the button to be pressed. 
+#######################################################################
+
+waitButton ()
+{
+  echo -n "Waiting for button ... "
+  while [ `gpio read $button` = 0 ]; 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"
+}
+
+# peep:
+#      Output a brief "peep" on the buzzer
+#######################################################################
+
+peep ()
+{
+  gpio pwmr 600
+  gpio pwm  1 300      # 1000Hz
+  sleep 0.1
+  gpio pwm  1 0
+  sleep 0.1
+}
+
+
+# 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
+  for i in `seq 10 -1 0`; do
+    echo -n $i " "
+    for j in 0 1; do
+      peep
+    done
+  done
+  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 routines once, then sit in a loop, waiting for
+#      the button to be pressed then executing the sequence.
+#######################################################################
+
+tuxxSetup
+
+while true; do
+  waitButton
+  stopTraffic
+  walk
+  graceTime
+  startTraffic
+done
diff --git a/wire.c b/wire.c
new file mode 100755 (executable)
index 0000000..972210c
--- /dev/null
+++ b/wire.c
@@ -0,0 +1,146 @@
+/*
+ * wire.c:
+ *     Guide a loop along a wire without touching it.
+ *     Copyright (c) Gordon Henderson, 2014
+ ***********************************************************************
+ *    This is free software: you can redistribute it and/or modify
+ *    it under the terms of the GNU Lesser General Public License as published by
+ *    the Free Software Foundation, either version 3 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This 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 Lesser General Public License for more details.
+ *
+ *    You should have received a copy of the GNU Lesser General Public License
+ *    along with This.  If not, see <http://www.gnu.org/licenses/>.
+ ***********************************************************************
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <math.h>
+
+#include <wiringPi.h>
+
+#include "pibrella.h"
+
+
+static void debounce (int pin)
+{
+  for (;;)
+  {
+    while (digitalRead (pin) == 1)
+      delay (1) ;
+
+    delay (20) ;
+
+    if (digitalRead (pin) == 0)        // Clear
+      break ;
+  }
+}
+
+/*
+ * main:
+ ***********************************************************************
+ */
+
+int main (void)
+{
+  int touches ;
+
+  wiringPiSetup () ;
+  pibrellaSetup () ;
+
+// We start with all LEDs off and ready to go. The button on the Pibrella
+//     acts as the reset button
+
+  for (;;)
+  {
+    touches = 0 ;
+    digitalWrite (PIBRELLA_GREEN,  0) ;
+    digitalWrite (PIBRELLA_YELLOW, 0) ;
+    digitalWrite (PIBRELLA_RED,    0) ;
+    playTone (0) ;
+
+// Wait for the wire to be clear
+
+    printf ("Waiting for the wire to be clear...\n") ;
+
+    if (digitalRead (PIBRELLA_IN_A) == 1)
+    {
+      digitalWrite (PIBRELLA_RED, 1) ;
+      debounce (PIBRELLA_IN_A) ;
+    }
+    digitalWrite (PIBRELLA_RED, 0) ;
+
+// OK. Ready to roll
+
+    printf ("OK. Ready to play!\n") ;
+
+    for (;;)
+    {
+      if (digitalRead (PIBRELLA_BUTTON) == 1)  // Big Red Reset Button
+       break ;
+
+      if (digitalRead (PIBRELLA_IN_A) == 1)    // Touched
+      {
+       ++touches ;
+       printf ("Touched! Touch number: %d\n", touches) ;
+
+       playTone (1000) ;
+
+       if (touches == 1)
+         digitalWrite (PIBRELLA_GREEN, 1) ;    //      First life gone
+
+       if (touches == 2)
+         digitalWrite (PIBRELLA_YELLOW, 1) ;   //      Second life gone
+
+       if (touches == 3)
+         digitalWrite (PIBRELLA_RED, 1) ;      //      Third life gone
+
+       if (touches == 4)
+       {
+         delay (100) ;
+         playTone (250) ;
+         break ;
+       }
+
+       delay (100) ;
+       playTone (0) ;
+
+       debounce (PIBRELLA_IN_A) ;
+      }
+    }
+
+// Broken out - game over or we've hit the reset button
+
+    if (digitalRead (PIBRELLA_BUTTON) == 1)    // Big Red Reset Button
+    {
+      playTone (0) ;
+      debounce (PIBRELLA_BUTTON) ;
+      continue ;
+    }
+
+// Game over
+
+    for (;;)
+    {
+      playTone (1000) ;
+      delay (100) ;
+      if (digitalRead (PIBRELLA_BUTTON) == 1)  // Big Red Reset Button
+       break ;
+
+      playTone (500) ;
+      delay (100) ;
+      if (digitalRead (PIBRELLA_BUTTON) == 1)  // Big Red Reset Button
+       break ;
+    }
+
+    playTone (0) ;
+  }
+
+  return 0 ;
+}