センサーの値からサーボを動かす(OF編)

この前の投稿の続きです。
Arduinoでやってたのを、OFで動かしてみる。


ArduinoをUSB接続。
Arduinoを開いてスケッチの例→StandardFirmataを開く。
OFのFirmataExampleが動くか確認。
13番ピンに以下のようにつなげて、画面をクリックして光っていたらOK。
*後で写真のせます!

動いたらFirmataExampleを複製、名前を変更してmyAppsに移動。
この前のArduinoで書いた内容をOF用に変更します。
testApp.h
[cpp]
#pragma once

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

class testApp : public ofBaseApp{

public:

void setup();
void update();
void draw();

void keyPressed(int key);
void keyReleased(int key);

void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);

ofTrueTypeFont font;
ofTrueTypeFont smallFont;
ofArduino ard;
bool bSetupArduino;

/*gui*/
ofxPanel gui;
ofxVec2Slider position;

private:

void setupArduino(const int & version);
void digitalPinChanged(const int & pinNum);
void analogPinChanged(const int & pinNum);
void updateArduino();

string buttonState;
string potValue;

};

[/cpp]

testApp.cpp
[cpp]
#include "testApp.h"

//落ちまくるのをどうにかしないと使い物にならない

int swi,cou;
int a;

//--------------------------------------------------------------
void testApp::setup(){
ofSetVerticalSync(true);
ofSetFrameRate(30);
ofBackground(0);
ofSetRectMode(OF_RECTMODE_CENTER);

/*arduino*/
buttonState = "digital pin:";
potValue = "analog pin:";

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

ard.connect("/dev/tty.usbmodemfa131", 57600);
// ard.connect("/dev/tty.usbserial-A900ceWs", 57600);

ofAddListener(ard.EInitialized, this, &testApp::setupArduino);
bSetupArduino = false;

/*gui*/
//position
ofVec2f initPos = ofVec2f(ofGetWidth()/2, ofGetHeight()/2);
ofVec2f minPos = ofVec2f(0, 0);
ofVec2f maxPos = ofVec2f(ofGetWidth(), ofGetHeight());

gui.setup();
gui.add(position.setup("position", initPos, minPos, maxPos));

swi = 0;
cou = 0;

a = 300;
}

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

updateArduino();

}

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

ofRemoveListener(ard.EInitialized, this, &testApp::setupArduino);
bSetupArduino = true;
ofLogNotice() << ard.getFirmwareName();
ofLogNotice() << "firmata v" << ard.getMajorFirmwareVersion()
<< "." << ard.getMinorFirmwareVersion();

ard.sendDigitalPinMode(13, ARD_OUTPUT);
ard.sendAnalogPinReporting(0, ARD_ANALOG);
ard.sendAnalogPinReporting(5, ARD_ANALOG);

//角度のパラメータはFirmata2.2で非推奨らしい
ard.sendServoAttach(9, 955, 2000, 360); //int pin, int minPulse, int maxPulse, int angle

ofAddListener(ard.EDigitalPinChanged, this, &testApp::digitalPinChanged);
ofAddListener(ard.EAnalogPinChanged, this, &testApp::analogPinChanged);

}

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

ard.update();

}

//--------------------------------------------------------------
void testApp::digitalPinChanged(const int & pinNum) {

}

//--------------------------------------------------------------
void testApp::analogPinChanged(const int & pinNum) {

}

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

//1.56sec for 360 deg
//16deg per 10

int sensor0 = ard.getAnalog(0);
int sensor5 = ard.getAnalog(5);

ofPushMatrix();
ofTranslate(ofGetWidth()/2, ofGetHeight()/2);

//②センサーが一定以上になったら、一度だけ回転
if(swi == 0){ //回転中でない
cou = 0;
ofSetColor(255, 0, 0);

if (sensor0 > a) { //a以上で反応する
swi = 1;
}
if (sensor5 > a) { //a以上で反応する
swi = 2;
}
}

if(swi == 1){ //回転中
ard.sendServo(9, 1500); //180°くらい 180° = 1477.5
ofRotateZ(180);
ofSetColor(255, 200, 0);
}

cou ++ ;
if (cou > 200){
swi = 3; //回転終了
}

if(swi == 2){ //回転中
ard.sendServo(9, 955); //0° 90° = 955
ofRotateZ(0);
ofSetColor(255, 255, 200);

}

cou ++ ;
if (cou > 200){
swi = 3; //回転終了
}

if(swi == 3){ //回転終了中
// ard.sendServo(9, 1200); //90°くらい 確認用
ofSetColor(255, 255, 255);
cou = 0;

if (sensor0 < a && sensor5 < a) { //a以下で回転終了
swi = 0;
}
}

// //①センサーの値がa以上になったら180°、a以下のときは0°
// if (sensor0 > a) {
// ard.sendServo(9, 1500); //180°
// ofRotateZ(180);
// ofSetColor(222, 59, 9);
// }
//
// if (sensor0< a) {
// ard.sendServo(9, 955); //0°
// ofRotateZ(0);
// ofSetColor(255, 255, 255);
// }

//Rect
ofRect(0, 0, 400, 400);
ofPopMatrix();

ofSetColor(255, 255, 255);
if (!bSetupArduino){
font.drawString("arduino not ready...n", 515, 40);
}

// 全てのAnalog Inの値をメッセージ出力
if (bSetupArduino){
string msg = "";
for (int i = 0; i < 6; i++) {
msg += "Analog IN " + ofToString(i, 0)
+ " : " + ofToString(ard.getAnalog(i), 0) + "n";
}
ofSetColor(255, 255, 255);
ofDrawBitmapString(msg, 20, ofGetHeight()-100);

//servo1
int servo1 = ard.getServo(9);
cout << "servo1 =" << servo1 << endl;
smallFont.drawString("servo1 =" + ofToString(servo1), ofGetWidth()-200, 40);

//switch
cout << "switch1 =" << swi << endl;
smallFont.drawString("swi =" + ofToString(swi), ofGetWidth()-200, 80);

}

// GUIを表示
gui.draw();

}

//--------------------------------------------------------------
void testApp::keyPressed (int key){

if(key == 'f'){
ofSetFullscreen(true);
}

}

//--------------------------------------------------------------
void testApp::keyReleased(int key){

}

//--------------------------------------------------------------
void testApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){
// turn on the onboard LED when the application window is clicked
ard.sendDigital(13, ARD_HIGH);
}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){
// turn off the onboard LED when the application window is clicked
ard.sendDigital(13, ARD_LOW);
}

//--------------------------------------------------------------
void testApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void testApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void testApp::dragEvent(ofDragInfo dragInfo){

}
[/cpp]

予想通りの動きに出来ました。
cou(カウント)がOFではArduinoと違って、値が自動でリセットされないようなので、swi= 0の時と swi = 3のときはリセットされて0になるように、Arduinoのスケッチから変更して追加しました。

次回はサーボを増やしてみようと思います。

コメントを残す

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

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください