Edited at

laser + servo by openFrameworks + Arduino

More than 1 year has passed since last update.

laser + servo by openFrameworks + Arduino

です.

thetaを変数としてparametric plotをArduinoと連携してやってみようというもの.

データの送信方法はserial通信:

http://qiita.com/keitasumiya/items/44908da606c8da1a635c

です.


variables


t

t ∈ [0,1023] で単調増加.

境界条件としてt>1023でt=0にしています.

if (t > 1023){

t = 0;
}


theta

theta ∈ [0, 2 pi]

float theta = 2*PI*(float)t/1023;


x, y

基本的には

x = cos(x)

y = sin(y)

です.

が, Arduinoのservoは90を中心に[0,180]で変化します.

さらに, 2軸とも[0,180]で動かしてしまうと, 天球状のスクリーンが必要になります.

今回は垂直な壁にプロジェクションの予定だったので, x, yを[60, 120]に絞りました.

float x = 60*(cos(theta)+1)/2 + 60;

float y = 60*(sin(theta)+1)/2 + 60;


codes


serial_read_2-2bytes_servo.ino

#include <Servo.h>

const int val_size = 2;
int values[val_size] = {0, 0};
bool isValids[val_size] = {false, false};
const int OUT_PINs[val_size] = {5, 3};
Servo myservos[val_size];

void setup(){
Serial.begin(115200);
myservos[0].attach(OUT_PINs[0]);
myservos[1].attach(OUT_PINs[1]);

}

void loop(){
bool isValids[val_size] = {false, false};
if (Serial.available() >= 3*val_size) {
int head = Serial.read();
for (int i=0; i<val_size; i++){
if (head == 128+i) {
int high = Serial.read();
int low = Serial.read();
values[i] = (high<<7) + low;
if (0 <= values[i] <= 1023) {
myservos[i].write(values[i]);
isValids[i] = true;
}
}
}
}
}



serial_write_multi-2bytes_change_servo/src/ofApp.cpp

#include "ofApp.h"


ofSerial mySerial;
const int val_size = 2;
int values[val_size] = {0, 0};
bool isValids[val_size] = {false, false};
int t = 0;

//--------------------------------------------------------------
void ofApp::setup(){
ofSetFrameRate(120);
mySerial.setup("/dev/cu.usbmodem1421",115200);
}

//--------------------------------------------------------------
void ofApp::update(){
t += 4;
if (t > 1023){
t = 0;
}
float theta = 2*PI*(float)t/1023;
float x = 60*(cos(theta)+1)/2 + 60;
float y = 60*(sin(theta)+1)/2 + 60;
values[0] = round(x);
values[1] = round(y);

bool isValids[val_size] = {false, false};
for (int i=0; i<val_size; i++){
int high = (values[i] >> 7) & 127;
int low = values[i] & 127;
bool byteWasWritten1 = mySerial.writeByte(128+i);
bool byteWasWritten2 = mySerial.writeByte(high);
bool byteWasWritten3 = mySerial.writeByte(low);
if ( byteWasWritten1 && byteWasWritten2 && byteWasWritten3 ) {
printf("value is %d \n", values[i]);
isValids[i] = true;
} else {
printf("an error occurred \n");
}
}
}



results

動画:

こんな感じです.

https://youtu.be/xR1X-ubHmPs

Anisotropic Kepler problem(AKP)で軌道を書いてみた例もあります

https://youtu.be/40Fag5gq5fU