Welcome to Hackster!
Hackster is a community dedicated to learning hardware, from beginner to pro. Join us, it's free!
Pramod C Wickramasinghe
Published © GPL3+

Personal Gym Timer

A hardware timer to support your gym workout, and can influence you to complete the exercises in predefined time period.

BeginnerFull instructions provided12 hours3,842
Personal Gym Timer

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
SSD- Big
×1
SSD - Small
×1
Shift Register- Serial to Parallel
Texas Instruments Shift Register- Serial to Parallel
×1
Linear Regulator (7805)
Linear Regulator (7805)
×1
18650 Battery
×2
2S 20A 8.4V 18650 Lithium Battery Charger BMS Protection Balanced Standard Board
×1
2S 7.4V 8.4V Lithium Li-ion 18650 Battery Charging Board Charger Module
×1
Rotary Encoder with Push-Button
Rotary Encoder with Push-Button
×1
Toggle Switch, (On)-Off-(On)
Toggle Switch, (On)-Off-(On)
×1
Toggle Switch, (Off)-On
Toggle Switch, (Off)-On
×2
45mm Chic LED Light Arcade Video Game Player Big Round Push Button Switch
1pcs Red and 1pcs Green
×2
Plastic Enclosure, Project Box
Plastic Enclosure, Project Box
×1
DC Power Connector, Jack
DC Power Connector, Jack
×1

Software apps and online services

Arduino IDE
Arduino IDE
Proteus

Hand tools and fabrication machines

Drill, Screwdriver
Drill, Screwdriver
Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free
Mini Side Cutter, 120mm Length with 25mm Jaw Capacity
Mini Side Cutter, 120mm Length with 25mm Jaw Capacity

Story

Read more

Schematics

Gym timer Full Schematic

Controll Cct

SSD Cct

Code

Gym timer Code

Arduino
/*=============================================
    Program : Personal_Gym_timer
    Author  : wickPro-PC\wickPro
    Time    : 12:47 PM
    Date    : 3/11/2018
    Coded by: Pramod C Wickramasinghe
    E-mail  : wick.pro@gmail.com
    Mobile  : +94774585875
  =============================================*/

#define LATCH 6 // shift register latch pin
#define CLK 5
#define DATA 4

#define DISP_1 7 // 1st seven segment common pin
#define DISP_2 8
#define DISP_3 9

#define workoutLed A0
#define restLed A1
#define t0 A2
#define t1 A3

#define modeSwitch 10 // select between auto mode and manual mode
#define workoutBtn 2 // start workout 
#define restBtn 3 // start rest

#define buzzer A4

int _delay = 250; // refresh display
int _wait = 1000;  // counter time = one second in millis
int countDigit_1, countDigit_2 ; // 1st digit counter variable
int countDigit_3 = 1;

int w1stMax, w2ndMax, r1stMax, r2ndMax;

byte pushCount_w, pushCount_r = 0;
byte autoCount = 1;

boolean val_toggle = true; // check the counter's status and initialize
boolean endOf_rest = true;
boolean endOf_workout = false;
boolean currentButtonState_w;
boolean currentButtonState_r;
boolean lastButtonState_w = LOW;
boolean lastButtonState_r = LOW;
boolean DISP_state = LOW;
boolean modeToogle_auto;
boolean modeToggle_manual;

unsigned long currentMillis = 0;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

void buzz(char when) {
  switch (when) {
    case 'w': // end of rest
      digitalWrite(buzzer, HIGH);
      delay(100);
      digitalWrite(buzzer, LOW);
      delay(100);
      digitalWrite(buzzer, HIGH);
      delay(100);
      digitalWrite(buzzer, LOW);

    case 'r': // end of workout
      digitalWrite(buzzer, HIGH);
      delay(200);
      digitalWrite(buzzer, LOW);
  }
}

void showDigit(int digit) {
  switch (digit) {
    case 20:    // show dash (-) == 0b00000001
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK , MSBFIRST , 1);
      digitalWrite(LATCH, HIGH);
      break;

    case 30:    // show dot (.) == 0b10010000
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK , MSBFIRST , 16);
      digitalWrite(LATCH, HIGH);
      break;

    case 0:
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, 238);
      digitalWrite(LATCH, HIGH);
      break;

    case 1:
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, 40);
      digitalWrite(LATCH, HIGH);
      break;

    case 2:
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, 205);
      digitalWrite(LATCH, HIGH);
      break;

    case 3:
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, 109);
      digitalWrite(LATCH, HIGH);
      break;

    case 4:
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, 43);
      digitalWrite(LATCH, HIGH);
      break;

    case 5:
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, 103);
      digitalWrite(LATCH, HIGH);
      break;

    case 6:
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, 231);
      digitalWrite(LATCH, HIGH);
      break;

    case 7:
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, 44);
      digitalWrite(LATCH, HIGH);
      break;

    case 8:
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, 239);
      digitalWrite(LATCH, HIGH);
      break;

    case 9:
      digitalWrite(LATCH, LOW);
      shiftOut(DATA, CLK, MSBFIRST, 47);
      digitalWrite(LATCH, HIGH);
      break;

    default:
      break;
  }
}

