Processing × スクーミー ⑫~動画の再生~【Python】

~距離センサーの値の変化で動画が再生される~

距離センサーに手を近づけると、動画が再生されます!

スケッチ保存先の名称変更(Windowsのみ)

Windowsの場合、初期設定では一般的に「C:\Users\user_name\OneDrive\ドキュメント」にスケッチ(プログラム)ファイルが保存される設定になっていますが、「ドキュメント」の様に全角カナ文字を含む保存先名が指定されている場合、プログラムを実行する事が出来ないため、保存先の設定変更をする必要があります。

①processingを起動して、「ファイル」⇒「設定」を開きます。

②「スケッチブックの場所」欄の「ドキュメント」を「Documents」に書き換えて「OK」ボタンを押します。

動画ファイルの準備

使用する動画ファイルをプログラム画面上にドラック&ドロップして、プログラムファイル内に動画ファイルを配置します。

「1個のファイルがスケッチに追加されました。」と表示されたらアップロード成功です。


プログラム65行目の”movie.mp4″の部分を上で指定したファイル名(拡張子含む)になるように変更してください。

※PC内の任意の場所にある場所にある動画ファイルを使用したい場合は、”movie.mp4″の部分を動画ファイルのパス(path)に変更してください。

使用するセンサーと取付位置

左上:距離センサー

距離センサーを使用するため、スクーミーIDEのプログラムの9行目でsensorTypeを9にしてください。

Pythonモードの追加

ProcessingでPythonを使うためには、Pythonモードがインストールされている必要があります。

Pythonモードが追加されていない場合、「ツール」→「ツールを追加」→「Modes」から「Python Mode for Processing 3」をインストールしてください。

Videoライブラリの追加

動画を再生するには、Videoライブラリを追加する必要があります。

「ツール」→「ツールを追加」→「Libraries」から「Video Library for Processing 3」をインストールしてください。

センサーの値の受け取りと条件分岐について

距離センサーの値が10以下になると動画が再生されます。

※ 距離センサーの値10はプログラムの11行目で指定しているtriggerValueの値 

playModeについて

ProcessingIDEのプログラムの15行目のplayModeを変更することで、動画の再生・停止方法が変わります。

playModeが1の場合:
距離センサーの値が10以下になると、動画が再生されます。


playModeが2の場合:
距離センサーの値が10以下になると、動画が再生されます。
距離センサーの値が10以上になると、動画が一時停止されます。
動画が一時停止されている状態で距離センサーの値が10以下になると、動画が最初から再生されます。

playModeが3の場合:
距離センサーの値が10以下になると、動画が再生されます。
距離センサーの値が10以上になると、動画が一時停止されます。
動画が一時停止されている状態で距離センサーの値が10以下になると、動画の続きが再生されます。

動画の繰り返し再生について

ProcessingIDEのプログラムの20行目のisLoopを変更することで、動画が繰り返し再生されるかどうかが変わります。

Trueの場合:
動画が繰り返し再生されます。

Falseの場合:
動画が一度だけ再生されます。

スクーミーIDEのコード

#include <SchooMyUtilities.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>

SchooMyUtilities scmUtils = SchooMyUtilities();

/************ sensorTypeの種類 ************/
int sensorType = 9;
// 1: タッチセンサー
// 2: 明るさセンサー
// 3: 磁気センサー
// 4: 通過センサー(プッシュスイッチも可)
// 5: 音センサー
// 6: 土壌水分センサー
// 7: 温度センサー
// 8: 加速度センサー
// 9: 距離センサー

/************ 特定のセンサーで必要な関数 ************/
float _sbeGetLux(int pinNumber, int res, float vol) {
  pinMode(pinNumber, INPUT);
  float cds_ad = analogRead(pinNumber);
  float cds_v = cds_ad * vol / res;
  float v_res = vol - cds_v;
  if (v_res < 0.01) {
    v_res = 0.01;
  }
  return 10000 * cds_v / v_res / 1000;
}

unsigned long distanceTimeOut = 100000;
float _sbeGetDistanceUsingDistanceSensor(int trigPin, int echoPin) {
  long distance = 0;
  long duration = 0;

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH, distanceTimeOut);
  if (duration > 0) {
    distance = duration / 2 * 340 * 100 / 1000000;
  }
  return distance;
}

float _sbeGetValOfMoisture(int pinNumber) {
  pinMode(pinNumber, INPUT);
  float moisture_ad = analogRead(pinNumber);
  return moisture_ad;
}

