14 March 2021

NIME Project: Light Theremin

 

My NIME project involved creating a light theremin using the Circuit Playground Express' light sensor and speaker. I also intended to use a servo alongside the theremin's sound, but it interfered with the speed the theremin changed pitch. As an alternative plan, I decided to separate the theremin and the servo's function using the switch. The servo runs on it's own and moves in a semicircle back and forth very quickly. The potentiometer and the light sensor controls the pitch of the theremin. The pitch can only get low by reducing the light and turning down the potentiometer. The potentiometer also changes the intensity of the red LED on the inside of the box.

When mapping the analog inputs and outputs of the CPE, I used the Voltage Out pad to send 5V of electricity through the circuit. The CPE automatically uses analog output 0 for the speaker. Nothing else could use that pad without disrupting it. The potentiometer is connected to A6 and the servo is connected to A5. Finally, the switch is on the CPE itself, which is connected to digital input 7. The potentiometer and light sensor's analog values are mapped 1:1. This is shown by the LED on the inside that makes the inside of the box glow red when the potentiometer is maxed out and dims as you turn it.

How would you have designed the theramin? How would you go about setting up the wires on the box?

Circuit Schematic

#include <Adafruit_CircuitPlayground.h> // Adding the CPE functions to the mix
#include <Servo.h>

// These constants won't change. They're used to give names to the pins used:
const int analogInPin = A6;  // Analog input pin that the potentiometer is attached to
const int analogOutPin = 9; // Analog output pin that the LED is attached to
const int speakerOutPin = 12; // Analog output pin for the speaker. This uses the pre-installed speaker on CPE's A0.

int sensorValue = 0;        // value read from the pot
int outputValue = 0;        // value output to the PWM (analog out)
int pos = 0;                // servo base position

Servo myservo;  // create servo object to control a servo

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);

  CircuitPlayground.begin(); // Initializing the CPE library
  myservo.attach(2); //Attaches servo functionality to D2 (A5 on CPE)
}

void loop() {
  uint16_t lightValue, lightSound;
  
  if(CircuitPlayground.slideSwitch()) {
    lightValue = CircuitPlayground.lightSensor(); // Reading Light Sensor

    lightSound = map(lightValue, 5, 1000, 131, 1760); // mapping light values to musical tones
    // read the analog in value:
    sensorValue = analogRead(analogInPin);
    // map it to the range of the analog out:
    outputValue = map(sensorValue, 0, 1023, 0, 255);
    // change the analog out value:
    analogWrite(analogOutPin, outputValue);
    // call to the tone fxn
    tone(speakerOutPin, sensorValue + lightSound);
    // print the results to the Serial Monitor:
    Serial.print("sensor = ");
    Serial.print(sensorValue);
    Serial.print("\t output = ");
    Serial.println(outputValue);

    // wait 2 milliseconds before the next loop for the analog-to-digital
    // converter to settle after the last reading:
    delay(2);
  }
  else{
    noTone(0); // turn off the CPE's speaker
    for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
      // in steps of 1 degree
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(1);                       // waits 1ms for the servo to reach the position
    }
    for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(1);                       // waits 1ms for the servo to reach the position
    }
  }
}

 


No comments:

Post a Comment

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