環境
OS: Ubuntu18.04
HW:Arduino Mega 2560
Servo Motor : MG996R
Power Supply : 5V
※MG996RはUSBのみの電力だと動作が不安定になった。ということで外部電源5Vを供給。
IDE:
Software | Arduino
事前準備
USBポートのデバイスファイルにアクセスするためのコマンド
$ sudo usermod -a -G dialout `whoami`
書き込み・実行もできるようしておく。
$ sudo chmod 755 /dev/ttyACM0
結線
Arduino側の実装
#include <Servo.h> Servo servo; void setup(){ //デフォルトはmin:544, max:2400 servo.attach(7, 500, 2500); // シリアルポートを9600 bps[ビット/秒]で初期化 Serial.begin(9600); } void loop(){ int inputchar; inputchar = Serial.read(); if(inputchar != -1 ){ switch(inputchar){ case 'o': // 読み込みデータが o の場合 // step one revolution in one direction: servo.write(180); delay(500); break; case 'p': // 読み込みデータが p の場合 // step one revolution in the other direction: servo.write(0); delay(500); break; case 'q': // 読み込みデータが q の場合 // step one revolution in the other direction: servo.write(90); delay(500); break; } } else { } }
MG996Rは他のサーボモータと同様に0°(500us) 180°(2500us)としてパルス幅が決められている。
Linux側の実装
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> #include <termios.h> #include <unistd.h> #define SERIAL_PORT "/dev/ttyACM0" //Arduinoのシリアル通信用deviceファイル名 int main(int argc, char *argv[]) { unsigned char buf[255]; int val; int fd; struct termios tio; int baudRate = B9600; int i; int len; int ret; int size; fd = open(SERIAL_PORT, O_RDWR); if (fd < 0) { printf("open error\n"); return -1; } tio.c_cflag += CREAD; // 受信有効 tio.c_cflag += CLOCAL; // ローカルライン(モデム制御なし) tio.c_cflag += CS8; // データビット:8bit tio.c_cflag += 0; // ストップビット:1bit tio.c_cflag += 0; // パリティ:None cfsetispeed( &tio, baudRate ); cfsetospeed( &tio, baudRate ); cfmakeraw(&tio); // RAWモード tcsetattr( fd, TCSANOW, &tio ); // デバイスに設定を行う ioctl(fd, TCSETS, &tio); // ポートの設定を有効にする // 送信処理ループ while(1) { // ターミナルで入力を待つ。 printf("o:180 p:0>"); fgets(buf, 255, stdin); val=atoi(buf); write(fd, buf, sizeof(buf)); if(buf[0] == 'q') break; } close(fd); // デバイスのクローズ return 0; }
実行
ターミナル上で、上記のmain.cをコンパイルして実行。
$ gcc main.c -o main $ ./main # 180°動かす o/p/q?>o # 0°動かす o/p/q?>p # 90°動かして終了 o/p/q?>q
実際に動かしてみると0~200°ぐらい動いてしまっている。
パチものだろうか🤔
そういうときは
servo.attach(7, 500, 2500);
のminとmax値を狭めるとオッケー