11 March 2021

 NIME Music Box

David Perez

 

My NIME music box device is very akin to a synthesizer. The device at all times is creating beeps and rotating its servo and it's up to the user to manipulate the way it sounds and how fast is plays. The music box is housed in a small rectangular box suitable for most hands to comfortably grip and reach all the controls. Users can input to the device using the two push buttons on the Circuit Playground Express, the slide switch on the CPE, the potentiometer dial on the box or by moving the box around to input motion.

Input/Output

Across the Circuit the LEDs are active. The LEDs by the corners (0, 5, 6 and 9) are lit green, LEDs 1 and 8 are red and LEDs 3, 4, 7 and 8 are blue. These are the default states of these LEDs.

The left push button adds 2 beats to the tempo while held down and changes LED 1 to blue to provide feedback.

The right push button adds 1 beat to the tempo while held down and changes LED 8 to blue to provide feedback.

When both push buttons are held, all beats are added together.

When the slide switch is in the + position, the tempo's rate increases and the Green LEDs become yellow to emphasize the new speed.

When the user shakes the music box, the CPE detects the motion and calculates a multiplier to the sound. The blue LEDs will become yellow when motion is detected (or white if much motion is detected). The stark change in color helps the user to understand their motion is detected.

When the potentiometer is twisted left, the sound is manipulated on a base level. The values of the potentiometer are greater than what motion can achieve, but the two are multiplied together. This can be used to raise the base value, then shake the device and achieve higher than normal sounds.

Would the device be easier to control or understand if the slide switch and buttons were external? That is, if the buttons were attached to the box as opposed to the circuit itself?

Video Demo

Schematic

Code

#include <Adafruit_CircuitPlayground.h>
#include <Adafruit_Circuit_Playground.h>
#include <Servo.h>


// initilization

// Servo
Servo myservo;
int pos = 0; // actual Servo position
int dir; // represents the condition the servo is in with 0 or 1

int rate = 500; // set base tempo
int potpin = A6; // potentiometer

// Sound data
int pitch; // adds pitch via potentiometer
int motion = 0; // contains the level of motion generated by the user
int sound; // end result sound after all inputs are calcuated



void setup() {
  CircuitPlayground.begin();
  myservo.attach(3);
  CircuitPlayground.setPixelColor(0, 0, 20, 0);
  CircuitPlayground.setPixelColor(9, 0, 20, 0);
  CircuitPlayground.setPixelColor(4, 0, 20, 0);
  CircuitPlayground.setPixelColor(5, 0, 20, 0);
}

// main loop below
void loop() {

  pitch = analogRead(potpin); // read poteniometer input
  pitch = map(pitch, 0, 1023, 0, 60); // map input to pitch scaling from 0 to 60
  motion = motionMulti(motion); // call function that gets multiplier of motion
  sound = pitch * motion; // Final calculation of sound, motion times pitch

  // base tempo, plays with no input. Base tempo = 7 + sound
  CircuitPlayground.playTone((7 + sound), rate);

  if (CircuitPlayground.slideSwitch()) {
    rate = 200; // change tempo to 200 when slide-switch is +, change LEDs to yellow
    CircuitPlayground.setPixelColor(0, 20, 20, 0);
    CircuitPlayground.setPixelColor(9, 20, 20, 0);
    CircuitPlayground.setPixelColor(4, 20, 20, 0);
    CircuitPlayground.setPixelColor(5, 20, 20, 0);
  }
  else {
    rate = 500; // return tempo to 500, return LEDs to green
    CircuitPlayground.setPixelColor(0, 0, 20, 0);
    CircuitPlayground.setPixelColor(9, 0, 20, 0);
    CircuitPlayground.setPixelColor(4, 0, 20, 0);
    CircuitPlayground.setPixelColor(5, 0, 20, 0);
  }

  if (CircuitPlayground.leftButton()) // Left button held down produces 2 sounds
  {
    CircuitPlayground.setPixelColor(1, 0, 0, 20); // make LED 1 blue
    CircuitPlayground.playTone((58 + sound), 100); // base sound 58 + sound
    CircuitPlayground.playTone((31 + sound), 100); // base sound 31 + sound
  }
  else CircuitPlayground.setPixelColor(1, 20, 0, 0); // return LED 1 to red

  // Right button held down produces one new sound.
  if (CircuitPlayground.rightButton()) {
    CircuitPlayground.playTone((25 + sound), 100); // Base sound is 25 + sound
    CircuitPlayground.setPixelColor(8, 0, 0, 20); // make LED 8 blue
  }
  else CircuitPlayground.setPixelColor(8, 20, 0, 0); // return LED 8 to red

  runServo(); // Call runServo
}

// this function captures motion and creates a value that acts as a multiplier for the pitch
int motionMulti (int)
{
  float movementX, movementY, movementZ, movement;

  movementX = abs(CircuitPlayground.motionX());  // read the X motion (absolute value)
  movementY = abs(CircuitPlayground.motionY());  // read the Y motion (absolute value)
  movementZ = abs(CircuitPlayground.motionZ());  // read the Z motion (absolute value)
  movement = movementX + movementY + movementZ;  // aggregate the movement sensed

  movement = map(movement, 8.0, 60.0, 3.0, 12.0); // times 3 to times 13 multiplier

  // LEDs 2, 3, 6 and 7 are default blue, turn yellow to white when motion is detected
  CircuitPlayground.setPixelColor(2, (3 * movement), (3 * movement), (18 - movement));
  CircuitPlayground.setPixelColor(3, (3 * movement), (3 * movement), (18 - movement));
  CircuitPlayground.setPixelColor(6, (3 * movement), (3 * movement), (18 - movement));
  CircuitPlayground.setPixelColor(7, (3 * movement), (3 * movement), (18 - movement));
  return movement;
}


// This function handles the servo's position on each loop.
void runServo ()
{

  if (dir == 0) // when in position 0, move to position 1
  {
    pos += 120;
    myservo.write(pos);
  }
  if (dir == 1) // when in position 1, move to position 0
  {
    pos -= 120;
    myservo.write(pos);
  }

  if (pos <= 120) dir = 1; // if Servo has moved to position 1, change "dir" to 1
  if (pos <= 0) dir = 0; // if Servo has moved to position 0, change "dir" to 0
}


 

 

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.