Arduinoで可変抵抗を使ってProcessingに送る

# 可変抵抗
　まわすツマミです。おおよそ、300度回転させることができます。よくボリュームなどの調整に使われている部品です。ArduinoのAnalog端子で使うことができます。

# 使うもの
Arduino Uno
緑の基板（オリジナル）
可変抵抗（つまみ付き）A0に接続
USBケーブル
※可変抵抗は、グリグリすると、接点が瞬間外れやすいので、はんだで固定しています。


# 基板の取り付け
向きと位置を写真参考に差し込む。
Arduinoに端子の切れ目があるので、よく見てください。
![IMG_9707（大）.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/73824e8e-fd8d-339d-5eb2-50cc3567602e.jpeg)

# ボードとportの設定
Arduinoのメニュー＞ツール＞ボード＞Arduino Uno
Arduinoのメニュー＞ツール＞シリアルポート＞/cu.usbmodem14xxxx

# シリアルプロッタによる動作確認

```cpp:arduino
void setup() {
  pinMode(A0, INPUT);
  Serial.begin(9600);
}

void loop() {
  byte b = analogRead(A0)/4;
  if(true){// true or false
    Serial.println(b);
  }else{
    Serial.write(b);
  }
  delay(50);
}
```
Serial.println命令で送ったデータを、シリアルプロッタ（またはシリアルモニタ）で確認する。滑らかにグラフが変化していればOK。
analogRead命令では0~1023までの2^10=1024のデータを読み取ることができるが、この後で、Processingにデータを送る際に0~255の範囲になっていてほしいから、4で割っている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/910816f7-40ad-83fe-323d-c89b8fc0ab0f.png)

確認が終わったら、忘れずに、シリアルプロッタ（またはシリアルモニタ）を終了する。

# Processingへ送信

先のプログラムの```true```を```false```に変更する。この操作で、シリアルプロッタではなく、processingへデータを送信できるようになる。

受信側のProcessingのプログラムを示す。

```java:processing
import processing.serial.*;

Serial port;
float th;

void setup() {
  size(400,400);
  noFill();

  printArray(Serial.list());
  port = new Serial(this, Serial.list()[0], 9600);
}

void draw() {
  background(128);
  
  while (port.available() > 0) {
    th = port.read();
    println(th);
    text(th, 200, 200);
    th = -th*0.01;
  }
  
  translate(200,200);
  rotate(th);
  rect(-50,-50,100,100);
}
```
```Serial.list()[0]```ここの数字は、macの場合、1か2に変更する必要があります。

port busyとエラーになるときは、Arduinoのシリアルプロッタとシリアルモニタをそれぞれ開いて、閉じる、操作を行う。
データを受信していれば、可変抵抗の操作で、正方形が回転する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/146c5715-a112-a7a6-a1fc-cfc32ba617f4.png)

# Fisicaで何か作る

まずは、マウス操作で動くサンプル。
```java:processing
import fisica.*;

FWorld w;
FBox bar;
FCircle ball;

FCircle enemy;

void setup() {
  size(500, 1000);

  Fisica.init(this);
  w = new FWorld();
  w.setEdges();

  ball = addBall(250, 500);
  bar = addBlock(250, 600);
  enemy = addEnemy(250, 0);

  //重力
  w.setGravity(0, 200);
}

void draw() {
  background(255);
  float th;
  float x = bar.getX();
  th = (mouseX-250)*0.001;
  bar.setRotation(th);
  bar.setPosition(x+th*20.0, 600);
  
  enemy.setPosition(enemy.getX(), enemy.getY()+5);
  if(enemy.getY()>1000){
    enemy.setPosition(random(width), enemy.getY()-1000);
    
  }    

  w.step();
  w.step();
  w.draw();
}


FBox addBlock(int x, int y) {
  FBox b = new FBox(200, 30);//サイズ
  b.setPosition(x, y);      //位置
  b.setFill(0, 200, 200);   //色
  b.setStatic(true);        //固定
  b.setFriction(1);         //摩擦抵抗
  b.setRestitution(1);      //反発係数
  b.setName("block");       //名前
  w.add(b);
  return(b);
}

FCircle addBall(int x, int y) {
  FCircle c = new FCircle(60);//サイズ
  c.setPosition(x, y);      //位置
  c.setFill(0, 255, 255); //色
  c.setVelocity(0, 0); //速度
  c.setDamping(0.001);          //減衰（空気抵抗）
  c.setFriction(1);         //摩擦抵抗
  c.setRestitution(1);      //反発係数
  c.setName("ball");        //名前
  w.add(c);
  return(c);
}

FCircle addEnemy(int x, int y) {
  FCircle c = new FCircle(100);//サイズ
  c.setPosition(x, y);      //位置
  c.setFill(255, 255, 0); //色
  c.setVelocity(0, 0); //速度
  c.setStatic(true);        //固定
  c.setDamping(0.001);          //減衰（空気抵抗）
  c.setFriction(1);         //摩擦抵抗
  c.setRestitution(1);      //反発係数
  c.setName("enemy");        //名前
  w.add(c);
  return(c);
}

```

上から降ってくる、障害物を避ける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/b84e3289-8103-7578-6b1a-dc6872fc14d7.png)



## マウス操作のプログラムをArduino操作に修正する

```java:processing
import fisica.*;
import processing.serial.*;

Serial port;
FWorld w;
FBox bar;
FCircle ball;

FCircle enemy;

float data;

void setup() {
  size(500, 1000);
  printArray(Serial.list());
  port = new Serial(this, Serial.list()[0], 9600);
  
  Fisica.init(this);
  w = new FWorld();
  w.setEdges();

  ball = addBall(250, 500);
  bar = addBlock(250, 600);
  enemy = addEnemy(250, 0);

  //重力
  w.setGravity(0, 200);
}

void draw() {
  background(255);
  
  while (port.available() > 0) {
    data = port.read();
    data = 255-data;
  }
  float th;
  float x = bar.getX();
  th = (data-128)*0.002;
  bar.setRotation(th);
  bar.setPosition(x+th*20.0, 600);
  
  enemy.setPosition(enemy.getX(), enemy.getY()+5);
  if(enemy.getY()>1000){
    enemy.setPosition(random(width), enemy.getY()-1000);
    
  }    

  w.step();
  w.step();
  w.draw();
}


FBox addBlock(int x, int y) {
  FBox b = new FBox(200, 30);//サイズ
  b.setPosition(x, y);      //位置
  b.setFill(0, 200, 200);   //色
  b.setStatic(true);        //固定
  b.setFriction(1);         //摩擦抵抗
  b.setRestitution(1);      //反発係数
  b.setName("block");       //名前
  w.add(b);
  return(b);
}

FCircle addBall(int x, int y) {
  FCircle c = new FCircle(60);//サイズ
  c.setPosition(x, y);      //位置
  c.setFill(0, 255, 255); //色
  c.setVelocity(0, 0); //速度
  c.setDamping(0.001);          //減衰（空気抵抗）
  c.setFriction(1);         //摩擦抵抗
  c.setRestitution(1);      //反発係数
  c.setName("ball");        //名前
  w.add(c);
  return(c);
}

FCircle addEnemy(int x, int y) {
  FCircle c = new FCircle(100);//サイズ
  c.setPosition(x, y);      //位置
  c.setFill(255, 255, 0); //色
  c.setVelocity(0, 0); //速度
  c.setStatic(true);        //固定
  c.setDamping(0.001);          //減衰（空気抵抗）
  c.setFriction(1);         //摩擦抵抗
  c.setRestitution(1);      //反発係数
  c.setName("enemy");        //名前
  w.add(c);
  return(c);
}
```