Beam Beats tangible rhythm sequencer: work is in progress!

Beam Beats is an interactive and tangible rhythm sequencer that translates the geometry of beacons on the ground into rhythms and polyrhythms thanks to a rotating laser beam. This experimental MIDI instrument is about investigating self-similarities in polyrhythms, as described in this post.

Update: Here’s the video of a demo at Dorkbot at La Gaité Lyrique in Paris

BeamBeats demo at Dorkbot at la Gaité Lyrique from cyrille martraire on Vimeo.

Before I report more on this project with demos and videos, here are some pictures to illustrate the work currently in progress, thanks to lasercutting techniques in particular:

The brand new laser-cut acrylic structure
The prototype laser head and retro-reflection light sensor
The Arduino to detect the light variations and convert them into MIDI notes
Very early design of beacons each with their own light sensor

This prototype works, here’s a picture of the laser beam rotating:

The revolving laser beam reflected on the wall

And here’s a very short early video (no sound)

Beam Beats – revolving laser beam to detect beacons from cyrille martraire on Vimeo.

I’ve been working on the Arduino source code to add the ability to send MIDI clock in order to sync Beam Beats to other MIDI devices.

Now I mostly need to conclude on the design for the active  beacons(sensors stands) and the passive (retroreflective adhesive stands) beacons, and find out what to play with this sequencer…

Every post on this project: http://cyrille.martraire.com/tag/beam-beats

Read More

Knobs pagination in Arduino

Here is an example of how to use the same knobs (e-g. 6 knobs easy to connect to the 6 Arduino analog inputs) several times to adjust several parameters spread over several “pages”.

This enables to “multiplex” the same knobs many times, in a safely fashion thanks to the protection mecanism:  after changing the active page, every knob is in protected mode (turning the knob does not change the value of the parameter) not to force a sudden jump of value. On turning a knob, the LED lights on when the knob’s value matches the stored value, and then the knob becomes fully active (at least till the next page switch).

This mecanism is inspired and similar to that of the microKorg synth edit knobs. As they say about it in Wikipedia:

“In the Edit mode, however, every knob makes the LED panel display the current value associated with the knob position. To change the current value of a given parameter, the user must pass through the original value before being able to modify anything. When one that original value, the Original Value LED will light on, and the value displayed on the LED panel will stop flashing. This avoids the user from passing from a small to a high value immediately, so there’s no big margin in the change of the parameters (a useful function for live performances).”
The microKorg Edit panel, with 5 knobs and 22 pages = 120 parameters to control
The microKorg Edit panel, with 5 knobs and 22 pages = 120 parameters to control

In Arduino

Console output printing the 4 pages of 6 parameters and the currently active page
Console output printing the 4 pages of 6 parameters and the currently active page

To do this in Arduino is not very difficult.We first need a 2-dimension array to store the value of each parameter:

// the permanent storage of every value for every page, used by the actual application code
int pageValues[PAGE_NB][KNOB_NB];

We also need an array to store the state of each knob: whether it is PROTECTED or ACTIVE, and yet another array to keep track of the value of each knob in the previous loop, in order to detect when a knob is being turned:

// last read knob values
int knobsValues[KNOB_NB];
// knobs state (protected, enable...)
int knobsStates[KNOB_NB];

Then we begin to read the digital switches to select the current active page. In case the selected page has changed, every knob has its state set to PROTECTED. We then read the analog value for each knob, detect changes, find out when the knob value is in sync with the stored value for the parameter to light the LED and set its state to ACTIVE.

Only when the state is set to ACTIVE we copy the current value of the knob to the actual parameter stored for the current page.

In my experiment I have 4 digital buttons connected to digital inputs 8 to 11, and 6 knobs (pots) connected to the 6 analog inputs:

The Arduino board, the 4 page buttons and the 5 + 1 knobs and fader
The Arduino board, the 4 page buttons, the 5 + 1 knobs and fader and the LED

Here is the full code below:

/*
 * Handles a pagination mecanism, each page can use the same knobs;
 * Digital switches select the current active page.
 *
 * This enables to "multiplex" the same knobs many times, safely thanks to the protection mecanism.
 *
 * After changing the active page, every knob is protected, not to force a jump in value.
 * On turning a knob the LED lights up when the knob's value matches the stored value, and then
 * the knob becomes active till next page switch.
 *
 * This mecanism is inspired and similar to that of the microKorg synth edit knobs.
 *
 * Copyleft cyrille martraire cyrille.martraire.com
 */ 

//---------- USER INPUT AND PAGINATION -----------
#define PAGE_NB 4
#define KNOB_NB 6
#define FIRST_PAGE_BUTTON 8

#define PROTECTED -1
#define ACTIVE 1

#define SYNC_LED 12

// the permanent storage of every value for every page, used by the actual music code
int pageValues[PAGE_NB][KNOB_NB];

// last read knob values
int knobsValues[KNOB_NB];
// knobs state (protected, enable...)
int knobsStates[KNOB_NB];
// current (temp) value just read
int value = 0;
// the current page id of values being edited
int currentPage = 0;
// signals the page change
boolean pageChange = false;
//temp variable to detect when the knob's value matches the stored value
boolean inSync = false;

void setup() {
  pinMode(13, OUTPUT);

  Serial.begin(19200);

  setupPagination();
}

void setupPagination(){
  pinMode(SYNC_LED, OUTPUT);
  for(int i=0; i < KNOB_NB; i++){
    knobsValues[i] = analogRead(i);
    knobsStates[i] = ACTIVE;
  }
}

// read knobs and digital switches and handle pagination
void poolInputWithPagination(){
  // read page selection buttons
  for(int i = FIRST_PAGE_BUTTON;i < FIRST_PAGE_BUTTON + PAGE_NB; i++){
     value = digitalRead(i);
     if(value == LOW){
         pageChange = true;
         currentPage = i - FIRST_PAGE_BUTTON;
     }
  }
  // if page has changed then protect knobs (unfrequent)
  if(pageChange){
    pageChange = false;
    digitalWrite(SYNC_LED, LOW);
    for(int i=0; i < KNOB_NB; i++){
      knobsStates[i] = PROTECTED;
    }
  }
  // read knobs values, show sync with the LED, enable knob when it matches the stored value
  for(int i = 0;i < KNOB_NB; i++){
     value = analogRead(i);
     inSync = abs(value - pageValues[currentPage][i]) < 20;

     // enable knob when it matches the stored value
     if(inSync){
        knobsStates[i] = ACTIVE;
     }

     // if knob is moving, show if it's active or not
     if(abs(value - knobsValues[i]) > 5){
          // if knob is active, blink LED
          if(knobsStates[i] == ACTIVE){
            digitalWrite(SYNC_LED, HIGH);
          } else {
            digitalWrite(SYNC_LED, LOW);
          }
     }
     knobsValues[i] = value;

     // if enabled then miror the real time knob value
     if(knobsStates[i] == ACTIVE){
        pageValues[currentPage][i] = value;
     }
  }
}

void loop() {
  poolInputWithPagination();
  printAll();
  delay(100);
}

void printAll(){
     Serial.println("");
     Serial.print("page ");
     Serial.print(currentPage);

     //Serial.println("");
     //printArray(knobsValues, 6);
     //Serial.println("");
     //printArray(knobsStates, 6);

     for(int i = 0; i < 4; i++){
       Serial.println("");
       printArray(pageValues[i], 6);
     }
}

void printArray(int *array, int len){
  for(int i = 0;i< len;i++){
       Serial.print(" ");
       Serial.print(array[i]);
  }
}

Read More