void blankDisp() {
  digitalWrite(DISP_1, LOW);
  digitalWrite(DISP_2, LOW);
  digitalWrite(DISP_3, LOW);
  DISP_state = LOW;
}

void countUpto() {
  if (digitalRead(t0) == 1 && digitalRead(t1) == 0) {
    w1stMax = 9;
    w2ndMax = 5;
    r1stMax = 9;
    r2ndMax = 2;
  } else if (digitalRead(t1) == 1 && digitalRead(t0) == 0) {
    w1stMax = 9;
    w2ndMax = 8;
    r1stMax = 9;
    r2ndMax = 5;
  } else if (digitalRead(t0) == 0 && digitalRead(t1) == 0) {
    w2ndMax = 7;
    r2ndMax = 4;
    if (countDigit_2 > 6) {
      w1stMax = 5;
    } else {
      w1stMax = 9;
    } 
    if (countDigit_2 > 3) {
      r1stMax = 5;
    } else {
      r1stMax = 9;
    }
  } else {
    //never gonna happen
  }
}

void timer(char when) {
  switch (when) {

    case 'w':   // w for Workout in manual mode
      if (val_toggle == false) {
        val_toggle   = true;
        countDigit_1 = 0;
        countDigit_2 = 0;
        autoCount += 2;
      }
      if (millis() - currentMillis > _wait) {
        currentMillis = millis();
        countDigit_1++;
        countUpto();
        if (countDigit_1 > w1stMax ) {
          countDigit_1 = 0 ;
          countDigit_2++;
          if (countDigit_2 > w2ndMax) {
            countDigit_2  = 0;
            val_toggle    = false;
            endOf_workout = true;
            endOf_rest    = false;
            buzz('r');
          }
        }
      }
      break;

    case 'r':    // r for Rest in auto mode
      if (val_toggle == false) {
        val_toggle   = true;
        countDigit_1 = r1stMax;
        countDigit_2 = r2ndMax;
        autoCount += 2;
      }
      if (millis() - currentMillis > _wait) {
        currentMillis = millis();
        countDigit_1--;
        countUpto();
        if (countDigit_1 < 0 ) {
          countDigit_1 = r1stMax;
          countDigit_2--;
          if (countDigit_2 < 0) {
            countDigit_2  = r2ndMax;
            val_toggle    = false;
            endOf_rest    = true;
            endOf_workout = false;
            countDigit_3++; // count no of sets
            buzz('w');
            if (countDigit_3 > 3) {
              countDigit_3 = 1;
            }
          }
        }
      }
      break;

    case 'W':   // "W" for workout in auto mode
      if (val_toggle == false) {
        val_toggle   = true;
        countDigit_1 = 0;
        countDigit_2 = 0;
      }
      if (millis() - currentMillis > _wait) {
        currentMillis = millis();
        countDigit_1++;
        countUpto();
        if (countDigit_1 > w1stMax ) {
          countDigit_1 = 0 ;
          countDigit_2++;
          if (countDigit_2 > w2ndMax) {
            //countDigit_2 = 0;
            countDigit_1 = r1stMax;
            countDigit_2 = r2ndMax;
            val_toggle    = false;
            endOf_workout = true;
            endOf_rest    = false;
            pushCount_w++;
            buzz('r');
          }
        }
      }
      break;

    case 'R':   // "R" for rest in manual mode
      if (val_toggle == false) {
        val_toggle   = true;
        countDigit_1 = r1stMax;
        countDigit_2 = r2ndMax;
      }
      if (millis() - currentMillis > _wait) {
        currentMillis = millis();
        countDigit_1--;
        countUpto();
        if (countDigit_1 < 0 ) {
          countDigit_1 = r1stMax;
          countDigit_2--;
          if (countDigit_2 < 0) {
            countDigit_2  = r2ndMax;
            val_toggle    = false;
            endOf_rest    = true;
            endOf_workout = false;
            pushCount_r++;
            countDigit_3++;
            countDigit_1 = 0;
            countDigit_2 = 0; // count no of sets
            buzz('w');
            if (countDigit_3 > 3) {
              countDigit_3 = 1;
            }
          }
        }
      }
      break;

    default:
      break;
  }
}

void checkButtons () {

  currentButtonState_w = digitalRead(workoutBtn);
  currentButtonState_r = digitalRead(restBtn);

  if ((millis() - lastDebounceTime) > debounceDelay) {

    if (currentButtonState_r != lastButtonState_r) {
      if (currentButtonState_r == HIGH) {
        pushCount_r++;

        //Serial.print("pushCount_r = ");
        //Serial.println(pushCount_r);

        if (pushCount_r == 2) {
          pushCount_r = 0;
        }
      }
    }
    lastButtonState_r = currentButtonState_r;

    if (currentButtonState_w != lastButtonState_w) {
      if (currentButtonState_w == HIGH) {
        pushCount_w++;

        if (digitalRead(modeSwitch) == HIGH) { // set to true if auto mode
          endOf_workout = false;
          autoCount     = 0;
          val_toggle    = false;
          countDigit_3  = 1;
        }

        //Serial.print("pushCount_w = ");
        //Serial.println(pushCount_w);

        if (pushCount_w == 2) {
          pushCount_w = 0;
        }
      }
      lastButtonState_w = currentButtonState_w;
    }
    lastDebounceTime = millis();
  }
}

