日常の進捗

主に自分のための,行為とその習慣化の記録

Arduinoで複数台のサーボモーターを動かす

今まではArduino富豪だったこともあって1台のサーボモーターを1台のArduinoで制御していた。その後、配線やら雨天対策やらを個別に考えるのが面倒になってきたこともあり、4台のサーボモーターを1台のArduinoで制御することにした。といっても先行事例は沢山あったのでそれほど大変ではなく、PWMのポートを確認するのと外部電源を取るくらいだった。

f:id:takawo:20170822191822p:plain

配線はこんな感じ。ポテンショメータでサーボの動く周期をコントロールしてる。回転の範囲を0-60°にしているのは、それ以上回転すると往復運動の場合は気持ち悪く感じたから。図案にもよると思うし、多分に三半規管が弱い僕の主観かもしれない。

外部電源は秋月電子通商の電源用マイクロUSBコネクタDIP化キットをつかった。Arduino/サーボモータ用電源を2ポート出力するモバイルバッテリを接続することを考えてたんだけど、モバイルバッテリの横幅が大きくて、想定していたケースに入らなかった。1マス戻る感。

基板化にはブレッドボード互換ユニバーサル基板 UB-BRD01を使用した。正直なところ、ブレッドボード互換ユニバーサル基板って品質が良くない印象がある。はんだ付けが下手というのもあると思うけど、ランド(はんだ付けする基板の○い部分)が割とすぐとれてしまったりした。コツでもあるんだろうか。

akizukidenshi.com www.sunhayato.co.jp

作業後、悔しいので、エレキジャックで連載していた「ユニバーサル基板のプロになる」を読んでいた。

キットと初歩の電子工作 Kits and Kids: (連載)ユニバーサル基板のプロになる! アーカイブ

書き込んだコードはこれ。もう少し整理出来る気もするけど、それはまたおいおいで。複数台から1台にまとめて良いのは、そういう改良や統合作業を気軽に再開できることだと思う。

#include <Servo.h>

Servo myservo1;
float angle1 = 0;
float vel1 = 0;

Servo myservo2;
float angle2 = 0;
float vel2 = 0;

Servo myservo3;
float angle3 = 0;
float vel3 = 0;

Servo myservo4;
float angle4 = 0;
float vel4 = 0;

int sensorPin1 = A3;    
int sensorValue1 = 0;  

int sensorPin2 = A4;    
int sensorValue2 = 0;  

int sensorPin3 = A5;    
int sensorValue3 = 0;  

int sensorPin4 = A6;    
int sensorValue4 = 0;  

void setup() {
  Serial.begin(9600);
  myservo1.attach(9); // 9,6,5,3
  myservo2.attach(6); // 9,6,5,3
  myservo3.attach(5); // 9,6,5,3
  myservo4.attach(3); // 9,6,5,3
}

void loop() {
  sensorValue1 = analogRead(sensorPin1);
  vel1 = mapfloat(sensorValue1, 0, 1023, 0.005, 0.01);
  float n1 = (float) sin(angle1);
  float val1 = n1 * 30.0 + 30.0;
  myservo1.write(val1);
  angle1 += vel1 * 5;

  sensorValue2 = analogRead(sensorPin2);
  vel2 = mapfloat(sensorValue2, 0, 1023, 0.005, 0.01);
  float n2 = (float) sin(angle2);
  float val2 = n2 * 30.0 + 30.0;
  myservo2.write(val2);
  angle2 += vel2 * 5;
  
  sensorValue3 = analogRead(sensorPin3);
  vel3 = mapfloat(sensorValue3, 0, 1023, 0.005, 0.01);
  float n3 = (float) sin(angle3);
  float val3 = n3 * 30.0 + 30.0;
  myservo3.write(val3);
  angle3 += vel3 * 5;

  sensorValue4 = analogRead(sensorPin4);
  vel4 = mapfloat(sensorValue4, 0, 1023, 0.005, 0.01);
  float n4 = (float) sin(angle4);
  float val4 = n4 * 30.0 + 30.0;
  myservo4.write(val4);
  angle4 += vel4 * 5;

  //Serial.println(sensorValue1);
  delay(5);
}


float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) {
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}