ラベル Arduino の投稿を表示しています。 すべての投稿を表示
ラベル Arduino の投稿を表示しています。 すべての投稿を表示

2020年1月28日火曜日

ドラクエ8のカジノビンゴを完全自動化しました

久しぶりに電子工作しました
iOS のスイッチコントロールが便利だという話です

環境

  • macOS 10.15.2
  • Arduino IDE 1.8.10
  • Arduino Pro mini (5V, 16Mhz)
  • サーボモータ SG90

成果物


Arduino Pro mini + サーボモータ (SG90) を使って先端につけたスタイラスペンを使って自動で画面にタップする感じです
回路などポイントは後述しています

これと iOS のスイッチコントロールを組み合わせることで永遠にビンゴし続けます
ちなみに土台はダンボールを使って簡単に作っています

背景

スイッチコントロールという iOS の機能を知ったがスイッチコントロールだけだと自動化できなかったので定期的にタップしてくれるロボットを作成した感じです
あとは久しぶりに電子工作したかった感じです

回路

fritzing で書いたブレッドボード回路は以下の通りです
スライドスイッチを入れていますがなくても OK です
サーボモータに VCC (5V) と GND を接続しあとは制御するようのピンに接続しているだけです

実写は以下の通りです
緑色のひょろひょろと出ているジャンパー線は GND から出ておりスタイラスペンにつながっています (これポイント)
電源は面倒なので FTDI のシリアルケーブルでそのまま Mac の USB ポートから供給しています
もちろん 5V 電源であればアダプタでも電池でもリチウムイオンでも何でも OK です

ブレッドボード上の回路部分だけアップ
ノイズ除去用に VCC と GND のすぐそばに並列でセラミックコンデンサを接続しています

スケッチ

大したスケッチではないですが一応紹介します
9 番ピンでモータの制御をしています

#include <Servo.h>

Servo myservo;
int led = 9;

void setup() {
  myservo.attach(led);
}

void loop() {
  myservo.write(90);
  delay(10000);
  myservo.write(180);
  delay(500);
}

タッチペン

先程紹介したひょろひょろの接続先です
スタイラスペンは人間の GND とスマホの電極を使って静電気を発生させタップしています
なので人間の手と同じ原理にするために GND をスタイラスペンの先端に接続する必要があります
この手法はタップをロボット化している方のほとんどが実践している手法のようです

またスタイラスペンは先っちょだけ外せるやつがたまたま手元にあったのでそれを使っています
固定は面倒だったので瞬間接着剤を使いました


あとはサーボモータの位置もポイントです
タップする際にふわっとしたタッチだと反応してくれません
結構しっかりタッチしないと反応してくれなかったので写真を見るとわかりますが調整してかなりスマホに近い位置にサーボモータを固定するようにしました
また画面の端っこすぎても反応してくれませんでした
なのでなるべくサーボモータをダンボールから前に突き出すことで画面の真ん中辺りをタップするようにしています

スイッチコントロールとは

iOS12 から使える機能なのですが特定のタップ、スワイプなどをレシピとして管理してワンタップするだけでそのレシピを実行してくれる機能です
https://support.apple.com/ja-jp/guide/iphone/iph400b2f114/ios

これを使うことでビンゴのスタートボタンを一定のタイミングで押すレシピを事前に作成しておき、あとは画面のどこをタップしてもいいようにサーボモータを制御しています

スイッチコントロールと組み合わせるメリットはロボット側が画面のどこをタップしても良いという点です
例えばロボットに「初めにここをタップして次にここをタップして」みたいな感じで全部やらせることもできるのですがそれだと回路も複雑になるしロボットのアームとして制御するサーボモータの数も膨大になってしまうので大変です
なのでスイッチコントロールと組み合わせることで簡単に複雑な画面タップを実現することができるのです

ただスイッチコントロールにもデメリットはあり「5 タップ、10 秒」までしかやってくれません
なので 10 とか 20 ある操作をスイッチコントロールにやらせることはできません

応用したい

今回作ったのは単純に自動タップマシンなので他にも何か使えないかなと思っています
スマホだけじゃなくて実は物理的なスイッチを押したりできるようになると更に便利かなと思っています
あとはモータの始動をスライドスイッチだけじゃなくてスマホからも制御できるようにするとか、、さすがにやりすぎかな

