2021-08-16
Arduino, Electronics, openFrameworks
laser + servo by openFrameworks + Arduino
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]
xxxxxxxxxx
float theta = 2*PI*(float)t/1023;
x, y
基本的には
xxxxxxxxxx
x = cos(x)
y = sin(y)
です. が, Arduinoのservoは90を中心に[0,180]で変化します. さらに, 2軸とも[0,180]で動かしてしまうと, 天球状のスクリーンが必要になります. 今回は垂直な壁にプロジェクションの予定だったので, x, yを[60, 120]に絞りました.
xxxxxxxxxx
float x = 60*(cos(theta)+1)/2 + 60;
float y = 60*(sin(theta)+1)/2 + 60;
codes
x#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;
}
}
}
}
}
xxxxxxxxxx
#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