Introduction: The Final Curtain - the Shower Timer

I needed a timer for the bath with a nice big screen you can see during the shower, hence The Final Curtain

Step 1: Parts List

Arduino pro mini
Potentiometer
Momentary Push Button
220 ohm Resistor
On/Off switch
Battery Case an batteries
Copper tape
some wires
Dual (8 digits) max7291 7-segment display
Piezo buzzer

Step 2: Diagram

Most of it you can understand from the diagram,
I'm using two stripes of copper tape one for ground the other 5v.
Each component is soldered to them as needed.
just remember to send it a bit with a flat screw to pill it's lamination.

Step 3: Push Button

The push button is connented to 5v at the first pin and to both the arduino digital 4 pin and through a 220ohm resistor to ground (pull down) at the second pin.

Step 4: Potentiometer

pin 1 is connected to 5v
pin 2 is connected to arduino analog pin 0
pin 3 is connected to ground

Step 5: Piezzo Buzzer

Long pin (positive) is connected to arduino PWM 3 (digital 3)
Short pin is connected to ground

Step 6: Dual (8 Digits) Max7291 7-segment Display

DIN connected to arduino pin 5
CS connected to arduino pin 6
CLK connected to arduino pin 7

VCC connected to 5v
GND is connected to ground

Step 7: ON / OFF Switch

pin 1 connected to battery case's Red wire
pin 2 connected to arduino RAW
pin 3 is not connected.

The second black / blue wire of the battery case is connected to arduino GND

Step 8: THE CODE

#define MAX7219_DIN 5
#define MAX7219_CS  6
#define MAX7219_CLK 7
#define Bot 4
#define BZzz 3
#define Pot 0
boolean runMode = false;
long runTime = 0;
void initialise()
{
  digitalWrite(MAX7219_CS, HIGH);
  pinMode(MAX7219_DIN, OUTPUT);
  pinMode(MAX7219_CS, OUTPUT);
  pinMode(MAX7219_CLK, OUTPUT);
}
void output(byte address, byte data)
{
  digitalWrite(MAX7219_CS, LOW);
  shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, address);
  shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, data);
  digitalWrite(MAX7219_CS, HIGH);
}
void setup() {
  Serial.begin (9600);
  pinMode (Bot, INPUT);
  pinMode (BZzz, OUTPUT);
  // put your setup code here, to run once:
  initialise();
  output(0x0f, 0x00); //display test register - test mode off
  output(0x0c, 0x01); //shutdown register - normal operation
  output(0x0b, 0x07); //scan limit register - display digits 0 thru 7
  output(0x0a, 0x0f); //intensity register - max brightness
  output(0x09, 0xff); //decode mode register - CodeB decode all digits
  output(0x08, 15); //digit 7 (leftmost digit) data
  output(0x07, 15);
  output(0x06, 15);
  output(0x05, 15);
  output(0x04, 15);
  output(0x03, 15);
  output(0x02, 15);
  output(0x01, 15); //digit 0 (rightmost digit) data
}
void loop() {
  if (!runMode){
    runTime = analogRead (Pot);
    runTime = map (runTime, 5, 1020, 1, 12) * 5;
    Serial.println (runTime);
    output(0x05, runTime % 10);
    output(0x06, runTime / 10);
    if (digitalRead (Bot)) {
      delay (20);
      runTime = runTime * 60000 + millis();
      tone (BZzz, 1000);
      delay (300);
      noTone (BZzz);
      runMode = true;
    } 
   if (runMode) {
      int Bip = true;
      while (millis() <= runTime) {
        int minuts, seconds;
        minuts = (runTime - millis ()) / 60000 ;
        Serial.print (minuts);
        output(0x05, minuts % 10);
        output(0x06, minuts / 10);
        Serial.print (" : ");
        seconds = ((runTime - millis ()) % 60000) / 1000;
        Serial.println (seconds);
        output(0x01, seconds % 10);
        output(0x02, seconds / 10);
        if (digitalRead (Bot)) {
          Bip = false;
          delay (100);
          break;
        }
        //delay (1000);
      }
      if (Bip) {
        for (int i = 1; i <= 10; i++) {
          tone (BZzz, 1000);
          output(0x08, 15); //digit 7 (leftmost digit) data
          output(0x07, 15);
          output(0x06, 15);
          output(0x05, 15);
          output(0x04, 15);
          output(0x03, 15);
          output(0x02, 15);
          output(0x01, 15);
          delay (200);
          Serial.println ("Bip Bip Bip...");
          noTone (BZzz);
          output(0x08, 10); //digit 7 (leftmost digit) data
          output(0x07, 10);
          output(0x06, 10);
          output(0x05, 10);
          output(0x04, 10);
          output(0x03, 10);
          output(0x02, 10);
          output(0x01, 10);
          delay (200);
          tone (BZzz, 1000);
          output(0x08, 15); //digit 7 (leftmost digit) data
          output(0x07, 15);
          output(0x06, 15);
          output(0x05, 15);
          output(0x04, 15);
          output(0x03, 15);
          output(0x02, 15);
          output(0x01, 15);
          delay (200);
          Serial.println ("Bip Bip Bip...");
          noTone (BZzz);
          output(0x08, 10); //digit 7 (leftmost digit) data
          output(0x07, 10);
          output(0x06, 10);
          output(0x05, 10);
          output(0x04, 10);
          output(0x03, 10);
          output(0x02, 10);
          output(0x01, 10);
          delay (400);
        }
      }
      output(0x08, 15); //digit 7 (leftmost digit) data
      output(0x07, 15);
      output(0x06, 15);
      output(0x05, 15);
      output(0x04, 15);
      output(0x03, 15);
      output(0x02, 15);
      output(0x01, 15);
      runMode = false;
    }
  }
}

Step 9: Firmware Version Update

The update adds a stopwatch functionality.
Also, when the timer finish counting and beeping, its starts counting the time passed since the end of the timer and stops only on button press.

#define MAX7219_DIN 5
#define MAX7219_CS 6 #define MAX7219_CLK 7
#define Bot 4
#define BZzz 3
#define Pot 0
#define stopWatch 65
boolean runMode = false, stopWatchMode;
long runTime = 0;
void initialise()
{
  digitalWrite(MAX7219_CS, HIGH);
  pinMode(MAX7219_DIN, OUTPUT);
  pinMode(MAX7219_CS, OUTPUT);
  pinMode(MAX7219_CLK, OUTPUT);
}
void output(byte address, byte data)
{
  digitalWrite(MAX7219_CS, LOW);
  shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, address);
  shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, data);
  digitalWrite(MAX7219_CS, HIGH);
}
void setup() {
  Serial.begin (9600);
  pinMode (Bot, INPUT);
  pinMode (BZzz, OUTPUT);
  // put your setup code here, to run once:
  initialise();
  output(0x0f, 0x00); //display test register - test mode off
  output(0x0c, 0x01); //shutdown register - normal operation
  output(0x0b, 0x07); //scan limit register - display digits 0 thru 7
  output(0x0a, 0x0f); //intensity register - max brightness
  output(0x09, 0xff); //decode mode register - CodeB decode all digits
  output(0x08, 15); //digit 7 (leftmost digit) data
  output(0x07, 15);
  output(0x06, 15);
  output(0x05, 15);
  output(0x04, 15);
  output(0x03, 15);
  output(0x02, 15);
  output(0x01, 15); //digit 0 (rightmost digit) data
}
void loop() {
  if (!runMode){
    runTime = analogRead (Pot);
    runTime = map (runTime, 5, 1020, 1, 14) * 5;
    if (runTime == 70) {
      runTime = 65;
    }
    Serial.println (runTime);
    if (runTime <= 60) {
      output(0x05, runTime % 10);
      output(0x06, runTime / 10);
      output(0x01, 15);
      output(0x02, 15);
      stopWatchMode = false;
    } 
    if (runTime == stopWatch) {
      stopWatchMode = true;
      output(0x01, 0);
      output(0x02, 0);
      output(0x05, 0);
      output(0x06, 0);
    }
    
    if (digitalRead (Bot)) {
      delay (40);
      if (!stopWatchMode) {
        runTime = runTime * 60000 + millis();
        tone (BZzz, 300);
        delay (300);
      } else {
        runTime = millis ();
        tone (BZzz, 200);
        delay (400);
      }
      noTone (BZzz);
      runMode = true;
    } 
   if (runMode) {
    if (!stopWatchMode) {
      int Bip = true;
      while (millis() <= runTime) {
        int minuts, seconds;
        minuts = (runTime - millis ()) / 60000 ;
        Serial.print (minuts);
        output(0x05, minuts % 10);
        output(0x06, minuts / 10);
        Serial.print (" : ");
        seconds = ((runTime - millis ()) % 60000) / 1000;
        Serial.println (seconds);
        output(0x01, seconds % 10);
        output(0x02, seconds / 10);
        if (digitalRead (Bot)) {
          while (digitalRead (Bot)) {
            Bip = false;
            runMode = false;
            stopWatchMode = false;
            //Serial.println ("all False");
            output(0x08, 10); //digit 7 (leftmost digit) data
            output(0x07, 10);
            output(0x06, 10);
            output(0x05, 10);
            output(0x04, 10);
            output(0x03, 10);
            output(0x02, 10);
            output(0x01, 10);
          }
          
          break;
        } //end if digitalRead Bot
        
      }
      if (Bip) {
        runTime = millis ();
        for (int i = 1; i <= 10; i++) {
          tone (BZzz, 300);
          output(0x08, 15); //digit 7 (leftmost digit) data
          output(0x07, 15);
          output(0x06, 15);
          output(0x05, 15);
          output(0x04, 15);
          output(0x03, 15);
          output(0x02, 15);
          output(0x01, 15);
          delay (200);
          Serial.println ("Bip Bip Bip...");
          noTone (BZzz);
          output(0x08, 10); //digit 7 (leftmost digit) data
          output(0x07, 10);
          output(0x06, 10);
          output(0x05, 10);
          output(0x04, 10);
          output(0x03, 10);
          output(0x02, 10);
          output(0x01, 10);
          delay (200);
          tone (BZzz, 300);
          output(0x08, 15); //digit 7 (leftmost digit) data
          output(0x07, 15);
          output(0x06, 15);
          output(0x05, 15);
          output(0x04, 15);
          output(0x03, 15);
          output(0x02, 15);
          output(0x01, 15);
          delay (200);
          Serial.println ("Bip Bip Bip...");
          noTone (BZzz);
          output(0x08, 10); //digit 7 (leftmost digit) data
          output(0x07, 10);
          output(0x06, 10);
          output(0x05, 10);
          output(0x04, 10);
          output(0x03, 10);
          output(0x02, 10);
          output(0x01, 10);
          delay (400);
          stopWatchMode = true;
        }
      } // end void Bip
      output(0x08, 15); //digit 7 (leftmost digit) data
      output(0x07, 15);
      output(0x06, 15);
      output(0x05, 15);
      output(0x04, 15);
      output(0x03, 15);
      output(0x02, 15);
      output(0x01, 15);
      //runMode = false;
    } // end of runMode !stopWatchMode (timer Mode)
    
    if (stopWatchMode) { // StopWatch Run Mode begin
      int minuts, seconds;
      while (!digitalRead (Bot)) {
        minuts = (millis () - runTime) / 60000 ;
        Serial.print (minuts);
        output(0x05, minuts % 10);
        output(0x06, minuts / 10);
        Serial.print (" : ");
        seconds = ((millis () - runTime) % 60000) / 1000;
        Serial.println (seconds);
        output(0x01, seconds % 10);
        output(0x02, seconds / 10);
      }
      runMode = false;
      stopWatchMode = false;
      delay (500);
    }
   } 
  }
}