サーボモータ自体かなり簡単に制御できるアクチュエータなので 2, 3 個であれば複数組み合わせても良いかなと思っています
ただサーボモータを固定するのが大変で今回は手元にあった適当なダンボールを使いましたが本当であればプラスチックや木材、ステンレスなどでしっかり固定するべきかなと思っています
そうなってくると今度は単純な工作技術が必要になってくるのでそれはそれで大変になってくるかなと思います

今後

ちゃんとユニバーサル基板にはんだ付けしようかなと思います
あとは土台作りをちゃんとしてみたいです
というかこうなってくると電子工作というよりかは土台作成がしっかりしてこないとダメだなと思いました
実はロボティクスの世界はフレームとかそういうのを作成するほうが大変なんじゃないかな

2016年1月18日月曜日

Arduino でサーボモータを制御してみた

概要

Arduino でサーボモータを制御してみました
Arduino にデフォルトで含まれている Servo ライブラリと独自で PWM を作成して制御する方法の 2 つを試してみました

環境

配線

Arduino UNO はデフォルトで PWM をサポートしているため配線は非常に簡単です
arduino_servo_circuit.jpg

サーボモータから出ている線の

  • 茶色 -> Arduino GND
  • 赤色 -> Arduino 5v電源
  • オレンジ色 -> Arduino GPIO 8 番

に接続します
GPIO は他の好きなところで OK ですが、今回は 8 番を使って進めていきます

制御用スクリプト

2 つ紹介します
どちらも流れとしては Serial.read で受け取った角度情報にサーボモータを回すという処理になります

独自の実装で PWM を送信

まずは自分で PWM 信号を作ってサーボモータを制御するスクリプトです

int deg = 610; // msec.
int pin = 8;

void setup() {
  pinMode(pin, OUTPUT);
  Serial.begin(9600);
}

void move_servo(int deg) {
  digitalWrite(pin, HIGH);
  delayMicroseconds(deg);
  digitalWrite(pin, LOW);
  delay(20);
}

int serialRead() {
  char c[4];
  for (int i = 0; i < 3; i++) {
    c[i] = Serial.read();
    if (c[i] == '\0') {
      break;
    }
  }
  return atoi(c);
}

void loop() {
  move_servo(deg);
  if (Serial.available() > 0) {
    delay(10);
    int input = serialRead();
    if ( input >= 0 && input <= 180 ) {
      deg = 610 + input / 180.0 * ( 2350 - 610 );
    }
  }
}

SG90 のサーボモータは送信するパルス幅の長さが約 610ms から 2350ms で 0 度 から 180 度の動きをするようです
そのパルスを送信する周期を 20ms にしています

送信の仕方は

digitalWrite(pin, HIGH);
delayMicroseconds(deg);
digitalWrite(pin, LOW);

で実現しており、HIGH の状態を指定ミリ秒続けることで幅の違うパルスを送信しています

あとは Serial.read で受け取った度数情報を delayMicroseconds に渡せるように変換してあげます

deg = 610 + input / 180.0 * ( 2350 - 610 );

loop メソッドはその名の通りずっとループしています
なので、move_servo は 20ms の wait をおいて常にコールされているため入力を変えない限り 20ms の間隔で同じパルス幅の信号が送信されていることになります

このプログラムで実際に動作させてみると入力した角度に動くのは動くのですが、サーボモータが動いていないときに「ジリジリ」という音と微妙な振動が発生してしまいました
おそらくですが、これは正確に PWM を送信されていないのが原因で、毎回 20ms 待つようにしていますが、Serial の読み込み等の他の処理があり周期が毎回正確になっておらず、サーボモータが不安定な状態になっているのだと思います

次に Servo ライブラリを使った制御を紹介しますが、結論から先に言うとライブラリを使った制御のほうが圧倒的に安定します
とりあえず今回は PWM の仕組みも知りたかったの、独自の制御方式も試してみた感じです

Servo ライブラリを使って PWM を送信

では、次に Arduino がデフォルトで提供している Servo ライブラリを使って制御してみたいと思います

#include <Servo.h>
Servo servo;

int pin = 8;
int deg = 0;

void setup() {
  servo.attach(pin);
  Serial.begin(9600);
}

void move_servo(int deg) {
  servo.write(deg);
  delay(200);
  servo.detach();
}

int serialRead() {
  char c[4];
  for (int i = 0; i < 3; i++) {
    c[i] = Serial.read();
    if (c[i] == '\0') {
      break;
    }
  }
  return atoi(c);
}

void loop() {
  move_servo(deg);
  if (Serial.available() > 0) {
    delay(10);
    int input = serialRead();
    if ( input >= 0 && input <= 180 ) {
      servo.attach(pin);
      deg = input;
    }
  }
}