#define SENSOR_BIT 9
OneWire oneWire_19(19);
DallasTemperature sensors_19(&oneWire_19);
float _sbeGetTemperature_19() {  
  sensors_19.requestTemperatures();  
  return sensors_19.getTempCByIndex(0);
}

int MPU6050_ADDR = 0x68;
#define MPU6050_SMPLRT_DIV   0x19
#define MPU6050_CONFIG       0x1a
#define MPU6050_GYRO_CONFIG  0x1b
#define MPU6050_ACCEL_CONFIG 0x1c
#define MPU6050_PWR_MGMT_1   0x6b
int16_t raw_acc_x, raw_acc_y, raw_acc_z, raw_t, raw_gyro_x, raw_gyro_y, raw_gyro_z ;
float acc_x, acc_y, acc_z, acc_angle_x, acc_angle_y;
float absAccelerometer;
double gyro_angle_x = 0, gyro_angle_y = 0, gyro_angle_z = 0;
float interval, preInterval;
double offsetX = 0, offsetY = 0, offsetZ = 0;
float angleX, angleY, angleZ;
float dpsX, dpsY, dpsZ;
double init_angleX = 0, init_angleY = 0, init_angleZ = 0;
volatile float rel_angleX, rel_angleY, rel_angleZ;
void AcceleroMeterWireRead() {
  Wire.beginTransmission(MPU6050_ADDR);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);
  Wire.beginTransmission(MPU6050_ADDR);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU6050_ADDR, 14, true);
  raw_acc_x = Wire.read() << 8 | Wire.read();
  raw_acc_y = Wire.read() << 8 | Wire.read();
  raw_acc_z = Wire.read() << 8 | Wire.read();
  raw_t = Wire.read() << 8 | Wire.read();
  raw_gyro_x = Wire.read() << 8 | Wire.read();
  raw_gyro_y = Wire.read() << 8 | Wire.read();
  raw_gyro_z = Wire.read() << 8 | Wire.read();
}
void AcceleroMeterAddressSetup() {
  byte error, address;
  int nDevices = 0;
  for(address = 1; address < 127; address++ ) {
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
    if (error == 0) {
      if (address<16)MPU6050_ADDR = address;
      nDevices++;
    }
  }
}
void writeMPU6050(byte reg, byte data) {
  Wire.beginTransmission(MPU6050_ADDR);
  Wire.write(reg);
  Wire.write(data);
  Wire.endTransmission();
}
void AcceleroMeterAngleSetup() {
  AcceleroMeterAddressSetup();
  AcceleroMeterWireRead();
  writeMPU6050(MPU6050_SMPLRT_DIV, 0x00);
  writeMPU6050(MPU6050_CONFIG, 0x00);
  writeMPU6050(MPU6050_GYRO_CONFIG, 0x08);
  writeMPU6050(MPU6050_ACCEL_CONFIG, 0x00);
  writeMPU6050(MPU6050_PWR_MGMT_1, 0x01);
  Serial.print("Calculate Calibration");
  for (int i = 0; i < 3000; i++) {
    AcceleroMeterWireRead();
    dpsX = ((float)raw_gyro_x) / 65.5;
    dpsY = ((float)raw_gyro_y) / 65.5;
    dpsZ = ((float)raw_gyro_z) / 65.5;
    offsetX += dpsX;
    offsetY += dpsY;
    offsetZ += dpsZ;
    if (i % 1000 == 0) {
      Serial.print(".");
    }
  }
  Serial.println();
  offsetX /= 3000;
  offsetY /= 3000;
  offsetZ /= 3000;
  Serial.print("Calculate Rotation");
  for (int i = 0; i < 1000; i++) {
    calcRotation();
    if (i % 1000 == 0) {
      Serial.print(".");
    }
  }
  Serial.println();
  init_angleX = angleX;
  init_angleY = angleY;
  init_angleZ = angleZ;
}
void calcRotation() {
  acc_x = ((float)raw_acc_x) / 16384.0;
  acc_y = ((float)raw_acc_y) / 16384.0;
  acc_z = ((float)raw_acc_z) / 16384.0;
  acc_angle_y = atan2(acc_x, acc_z + abs(acc_y)) * 360 / -2.0 / PI;
  acc_angle_x = atan2(acc_y, acc_z + abs(acc_x)) * 360 / 2.0 / PI;
  dpsX = ((float)raw_gyro_x) / 65.5;
  dpsY = ((float)raw_gyro_y) / 65.5;
  dpsZ = ((float)raw_gyro_z) / 65.5;
  interval = millis() - preInterval;
  preInterval = millis();
  gyro_angle_x += (dpsX - offsetX) * (interval * 0.001);
  gyro_angle_y += (dpsY - offsetY) * (interval * 0.001);
  gyro_angle_z += (dpsZ - offsetZ) * (interval * 0.001);
  angleX = (0.996 * gyro_angle_x) + (0.004 * acc_angle_x);
  angleY = (0.996 * gyro_angle_y) + (0.004 * acc_angle_y);
  angleZ = gyro_angle_z;
  gyro_angle_x = angleX;
  gyro_angle_y = angleY;
  gyro_angle_z = angleZ;
  rel_angleX = init_angleX - angleX;
  rel_angleY = init_angleY - angleY;
  rel_angleZ = init_angleZ - angleZ;
}
float relativeAngleX() {
  AcceleroMeterWireRead();
  calcRotation();
  return rel_angleX;
}

