Time kind of got away from us on this one, due in no small part to other classes and other projects. The original idea was some sort of DDR/Stepmania glove game, but ended up as just a prototype for the glove part, which was a glove with running LEDs on it that could be stopped and reset via buttons on the fingers. The LEDs would light in sequence from wrist to finger tip, and if the rest of this had been built the wearer would have been awarded points for tapping their finger when the last LED lit.

glovebuttons2

Tactile buttons on the bottom of the glove. Getting the buttons to click

isn’t really easy. We played with different positions on the finger, but the button

just seems to rely too much on a straight down press to be good for

this kind of thing.

glovetop

Glove and Duemilanove. Hidden among the rope of wires running down the

index finger are five LEDs: a green one at the tip of the finger, three yellows and

red one at the bottom.

schematic

Handy schematic.

It works except for the sync part. That’s still not working. I would have a video for you but word press apparently thinks that videos come in jpg, jpeg, png, gif, pdf, doc, ppt, odt, pptx or docx. Way to go dip-shits.

partsAll the parts for the circuit. 2 yellow LEDs, 2 220 ohm resistors, 4 trimmer type

potentiometers, the breadboard and the Duemilanove.

circuitAlso the first attempt at the circuit.

Trying the AnalogInput example code shows my circuit isn’t right. I thought the potentiometers would work like a slide switch, but it turns out one of the outside pins has to go to power, instead of both going to ground. So …

blinknew1

new Fritzing breadboard …

blinkschemsimpnewnew circuit diagram and …

circuitnewnew circuit.

A little code:

int clickPin = 0; //input pin for the click track pot
int offsetPin = 1; //input pin for the offset pot
int gridPin = 2; //input pin for the grid pot
int gatePin = 3; //input pin for the gate pot

int clickLEDPin = 3; //pin for the click track LED
int beatLEDPin = 2; //pin for the beat LED

int bpm = 0; //bpm set by click track pot
int offset = 0; //set by offset pot
int grid = 0; //set by grid pot
int gate= 0 ; //set by gate pot

//COUNTERS
int gateCounter = 0;
int beatCounter = 0;

//TIMERS
int milliBlink = 10; //how long to keep the LEDs on

int clickTimer = 0; //the last time the click LED blinked
int clickBlink = 0; //the last timer the click LED was turned on

int beatTimer = 0; //the last time the beat LED blinked;
int beatBlink = 0; //the last time the beat LED was turned on

//UTILITY VARIABLES
int rateValues[] = {32, 24, 16, 12, 8, 6, 4, 3, 2, 1};

void setup() {
  pinMode(clickLEDPin, OUTPUT);
  pinMode(beatLEDPin, OUTPUT);

  clickBlink = millis();
  clickTimer = millis();

  Serial.begin(9600);
}

void loop() {
  //collect raw values
  bpm = analogRead(clickPin);
  offset = analogRead(offsetPin);
  grid = analogRead(gridPin);
  gate = analogRead(gatePin);

  //TRANSFORM VALUES
  //bpm
  bpm = map(bpm, 0, 1023, 60, 180); //remap pot value to 60-120
  bpm = 60000/bpm; //convert it from a rate to a delay in milliseconds

  //grid - grid maps to either 1/32, 1/24, 1/16, 1/12, 1/8, 1/6, 1/4, 1/3, 1/2 or 1
  grid = rateValues[map(grid, 0, 1023, 0, 9)]; //remap pot value to an array index
  //pardon the interruption, we need to calculate gate here - maps the same as grid
  gate = rateValues[map(gate, 0, 1023, 0, 9)];
  gate = grid/gate;
  //now back to grid
  grid = (bpm*4)/grid; //convert from rate to delay

  //CLICK LED STUFF
  //blink the LED
  if(millis() - clickBlink < milliBlink) {
    digitalWrite(clickLEDPin, HIGH);
  } else {
    digitalWrite(clickLEDPin, LOW);
  }

  //blink the led every bpm number of milliseconds, or every 1/4 note
  if(millis() - clickTimer > bpm) {
    clickBlink = millis();
    clickTimer = millis();
    beatCounter++;
    //reset beat counter and gate counter every measure
    if(beatCounter == 4) {
      beatCounter = 0;
      gateCounter = 0;
    }
  }

  //BEAT LED STUFF
  //blink the LED
  if(millis() - beatBlink < milliBlink && gateCounter <= gate) {
    digitalWrite(beatLEDPin, HIGH);
  } else {
    digitalWrite(beatLEDPin, LOW);
  }

  //blink the led every grid number of milliseconds
  if(millis() - beatTimer > grid) {
    beatBlink = millis();
    beatTimer = millis();
    gateCounter++;
  }

  //debugging stuff
  Serial.println(gate);
}

Tempo, grid and gate work. Tomorrow will be getting offset to work and figuring out why the LEDs go out of sync sometimes and why the whole thing just stops sometimes.

Project Blink.

An LED version of the Beat Repeat audio effect in the Ableton Live DAW. One LED will act as a click track and the other as the sample to repeat. One potentiometer will control the tempo, one the offset (how late into each measure to start the repetitions), one the grid (how quickly to repeat the sample) and the last will control gate (how many times to repeat the sample).

Gate is expressed as a fraction of a measure and is also dependent on the grid setting. So for example if the grid is set 1/32, and gate is set to 1/2, you will get one repetition every 1/32 of a measure, for 1/2 a measure, so 16 repetitions. A gate setting lower than the grid setting effectively results in no repetitions.

blink

Fritzing breadboard image of circuit.

blinkschem

Fritzing circuit diagram. Bit confusing.

blinkschemsimp

A little clearer.