ソースもかなり簡潔になりました
Servo ライブラリを使うと servo.write で角度の情報をそのまま渡せます
なので、パルス幅を計算するロジックがなくなります

独自のパルスを送信しているときにジリジリ言っていた問題は

delay(200);
servo.detach();

のロジックでほぼ言わなくなりました
当たり前といえば当たり前ですが、サーボモータを回したくないときは detach することで無駄な信号の送信を抑制します
再度サーボモータを回したいときに attach しています

サーボモータを servo.write で回してからdetach するまでに 200ms の delay を入れています
これは、回した直後に detach してしまうと write の情報がサーボモータに届く前にサーボモータを detach してしまうので、サーボモータが上手く回ってくれないためです

実行してみる

どちらもコードを Arduino IDE に貼り付けて配線して Run すれば OK です
動画等はなくて恐縮ですが、実行して比較してみると Servo ライブラリを使ったほうが断然いい感じにサーボモータが動きます

最後に

Arduino でサーボモータを制御してみました
PWM に詳しく実際に PWM でモータやセンサー等を制御したことある場合は独自の PWM 実装でもいいかもしれませんが、PWM について良くわからないということであれば素直に Servo ライブラリを使うことをオススメします

サーボモータは RaspberryPi でも制御できるので機会があれば RPi でも制御してみたいと思います
Arduino と RaspberryPi どちらでもできるけど、アナログ信号や PWM を扱う場合は Arduino のほうが簡単に制御できる気がします
両方使うとボードが増えて大変ですが、、

参考サイト

2016年1月13日水曜日

Mac で Arduino を使う環境を整えてみた

概要

Mac で Arduino を操作できる環境を整えてみました
簡単なコードの実行まで試してみます

環境

  • Mac OS X 10.10.5
  • Arduino UNO
  • Arduino IDE 1.6.7

Arduino IDE のインストール

まず Arduino のサイトに移動します
https://www.arduino.cc/

Download のリンクをクリックします
arduino_top.png

IDE は OS ごとにインストールするパッケージが異なるので Mac 用のパッケージを選択します
「Mac OS X 10.7 Lion or newer」をクリックします
arduino_for_mac.png

ダウンロードのリンクが表示されるので JUST DOWNLOAD をクリックして zip ファイルのダウンロードを開始します
arduino_download.png

arduino-1.6.7-macosx.zip というファイルがダウンロードできたら解凍します
すると Arduino.app というファイルが出てくるのでアプリケーションフォルダに移動します
移動したら Aruduino.app をクリックして開きます
初めはインターネットからダウンロードしたファイルを開くかどうかの警告が表示されるので「開く」を選択します

Arduino IDE が起動すれば OK です
start_arduino_ide.png

Mac と Arduino を接続する

USB ケーブルを使って接続すれば OK です
IDE を起動してからでも大丈夫です
connect_arduino_mac.jpg

接続できたら IDE に Arduino が接続しているポートを教えてあげます

ツール -> シリアルポート -> /dev/cu.usbmodem1421 (Arduino/Genuino UNO)

を選択します
最後のポートは環境によって異なる可能性があるので自信環境で Arduino を接続している USB ポートを選択してください

L チカ用の簡単な配線をする

とりあえず今回は HelloWorld として L チカをやってみます
カソード側を GND に接続し、アノード側を GPIO の 11 番に接続します
arduino_led_circuit.jpg

サンプルのコードの作成

IDE に以下のコードを貼り付けます

int led_pin = 11;

void setup() {
  pinMode(led_pin, OUTPUT);
}

void loop() {
  digitalWrite(led_pin, HIGH);
  delay(1000);
  digitalWrite(led_pin, LOW);
  delay(1000);
}

記載したら IDE の左上にある「検証」をクリックします
コンパイルが成功すると以下のように表示されます
arduino_verify.png

あとはこのコードを Arduino 側に書き込みます
書き込みは IDE の「マイコンボードに書き込む」を選択すれば OK です
書き込みに成功すると LED が点滅し始めると思います

最後に

Arduino を Mac で動作できるようにしてみました

Arduino は RaspberryPi とは違い OS がありません
その代わりに専用の IDE と Arduino 独自の言語を使って GPIO やペリフェラルを制御することができます
他にもいろいろと違い ( デフォルトでアナログ信号を受信できるとか ) がありますが、用途に合わせて使うボードを使い分けられると電子工作も捗ると思います

参考サイト