/***************************************************************/

/************ 各センサーの関数 ************/
void touchSensor() {
  Serial.write(digitalRead(19));
}

void brightnessSensor() {
  Serial.write(int(_sbeGetLux(A5, 1023, 5)));
}

void magneticSensor() {
  Serial.write(analogRead(A5));
}

void passingSensor() {
  Serial.write(!digitalRead(19));
}

void soundSensor() {
  scmUtils.soundSensorBegin(A5);
  Serial.write(scmUtils.soundSensorPlotterAnalogRead(A5));
}

void soilMoistureSensor() {
  Serial.write(int(_sbeGetValOfMoisture(A5)));
}

void temperatureSensor() {
  sensors_19.setResolution(SENSOR_BIT);
  Serial.write(int(_sbeGetTemperature_19()));
}

void accelerationSensor() {
  Serial.write(int(relativeAngleX()));
}

void distanceSensor() {
  Serial.write((byte)_sbeGetDistanceUsingDistanceSensor(18 , 19));
}

/***************************************************************/

void changeSensorType(int type) {
    switch(type) {
        case 1:
            touchSensor();
            break;
        case 2:
            brightnessSensor();
            break;
        case 3:
            magneticSensor();
            break;
        case 4:
            passingSensor();
            break;
        case 5:
            soundSensor();
            break;
        case 6:
            soilMoistureSensor();
            break;
        case 7:
            temperatureSensor();
            break;
        case 8:
            accelerationSensor();
            break;
        case 9:
            distanceSensor();
            break;
    }
}

void setup() {
  Serial.begin(9600);
  pinMode(19, INPUT);
  if(sensorType==8){
    Wire.begin();
    AcceleroMeterAngleSetup();
  }
}

void loop() {
    changeSensorType(sensorType);
}

ProcessingIDEのコード

add_library('serial')
try:
    add_library("video")
except:
    from processing.video import Movie

myPort = None
available_serialport = 2
arduinoPort = Serial.list()[available_serialport]
sensingValue = 100
triggerValue = 10
isPlaying = False
valueStatus = True

playMode = 1
# 1: Play to the end
# 2: Playback from the beginning when approaching after moving away
# 3: Playback from the middle when approaching after moving away

isLoop = True
# True: Loop playback
# False: Play only once

def playMode_1():
    global isPlaying, isLoop
    if sensingValue < triggerValue or isPlaying:
        if isLoop:
            loopVideo()
            isPlaying = True
        else:
            mv.play()

def playMode_2():
    global isLoop
    if sensingValue < triggerValue :
        if isLoop:
            loopVideo()
        else:
            mv.play()
    else:
        mv.pause()
        mv.jump(0)
        
def playMode_3():
    global isLoop
    if sensingValue < triggerValue:
        if isLoop:
            loopVideo()
        else:
            mv.play()
    else:
        mv.pause()
        
def loopVideo():
    if mv.time() >= mv.duration():
        mv.jump(0)
        mv.play()
    else:
        mv.play()
        
def setup():
    global myPort, mv
    size(1200, 700)
    myPort = Serial(this, arduinoPort, 9600)
    mv = Movie(this, "movie.mp4")
    
def draw():
    if playMode == 1:
        playMode_1()
    elif playMode == 2:
        playMode_2()
    elif playMode == 3:
        playMode_3()
        
    if mv.available():
        mv.read()
        
    background(255)
    image(mv, 0, 0)
    
def serialEvent(myPort):
    global sensingValue
    if myPort.available() > 0:
        sensingValue = int(myPort.read())
        println(sensingValue)
キャロット
キャロット

このページのHelloNoは、050012 です!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です