User:Fako Berkers/clapping

From XPUB & Lens-Based wiki
< User:Fako Berkers
Revision as of 22:53, 30 October 2010 by Fako Berkers (talk | contribs) (Created page with "==Dynamic clapping music== My idea was to make a small interface to the clapping music program that enables people to change the pattern manually. I wanted to have four buttons:...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Dynamic clapping music

My idea was to make a small interface to the clapping music program that enables people to change the pattern manually. I wanted to have four buttons:

  • button 1 would shift a note/rest from the end to the beginning with the part of performer 1
  • button 2 would shift a note/rest from the beginning to the end with the part of performer 1
  • button 3 would shift a note/rest from the end to the beginning with the part of performer 2
  • button 4 would shift a note/rest from the beginning to the end with the part of performer 2

This allows you to explore all possibilities of the clapping music principle.

While building this Stock mentioned some possible improvements and I went along learning some new things. This also means that I do not entirely understand the code yet, but I'll try to explain as much as possible so I can grasp it better myself. I also want to mention Laura for her great idea to double the pattern (it makes coding Clapping Music so much easier, thnx!)

Hardware

  • Pin 13 is connected (together with ground) to the speaker as output.
  • Pin 8 to 11 are output and set to high one at a time using a timer (internal) interrupt
  • Pin 2 is used as input and is set to high
  • The four wires coming from 8 through 11 are going to one end of the switches
  • The other end of these switches are connected through diodes with ground (in such a way that no current can go from ground to the switches)
  • Ground is connected to pin 2

Code

// Include libraries
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>

// Declare variables
// The pattern
char pat[] = "xxx xx x xx ";
char patd[25];
int patlen = strlen(pat);
// Indices for pattern changing
int per1 = 0;
int per2 = 0;
// per12 and 22 will change when buttons are pressed and per1 and 2 will synchronize with them at the end of the loop.
int per12 = per1;
int per22 = per2;
// Make button vars.
//bool pressed = false;
int button = 0;
// Define Pins
int outPin = 13;
 
int butt_state[4] = {HIGH, HIGH, HIGH, HIGH};

 
// define constatnts for configuring timer1

#define TIMER1_MAX               1250
#define TIMER1_INTERRUPT_MASK    _BV(OCIE1A)
#define TIMER1_MODE_A            0
#define TIMER1_MODE_B            (_BV(WGM12) | _BV(CS11) | _BV(CS10)) // CTC-mode, prescaler Fclk/64
 
void setup() {
  
  // Make the pattern to work with double size.
  strcat(patd,pat);  
  strcat(patd,pat);
  
  // Set Ardiuno in right mode.
  pinMode(8,OUTPUT);
  pinMode(9,OUTPUT);
  pinMode(10,OUTPUT);
  pinMode(11,OUTPUT);
  digitalWrite(8,HIGH);
  digitalWrite(9,HIGH);
  digitalWrite(10,HIGH);
  digitalWrite(11,HIGH);
  pinMode(2,INPUT);
  digitalWrite(2,HIGH); // Activate internal pull up resistor.
  
  TCCR1A = TIMER1_MODE_A;
  TCCR1B = TIMER1_MODE_B;
  OCR1A = TIMER1_MAX;
  TIMSK1 = TIMER1_INTERRUPT_MASK;

  sei();  // enable interrupts globally 
 
  Serial.begin(115200); 
}
 
void loop () {
 
  for (int p=0; p<patlen; p++) {
    
    // Make the tones.
    if (patd[p+per1] == 'x') {
      tone(outPin, 500, 25);
    }
    delay(25);
    if (patd[p+per2] == 'x') {
      tone(outPin, 1000, 25);
    }
    delay(300);
    
    per1 = per12;
    per2 = per22;
    
    Serial.print(per1);
    Serial.print(" ");
    Serial.print(per2);
    Serial.print(" Butt_State:");
    for (int i = 0; i < 4; i++)
    {
      Serial.print(butt_state[i]);
      Serial.print(" ");    
    }
    Serial.println();
    
  }
  
}

// Called during timer interrupt
void read_buttons() {
  int input_pin = digitalRead(2);
  
  if (input_pin != butt_state[button])
  {
    butt_state[button] = input_pin;
    if (input_pin == LOW)    // button pressed 
    {
      switch (button)
      {
        case 0:
          per22++;
          break;
        case 1:
          per22--;
          break;
        case 2:
          per12++;
          break;
        case 3:
          per12--;
          break;
      }
      if (per22 > patlen) per22 = 0;
      if (per22 < 0) per22 = patlen;
      if (per12 > patlen) per12 = 0;
      if (per12 < 0) per12 = patlen;
    }
  }  
}

// Timer1 Output Compare A Interrupt
ISR(TIMER1_COMPA_vect)
{
    digitalWrite(button+8,HIGH);
    button++;
    button %= 4; // This makes a value of 4 going to 0 (making possible values 0, 1, 2, 3)
    digitalWrite(button+8,LOW);
    read_buttons();
}

Next step

I would like to insert a latin rhythm in the same interface instead of what Steve Reich used.