This is code used to control the playback speed of a video playing in Quicktime Player. Upload arduino_read_potentiometer.cpp on your Arduino and run processing_control_video.pde in Processing. See video demo at http://www.youtube.com/watch?v=UfDRINiV4Kg
Created
April 21, 2013 17:56
-
-
Save ryangreenberg/5430440 to your computer and use it in GitHub Desktop.
Potentiometer video control
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Potentiometer Passing | |
* by Ryan Greenberg | |
* 23 September 2009 | |
* | |
* This program gets the value of two potentiometers connected to analog inputs | |
* and writes their values to serial for Processing to receive. These pots | |
* control video playback speed and volume. A blinking LED matches the | |
* tempo and volume of the video. | |
*/ | |
int ledPin = 10; // select the output pin for LED | |
int spdPin = 2; // select the input pin for the speed pot | |
int volPin = 3; // select the input pin for the volume pot | |
int spd = 0; // variable to store the speed value coming from the pot | |
int vol = 0; // variable to store the volume value coming from the pot | |
int bpm = 194; // Speed of song in beats per minute, at 100% speed | |
// Calculate the BPM of a song manually at | |
// http://www.all8.com/tools/bpm.htm | |
float beatPeriod; // ms to wait between flashes | |
float beatMultiplier = 1.0; // number from -1 to 3 to multiply base bpm | |
long nextBeat; // time of next flash toggle | |
int beatOn = 0; | |
int pollPeriod = 1000; // ms to wait between polls | |
long nextPoll; // time of next poll | |
void setup() { | |
pinMode(ledPin, OUTPUT); // declare the ledPin as an OUTPUT | |
nextPoll = millis() + pollPeriod; | |
nextBeat = millis() + beatPeriod; | |
setBeatPeriod(); | |
Serial.begin(9600); | |
} | |
void loop() { | |
// Flash light to the beat | |
if (millis() >= nextBeat) { | |
toggleBeat(); | |
} | |
// Read changes to the beat | |
if (millis() >= nextPoll) { | |
pollPot(); | |
} | |
} | |
void toggleBeat() { | |
nextBeat = millis() + beatPeriod; | |
if (beatOn == 1) { | |
digitalWrite(ledPin, LOW); // turn the ledPin off | |
beatOn = 0; | |
} else { | |
analogWrite(ledPin, vol / 1024.0 * 255); | |
// digitalWrite(ledPin, HIGH); // turn the ledPin on | |
beatOn = 1; | |
} | |
} | |
// An unfortunately named function | |
void pollPot() { | |
nextPoll = millis() + pollPeriod; // set time for next reading | |
spd = analogRead(spdPin); // read the speed | |
vol = analogRead(volPin); // read the volume | |
Serial.print("S"); // Send value to Processing | |
Serial.println(spd); | |
Serial.print("V"); | |
Serial.println(vol); | |
beatMultiplier = spd/1023.0 * 4 - 1; | |
setBeatPeriod(); | |
} | |
// Calculate the flash period from the bpm frequency | |
void setBeatPeriod(){ | |
float oldBeatPeriod = beatPeriod; | |
// Avoid divide by zero error | |
if (beatMultiplier == 0) { | |
beatPeriod = 1000000; // Big enough | |
} else { | |
beatPeriod = abs((1.0 / (bpm * 2 * beatMultiplier / 60.0) * 1000)); | |
} | |
nextBeat = nextBeat - oldBeatPeriod + beatPeriod; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Arduino Movie Player | |
* ---------------------- | |
* | |
* Receives speed and volume values over the serial port, | |
* terminated with a carriage return (ascii 13) then newline (10). | |
* | |
* This matches what Arduino's " Serial.println(val)" function | |
* puts out. | |
* | |
* Created 25 October 2006 | |
* copyleft 2006 Tod E. Kurt <[email protected] | |
* http://todbot.com/ | |
* | |
* Modified 21 September 2009 by Ryan Greenberg | |
* | |
*/ | |
import processing.serial.*; | |
import com.apple.cocoa.foundation.*; // Only works on OS X with the proper libraries installed | |
//import processing.video.*; // Too slow | |
// Change this to the portname your Arduino board | |
String portname = "/dev/tty.usbserial-A7006RZH"; // or "COM5" | |
Serial port; | |
String buf=""; | |
int cr = 13; // ASCII return == 13 | |
int lf = 10; // ASCII linefeed == 10 | |
int potVal; | |
int count = 0; | |
int col = 255; | |
float currentPlaySpeed = 1.0; | |
float currentVolume = 1.0; | |
//Movie myMovie; | |
void setup() { | |
port = new Serial(this, portname, 9600); | |
setupMovie(); | |
size(100,100); | |
} | |
void keyPressed() { | |
if(key == ' ') { | |
background(255,0,0); // erase screen | |
} | |
} | |
void setupMovie() { | |
println("Setting up movie..."); | |
// Play currently open movie in QuickTime Player | |
String script = "tell application \"QuickTime Player\" to play first document"; | |
executeScript(script); | |
setVolume(7); // Start with volume turned all the way up | |
delay(1500); // Wait for movie to start playing | |
} | |
void draw() { | |
// Offer some visual feedback of the current pot value | |
// Mostly for debugging | |
background(col); | |
} | |
void setMovieSpeed(float s) { | |
float diff = abs(currentPlaySpeed - s); | |
println("Current: " + currentPlaySpeed + " Requested: " + s + " Diff: " + diff); | |
if (diff < .15) { | |
println("Not changing speed because change is insignificant"); | |
} else { | |
println("Changing speed to " + s); | |
String script = "tell application \"QuickTime Player\" to set rate of first document to " + s; | |
executeScript(script); | |
currentPlaySpeed = s; | |
} | |
} | |
void setVolume(float v) { | |
float diff = abs(currentVolume - v); | |
println("Current: " + currentVolume + " Requested: " + v + " Diff: " + diff); | |
if (diff < .15) { | |
println("Not changing volume because change is insignificant"); | |
} else { | |
String script = "tell application \"Finder\" to set volume " + v; | |
executeScript(script); | |
currentVolume = v; | |
} | |
} | |
// called whenever serial data arrives | |
void serialEvent(Serial p) { | |
int c = port.read(); | |
// Add string to buffer if not end of line | |
if (c != lf && c != cr) { | |
buf += char(c); | |
} | |
if (c == lf) { | |
if (buf.charAt(0) == 'S') { | |
println("Got value for speed..."); | |
int val = int(buf.substring(1)); | |
float playSpeed = (val / 1023.0 * 4.0)-1; | |
setMovieSpeed(playSpeed); | |
col = (int)(val / 1023.0 * 255); | |
} else if (buf.charAt(0) == 'V') { | |
println("Got value for volume..."); | |
int val = int(buf.substring(1)); | |
float volume = (val / 1023.0 * 7); | |
setVolume(volume); | |
println("Setting volume to " + val); | |
} | |
buf = ""; // Clear buffer | |
} | |
} | |
// Used to run AppleScript | |
// Only works on MacOS computers | |
void executeScript(String script) { | |
NSAppleScript myScript = new NSAppleScript(script); | |
NSMutableDictionary errors = new NSMutableDictionary(); | |
myScript.execute(errors); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment