Arduino Projects

Arduino
  1. Burst Mode/Interval Trainer

Burst Mode/Interval Trainer

This tool emits audible signals to allow burst mode training without the use of a timer or clock. It beeps at the start (or during) the burst cycle and uses a different tone for the end of the cycle. This should allow you to do things other than to pay attention to a timer or clock for the burst cycle while riding your stationary bike or elliptical trainer.
The circuit is as simple as possible, just a resistor and a speaker.
Please see this page for the pitches.h file and the circuit and schematic.

/*
Burst training - sound cue generator
 
circuit:
 * 8-ohm speaker on digital pin 8
 
created 1 Mar 2014

Based on this example code in the public domain.
    http://arduino.cc/en/Tutorial/Tone

TODO:
- add support for other LED (so it can be packaged up in enclosure)
- play a better melody
- add support to pause?
- add buttons and 2x 8segment leds to configure parameters
*/
#include "pitches.h"

#define SETTLE_TIME    20 // in seconds
#define WARM_UP_TIME   (1*60) // in seconds
// eg. 20 second burst cycle - 8 seconds go, 12 seconds slow
#define BURST_CYCLE    20 // in seconds
#define BURST_ON       8 // in seconds
#define WORKOUT_TIME   (18*60) // in seconds=20 minutes
#define WARM_DOWN_TIME (1*60) // =1 minute
#define BURST_TONE     1 // play NOTE_GO every second during GO

#define SPKR_PIN       8   // resistor->speaker[red]
#define LED_PIN        13  // built-in UNO LED

#define MODE_NOT_INIT  0
#define MODE_SETTLE    1
#define MODE_WARM_UP   2
#define MODE_GO        3
#define MODE_SLOW      4
#define MODE_DOWN      5
#define MODE_DONE      6

#define NOTE_INIT      NOTE_B3
#define NOTE_GO        NOTE_C1
#define NOTE_GO_A      NOTE_B0
#define NOTE_SLOW      NOTE_DS6
#define NOTE_DOWN      NOTE_B2

#define SEC_TO_MS(n)   ((n) * 1000)
#define MS_TO_SEC(n)   ((n) / 1000)

unsigned long g_next = 0;
unsigned long g_cycle_len = 0;
int g_mode = MODE_NOT_INIT;

// notes in the melody:
int melody[] = {NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {4, 8, 8, 4, 4, 4, 4, 4};

void setup()
{
  
  Serial.begin(9600);
  pinMode(LED_PIN, OUTPUT); // onboard LED!
  digitalWrite(LED_PIN, LOW);
  // play some notes so we can tell it's running
  play_note(NOTE_INIT, 0);
  play_note(NOTE_GO_A, 0);
  play_note(NOTE_GO, 0);
  play_note(NOTE_SLOW, 0);
  play_note(NOTE_DOWN, 0);
  g_next = millis() + SEC_TO_MS(SETTLE_TIME);
  g_mode = MODE_SETTLE;
}

void play_note(int thisNote, unsigned long noteDuration)
{
  // to calculate the note duration, take one second divided by the note type.
  //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
  if (noteDuration == 0)
    noteDuration = SEC_TO_MS(1)/4;
  tone(SPKR_PIN, thisNote, noteDuration);
  // to distinguish the notes, set a minimum time between them.
  delay(noteDuration * 1.3);
  // stop the tone
  noTone(SPKR_PIN);
}

void play_melody()
{
  // iterate over the notes of the melody:
  for (int thisNote = 0; thisNote < sizeof(melody)/sizeof(melody[0]); thisNote++) {
    // to calculate the note duration, take one second 
    // divided by the note type.
    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    int noteDuration = SEC_TO_MS(1)/noteDurations[thisNote];
    play_note(melody[thisNote], noteDuration);
  }
}

unsigned long handle_cycle(unsigned long curt)
{
  unsigned long len = 0;
  
  g_cycle_len++;
  switch (g_mode) {
    case MODE_SETTLE:
      len = SETTLE_TIME;
      break;
    case MODE_WARM_UP:
      len = WARM_UP_TIME;
      break;
    case MODE_GO:
      len = BURST_ON;
      break;
    case MODE_SLOW:
      len = BURST_CYCLE - BURST_ON;
      break;
    case MODE_DOWN:
      len = WARM_DOWN_TIME;
      break;
    case MODE_DONE:
      return 0;
  }
  if (g_cycle_len >= len) {
    g_cycle_len = 0;
    if (g_mode == MODE_SETTLE) {
      g_mode = MODE_WARM_UP;
      play_melody();
      digitalWrite(LED_PIN, HIGH);
    } else if (g_mode == MODE_WARM_UP || g_mode == MODE_SLOW) {
      g_mode = MODE_GO;
      digitalWrite(LED_PIN, HIGH);
      play_note(NOTE_GO, 0);
    } else if (g_mode == MODE_GO) {
      g_mode = MODE_SLOW;
      digitalWrite(LED_PIN, LOW);
      play_note(NOTE_SLOW, 0);
    }
    if (MS_TO_SEC(curt) > (WARM_UP_TIME + WORKOUT_TIME)) {
        g_mode = MODE_DOWN;
        play_note(NOTE_DOWN, 0);
        play_note(NOTE_DOWN, 0);
        play_note(NOTE_DOWN, 0);
    }
    if (MS_TO_SEC(curt) > (WARM_UP_TIME + WORKOUT_TIME + WARM_DOWN_TIME)) {
        g_mode = MODE_DONE;
        play_melody();
        play_melody();
    }
  } else {
    if (g_mode == MODE_SETTLE) {
      if (curt % 2 == 0)
        digitalWrite(LED_PIN, HIGH);
      else
        digitalWrite(LED_PIN, LOW);
    } else if (g_mode == MODE_WARM_UP) {
      if (g_cycle_len + 5 == len) { // 5 second warning
        play_note(NOTE_GO_A, 0);
        play_note(NOTE_GO_A, 0);
        play_note(NOTE_GO_A, 0);
      }
    } else if (g_mode == MODE_GO) {
      if (BURST_TONE)
        play_note(NOTE_GO, 0);
    } else if (g_mode == MODE_SLOW) {
      if ((g_cycle_len + 1 == len && !BURST_TONE)
        play_note(NOTE_GO, 0);
    }
  }
  return curt + SEC_TO_MS(1);
}

void loop()
{
  unsigned long curt;
  
  curt = millis();
  if (curt >= g_next) {
    g_next = handle_cycle(curt);
  }
  delay(20);
}
Speaker Circuit
Speaker Schematic