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