glennedi
Published © GPL3+

GymGeneral - A Sports Interval Timer

Easy setup via .txt file.

IntermediateFull instructions provided8,349
GymGeneral - A Sports Interval Timer

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
TTP223B capacitive touch switch
×2
Serial I2C LCD Backpack
×1
2*16 LCD display
×1
Piezo sounder
×1
Deek robot data logging shield v1.0
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Diagram of connections

Code

GymGeneral code

C/C++
/*
 The circuit:
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 10 -> for deek robot data shield v1.0
 */
#include <SPI.h>
#include <SD.h>

const int chipSelect=10;

//my_aliases
const int down_switch=3;
const int enter_switch=2;

const int start_screen=1;
const int initialization_screen=2;
const int file_menu_screen=3;
const int file_wont_open_screen=4;

//my_boolean variables
volatile bool count_updated=true;
volatile bool enter_pressed=false;
volatile bool beep_file_contents=false;
volatile bool do_update=true;

File root;
File myFile;

/*-----( Import needed libraries )-----*/
#include <Wire.h>  // Comes with Arduino IDE
// Get the LCD I2C Library here: 
// https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
// Move any other LCD libraries to another folder or delete them
// See Library "Docs" folder for possible commands etc.
#include <LiquidCrystal_I2C.h>

// set the LCD address to 0x27 for a 16 chars 2 line display
// A FEW use address 0x3F ------------------------> like mine!
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

//my_global_variables
int screen_number=start_screen;
bool initialization_fail=false;
bool file_exists=false;
static String my_filename="";

const int sounder_pin=9;// the pin we attach our sounder to
const int duty_cycle=128;//50% duty cycle for analogWrite()

void setup() {

//initial lcd setup
  lcd.begin(16,2);    // initialize the lcd for 16 chars 2 lines
  lcd.backlight();    //turn on backlight    
  lcd.clear();

  update_display();
  delay(5000);
  screen_number=initialization_screen;

//try to initialize sd card
  if (!SD.begin(chipSelect)) {
    initialization_fail=true;
    update_display();
    return;
  }
  initialization_fail=false;
  update_display();
  delay(5000);
  
//for switches
  pinMode(down_switch, INPUT);// sets the digital pin as input
  pinMode(enter_switch, INPUT);// sets the digital pin as input
  attachInterrupt(digitalPinToInterrupt(down_switch), enter_button, RISING);
  attachInterrupt(digitalPinToInterrupt(enter_switch), increment_down, RISING);

  // initialize digital pin as an output.
  pinMode(sounder_pin, OUTPUT);

}/*end of setup*/

void loop() {
  
  root = SD.open("/");

  int repeats=0;
  int frequency=0;
  int on_time=0;
  int off_time=0;
  int index=0;
 
while(1){

  if (do_update){do_update=false;update_display();}
  
  if (count_updated){


  //cycle through the existing files on the SD card
  count_updated=false;

  File entry =  root.openNextFile();
    if (! entry) {
      // no more files -> so go back to beginning
      entry.close();
      root.rewindDirectory();
      my_filename="No more";
      update_display();   
    }else
    {
    my_filename=entry.name(); 
    screen_number=file_menu_screen;
    update_display();
    entry.close();}                   
                    }

//beep out the intervals from the chosed file
if (beep_file_contents){
  
  beep_file_contents=false;

  if (SD.exists(my_filename)) {file_exists=true;}else{file_exists=false;}
  
  update_display();

  //read data from file
  // re-open the file for reading:
  myFile = SD.open(my_filename, FILE_READ);
  if (myFile) {

    // read from the file until there's nothing else in it:
    while (myFile.available()) 
    {
      repeats=myFile.parseInt();
      frequency=myFile.parseInt();
      on_time=myFile.parseInt();
      off_time=myFile.parseInt();

      for (index=0;index<repeats;index++)
      {
        if (frequency==1){TCCR1B = (TCCR1B & 0b11111000) | 0x04;}else{TCCR1B = (TCCR1B & 0b11111000) | 0x02;}
        analogWrite(sounder_pin, duty_cycle);
        delay(on_time*100);
        analogWrite(sounder_pin,0);
        delay(off_time*100);
        }     
    }

    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    screen_number=file_wont_open_screen;
    update_display();
  }

}//end beep out file
                    
}
  
}/*end of loop*/

//my_functions

//my_isr_functions
void enter_button(void)//enter button
{   switch(screen_number){case file_menu_screen:beep_file_contents=true;break;
                          case file_wont_open_screen:screen_number=file_menu_screen;do_update=true;break;}
}

void increment_down()//down button
{if (screen_number==file_menu_screen){count_updated=true;}}

//my_screen_functions
void update_display(void)
{
  switch (screen_number)
  {
    case start_screen:lcd.clear();
                      lcd.setCursor(3,0);
                      lcd.print("GymGeneral");
                      lcd.setCursor(3,1);
                      lcd.print("Gym timer");
                      break;    
    case initialization_screen:lcd.clear();
                               lcd.setCursor(0,0);
                               lcd.print("Init SD...");
                               if (!initialization_fail){lcd.print("done.");}else{lcd.print("fail!");}
                               break;
    case file_menu_screen:lcd.clear();
                          lcd.setCursor(2,0);
                          lcd.print("Select file");
                          lcd.setCursor(2,1);
                          lcd.print("            ");//clear any previous filename (8.3 character format, so 12 spaces)
                          lcd.setCursor(2,1);
                          lcd.print(my_filename);
                          break;                        
    case file_wont_open_screen:lcd.clear();
                               lcd.print("Can't open file");
                               break;          
    }
  }

Credits

glennedi

glennedi

5 projects • 23 followers

Comments