ofVideoPlayer + potentiometer

Hello,

I would like to map the reading from a potentiometer with a video on how the video is going to be played.
My scenario is when user turn the potentiometer, it will direct them to different “part” of the video. For instance if the potentiometer gets reading of 100 out of 1023, it will get a roughly frame of 10% of the video (which is around 00:01:00).

I am trying to use setFrame() for this, and my code is as below.
However the value never returns to 0 when it is supposed to be 0 and the video I am playing is stuttering a lot. May someone please tell me if I am doing it in a correct way please?

Cheers!

My ofApp.h:

#pragma once

#include "ofMain.h"
#include "ofEvents.h"

class ofApp : public ofBaseApp{

public:
    void setup();
    void update();
    void draw();

    ofImage				bgImage;
    ofTrueTypeFont		font;
    ofTrueTypeFont      smallFont;

    ofArduino ard;
    bool bSetupArduino;

    ofVideoPlayer player;
    void playerPlay();    
    float videoPlay; 

private:

    void setupArduino(const int & version);
    void digitalPinChanged(const int & pinNum);
    void analogPinChanged(const int & pinNum);
    void updateArduino();
    void getAverage(); // average the incoming readings from the arduino

    vector<int> allReadings; //store all readings in a vector
    float smoothReading; //smoothed reading after averaging

    int ardReading; //raw reading from arduino

   string potValue;

};

My ofApp.cpp is:

#include "ofApp.h"
#include <iostream>

//--------------------------------------------------------------
void ofApp::setup(){

ofSetVerticalSync(true);
ofSetFrameRate(60);
ofBackground(255,255,255);

font.loadFont("franklinGothic.otf", 20);
smallFont.loadFont("franklinGothic.otf", 14);

string movie = "plateCHartTest2.mov";
player.loadMovie(movie);

potValue = "analog pin:";

//connect to arduino
ard.connect("/dev/tty.usbmodem1421", 57600);

// listen for arduino to be ready. when it is ready, call setupArduino() function
ofAddListener(ard.EInitialized, this, &ofApp::setupArduino);
bSetupArduino	= false;	// flag so we setup arduino when its ready, you don't need to touch this :)

}

//--------------------------------------------------------------
void ofApp::update(){

updateArduino();
getAverage();

}

//--------------------------------------------------------------
void ofApp::getAverage(){
float sum = 0.;
//set initial values to make sure they will be replaced by the incoming readings
float highest = 0.;
float lowest = 1000.;

//replace dummy highest and lowest readings with actual readings from within the vector of allReadings
for(int i = 0; i < allReadings.size(); i++){
    sum += allReadings[i];
    if(allReadings[i] < lowest){
        lowest = allReadings[i];
    }
    if(allReadings[i] > highest){
        highest = allReadings[i];
    }
}

//for loop through noiseObjects vector, if diff > that object.resistance, then do something to the object

smoothReading = sum / allReadings.size();
cout << "smoothed reading: " << smoothReading << endl;
}

//--------------------------------------------------------------
void ofApp::setupArduino(const int & version) {

// remove listener because we don't need it anymore
ofRemoveListener(ard.EInitialized, this, &ofApp::setupArduino);

// it is now safe to send commands to the Arduino
bSetupArduino = true;

// print firmware name and version to the console
ofLogNotice() << ard.getFirmwareName();
ofLogNotice() << "firmata v" << ard.getMajorFirmwareVersion() << "." << ard.getMinorFirmwareVersion();

// set pin A0 to analog input
ard.sendAnalogPinReporting(0, ARD_ANALOG);

// Listen for changes on the digital and analog pins
ofAddListener(ard.EAnalogPinChanged, this, &ofApp::analogPinChanged);
}

//--------------------------------------------------------------
void ofApp::updateArduino(){

// update the arduino, get any data or messages:
ard.update();
cout << ard.getAnalog(0) << endl;
}
//--------------------------------------------------------------
void ofApp::analogPinChanged(const int & pinNum) {
// do something with the analog input. here we're simply going to print the pin number and
// value to the screen each time it changes

ardReading = ard.getAnalog(pinNum);

potValue = "analog pin: " + ofToString(pinNum) + " = " + ofToString(ardReading);

allReadings.push_back(ardReading);

//if the allReadings vector > 5, erase the oldest reading
//play around with vector size to change sensitivity
if(allReadings.size() > 8){
    allReadings.erase(allReadings.begin());
    }
}

//--------------------------------------------------------------
void ofApp::playerPlay(){

float videoLength = player.getTotalNumFrames();

player.play();
videoPlay = ofMap(smoothReading, 0 , 1023, 0 ,videoLength);
cout << "sensor value : " << smoothReading << endl;
cout << "output value : " << videoPlay << endl;
player.setFrame(videoPlay);

player.draw(0,0);
player.update();
cout << "draw video" << endl;

}

//--------------------------------------------------------------
void ofApp::draw(){

playerPlay();

}

Hi, a few ideas come to mind …

  1. I would be more inclined to monitor the Arduino output inside an ofThread. This will allow you to: poll for a result, stop the thread once a new result is available, set the new start frame, play the video, then poll for the new results again, without the worry of the main update() and draw() loops

  2. The player.play() method only needs to be called once. You’re calling this repeatedly since the playerPlay() method is being called on the draw().

  3. Because you’re attempting to set the frame inside the playerPlay() method, and read the value of the Arduino every frame, the playback will reset to the last potentiometer value, which is possibly causing the stuttering.

  4. In the past I’ve found the results I receive from a potentiometer are never exactly 0 - 127. You may need to configure the pot to get the ranges, and possibly identify a fluctuation range you can use, so that when you want the pot == 0, then the real values are actually in a range [0-10]

References:

http://openframeworks.cc/documentation/video/ofVideoPlayer.html
http://openframeworks.cc/documentation/utils/ofThread.html

Hello, thank you very much for your reply and suggestions.
I have modified my code and part of the stuttering was caused because of my potentiometer where their legs are not well wired!

I have too modified my code and not trying to grab an average reading but just raw reading from Arduino:

void ofApp::playerPlay(){

float videoLength = player.getTotalNumFrames();

player.play();
videoPlay = ofMap(ardReading, 0 , 1023, 0 ,videoLength);

cout << "sensor value : " << ardReading << endl;
cout << "output value : " << videoPlay << endl;
player.setFrame(videoPlay);

player.draw(0,0);
player.update();
cout << "draw video" << endl;

}