void modeInitiate(char mode) {

  switch (mode) {
    case 'a':         // "a" for auto mode
      if (modeToogle_auto == true) {
        //countDigit_1 = 0;
        //countDigit_2 = 0;
        //countDigit_3 = 1;
        //val_toggle   = true;
        endOf_rest      = false;
        endOf_workout   = false;
        autoCount       = 13;
        modeToogle_auto = false;
        //modeToggle_manual = false;
        //Serial.println("done auto");
      }
      break;

    case 'm':       // "m" for manual mode
      if (modeToggle_manual == true) {
        //countDigit_1      = 0;
        //countDigit_2      = 0;
        //countDigit_3      = 1;
        endOf_rest        = false;
        endOf_workout     = false;
        modeToggle_manual = false;
        //Serial.println("done manual");
      }
      break;

    default:
      break;
  }
}

void setup() {

  //Serial.begin(115200);

  pinMode(LATCH, OUTPUT);
  pinMode(CLK, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(DISP_1, OUTPUT);
  pinMode(DISP_2, OUTPUT);
  pinMode(DISP_3, OUTPUT);
  pinMode(modeSwitch, INPUT);
  pinMode(workoutBtn, INPUT);
  pinMode(restBtn, INPUT);
  pinMode(t0, INPUT), (t1, INPUT);
  pinMode(workoutLed, OUTPUT);
  pinMode(restLed, OUTPUT);
  pinMode(buzzer, OUTPUT);
}

void loop() {

  countUpto();

  //Serial.print("pushCount_r = ");
  //Serial.println(pushCount_r);

  //Serial.print("pushCount_w = ");
  //Serial.println(pushCount_w);

  checkButtons();

  modeToogle_auto = true;
  //modeToggle_manual = false;

  modeInitiate('m');

  if (pushCount_w % 2 != 0) {
    digitalWrite(workoutLed, HIGH);

  } else {

    digitalWrite(workoutLed, LOW);
  }
  if (pushCount_r % 2 != 0) {
    digitalWrite(restLed, HIGH);
  } else {
    digitalWrite(restLed, LOW);
  }

  if (endOf_workout == false && pushCount_w % 2 != 0) {
    timer('W');
  } else if (endOf_rest == false && pushCount_r % 2 != 0) {
    timer('R');
  }

  blankDisp();
  showDigit(countDigit_1);
  digitalWrite(DISP_1, HIGH);
  delayMicroseconds(_delay);

  blankDisp();
  showDigit(countDigit_2);
  digitalWrite(DISP_2, HIGH);
  delayMicroseconds(_delay);

  blankDisp();
  showDigit(countDigit_3);
  digitalWrite(DISP_3, HIGH);
  delayMicroseconds(_delay);


  while (digitalRead(modeSwitch) == HIGH) {       // true when auto mode

    modeToggle_manual = true;
    //modeToogle_auto   = false;

    modeInitiate('a');

    if (endOf_workout == false) {
      timer('w');        // w for Workout
    }
    else if (endOf_rest == false) {
      timer('r');       // r for Rest
    }

    //Serial.print("Auto Count = ");
    //Serial.println(autoCount);

    if (autoCount > 12) {    // stop after three sets
      endOf_rest    = true;
      endOf_workout = true;
      checkButtons();

      if (millis() - currentMillis > _wait / 3) {
        currentMillis = millis();

        if (DISP_state == HIGH) {
          blankDisp();
          showDigit(20);
          digitalWrite(DISP_1, HIGH);
          digitalWrite(DISP_2, HIGH);
          digitalWrite(DISP_3, HIGH);
          DISP_state = LOW;
        } else {
          blankDisp();
          showDigit(30);
          digitalWrite(DISP_1, HIGH);
          digitalWrite(DISP_2, HIGH);
          digitalWrite(DISP_3, HIGH);
          DISP_state = HIGH;
        }
      }
    }

    if (endOf_rest == false || endOf_workout == false) {

      blankDisp();
      showDigit(countDigit_1);
      digitalWrite(DISP_1, HIGH);
      delayMicroseconds(_delay);

      blankDisp();
      showDigit(countDigit_2);
      digitalWrite(DISP_2, HIGH);
      delayMicroseconds(_delay);

      blankDisp();
      showDigit(countDigit_3);
      digitalWrite(DISP_3, HIGH);
      delayMicroseconds(_delay);

    }
  }
}

Credits

Pramod C Wickramasinghe
4 projects • 27 followers
The kind of person who turns ideas into projects, and projects into success.
Contact

Comments

Please log in or sign up to comment.