昨日分からんかったことが分かった!何か面白い。

Fun-Desire-Blog 

PexelsのChristina Morilloによる写真

電子工作

四足歩行ロボットを作りたい!~Arduino・I2C通信 で複数サーボを動かすdo~

更新日:

前回から引き続いてI2Cの接続事例具体的な説明をしていきます。I2C通信について復習すると、通信は2本の信号線ですべてのデータのやりとりを行います。デバイス間のマスタ/スレーブで通信しますが、(今回、Nano :マスタ  とモータードライバー :スレーブ)マスタ側が開始指示に続いてスレーブのアドレスとRead/Write要求を出力をすることで通信が開始されます。このあたりからお話します。さあ、いってみましょう! はヤッ(~~;)。

<このブログの内容(こんな感じで行きま~す)>
・予告編動画
・接続図
・アドレスの設定
・ライブラリのインストール
・スケッチとソフトウエアの説明
・まとめ

1.予告編動画


今回やるのは、I2Cのモータードライバーを使ってサーボモーターと接続・通信し、2個のサーボモーターそれぞれ、ちがう動きをさせます。

2.接続図


NanoのA4ピン:SDA、A5ピン:SCL、5V:VCC、GND:GNDをつなぎます。
サーボモーターは黄色の線と、黄色のピンのを合わせて挿します。

3.アドレスの設定


さて、通信に戻りますが、アドレスの設定については、デフォルトの (0x40) で設定しています。(特に何もしなくて構いません)

これは、デバイス(スレーブ)のI2Cアドレスを指定する話で、いろんなサイトを見ているとモータードライバー(PCA9685搭載)のアドレスを設定する話が記載されています。それは、下の写真のようにモータードライバーの基板上のハンダジャンパーパッドという部分の話です。(ソフトの話ではない)
昔、杉田玄白が解体新書を読み解くのに「というものは目の上に生えている毛である」ということを理解するにも苦労されたそうですが、そういう感じに似ています。(分かってしまえば、そらそうだ、になるのですが・・)



↓↓↓ 詳しく説明されています。
PWM/サーボシールド(PCA9685)を動かしてみます(1/2)



因みにこのハンダジャンパーパッドで0/1を表現しており、A5~A0は「0」を表しています。(パッドが繋がっていないのが、「0」を表すことになります)つまり、0が6個で000000になります。 1+A5とあるように、A5の前に1を付けて、2進数では、1000000、16進数にすると0x40というアドレスになります。(0x :16進数で書いていますという表記)

4.ライブラリのインストール


ここからは、ソフトの話になります。
まず、ライブラリーのダウンロードになります。(zipフォルダです)
サーボ1個だけの時は、下のライブラリを使いました。
Adafruit-PWM-Servo-Driver-Library


複数のサーボを動かす時は下のライブラリを使いました。
秋月通商さんのHPからダウンロードできます。商品は下記。
I2C接続16チャンネル サーボ&PWM駆動キット
(どちらを使うにしてもダウンロードした方をincludeし、アレンジすれば使えると思います)

Adafruitのライブラリをインストールして使う場合は下の3行
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

秋月通商さんのライブラリをインストールして使う場合は下の3行
#include <PCA9685.h>
PCA9685 pwm = PCA9685(0x40);

が必要になり、それぞれ入れ替える必要がありますのでご注意下さい。

読み込んだZIPファイルのインストール



ライブラリーをダウンロードしてArduino IDEで読み込みます。
スケッチ→ライブラリをインクルード→.ZIP形式のライブラリをインストール

5.スケッチとソフトウエアの説明


●まず、サーボモータを1個だけ動かします。

#include <Wire.h> 
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

#define SERVOMIN 102 
     // 下で設定するPWM設定周波数を4096で分割したタイミングで制御する最小パルス幅 :4096/20×0.5=102.4 (0.5ms:SG90、0°の時のパルス幅)
#define SERVOMAX 492 
     // 下で設定するPWM設定周波数を4096で分割したタイミングで制御する最大パルス幅 :4096/20×2.4=491.5 (2.4ms:SG90、180°の時のパルス幅)
 void setup() {
 pwm.begin();
 pwm.setPWMFreq(50); // SG90は 50 Hz で動く(PWM周波数設定)
 }
 void loop() {
    //0番ピンのサーボに角度10度を指示
 servo_write(0,10);
 delay(1500);
    //0番ピンのサーボに角度170度を指示
 servo_write(0,170);
 delay(1500);
 }
 void servo_write(int n, int ang){ //動かすサーボと角度を引数に持つ
 ang = map(ang, 0, 180, SERVOMIN, SERVOMAX); 
    //角度(0~180)をPWMのパルス幅(102~492)へ変換
 pwm.setPWM(n, 0, ang);
    //何番のピンに、いつPWM信号出して、いつ終わるか
 }
サーボを1個だけ動かしてみた

●次に、一斉に動かしてみます。

#include <PCA9685.h>             
    //PCA9685用ヘッダーファイル(秋月電子通商作成)
 PCA9685 pwm = PCA9685(0x40);    
    //PCA9685のアドレス指定(アドレスジャンパ未接続時)
    //PCA9685 pwm2 = PCA9685(0x41);   //PCA9685のアドレス指定(A0接続時)
#define SERVOMIN 102           
    //最小パルス幅
#define SERVOMAX 492            
    //最大パルス幅
 void setup() {
  pwm.begin();                   //初期設定 (アドレス0x40用)
  pwm.setPWMFreq(50);            //PWM周期を50Hzに設定 (アドレス0x40用)
     // pwm2.begin();            //初期設定 (アドレス0x41用)
     //pwm2.setPWMFreq(50);      //PWM周期を50Hzに設定 (アドレス0x41用)
 }
 int n=0;
 void loop() {
     //16chすべてのチャンネルを0度~180度の移動。(10°づづ送り)
   for(int i=0; i<16; i++)      
       servo_write(i,n);  
   n=n+10;     
   if(n>=180)n=0;
   delay(1000);  
 }
 void servo_write(int ch, int ang){ 
     //動かすサーボチャンネルと角度を指定
   ang = map(ang, 0, 180, SERVOMIN, SERVOMAX);
     //角度(0~180)をPWMのパルス幅(102~492)に変換
   pwm.setPWM(ch, 0, ang);
     //  pwm2.setPWM(0, 0, ang);

 }
眠りを誘う、あみんステップ(ちょっとチャウか?)

動画の画面が少しづつ変化してるのが分かりましたか?分からなかった場合はもう一度よく見ながら再生してみて下さい。確かに変化しています。

●最後に、2個のサーボモーターの動きを別々にします。

個別にCHを設定する方法もありますが、CHを0~8と9~16に2分割して動作させてみました。

#include <PCA9685.h>             
      //PCA9685用ヘッダーファイル(秋月電子通商作成)
 PCA9685 pwm = PCA9685(0x40);    
      //PCA9685のアドレス指定(アドレスジャンパ未接続時)
#define SERVOMIN 102           
      //最小パルス幅 
#define SERVOMAX 492            
      //最大パルス幅
 void setup() {
  pwm.begin();                   //初期設定 (アドレス0x40用)
  pwm.setPWMFreq(50);            //PWM周期を50Hzに設定 (アドレス0x40用)
 }
 int n=0;
 int m=0;
 void loop() {
      //16chのうち、0~8CH、9~16CHで分けて別の動作とし、0度~180度の移動を繰り返します。
   for(int i=0; i<9; i++)       
   servo_write(i,n);   
   n=n+35;   
   if(n>=180)n=0;
   delay(500);  

    for(int j=9; j<16; j++)       
    servo_write(j,m);   
    m=m+80;   
    if(m>=180)m=0;
    delay(1000);  
 }
 void servo_write(int ch, int ang){ 
      //動かすサーボチャンネルと角度を指定
   ang = map(ang, 0, 180, SERVOMIN, SERVOMAX);
      //角度(0~180)をPWMのパルス幅(102~492)に変換
   pwm.setPWM(ch, 0, ang);
 }
ウルトラのステップ(光りましたね!)

6.まとめ

最後まで読んで頂き、ありがとうございました。
今回も動作を見るのは、なかなか楽しかったです。しかしそこまではいつもの如くなかなかうまく行かないもんですね。ちょっとまとめてみましょうか。

・Arduino Nano、PCA9685搭載モータードライバー、電池ボックス、USBを接続(USBポート認識)、(ハンダジャンパーパッド確認)
・I2C用のライブラリインストール
・スケッチ作成
 :モータ周波数入力、最大、最小パルス幅計算、動かしたい角度を決めて入力、動かしたいチャンネルを決めて入力

参考までに、ライブラリで使うコマンドが書いてるリンクを貼っておきます。
Adafruit PCA9685 PWM Library

部品リストです。

品名型名(製造元)個数
1マイコン基板Arduino Nano1
2モータードライバーPCA9685搭載16チャネル PWM/サーボ ドライバー ←個数注意1
3サーボモーターデジタル・マイクロサーボ SG90←個数注意8
4接続電線他接続電線、USBケーブル、電池、センサ、本体など1式

さて、今回はいかがでした?I2C使って動かすだけなのですが、結構大変でした。I2Cだけでなく、SPI、UART,Processingなど他にも通信方式はあるようでなので、少しづつ・・(汗)次回は、四足で歩く原理など紹介します。
では、AI、IoT、Tecnogy、You Can Do It! で、つづく。(アラ、今回オッソ)

-電子工作
-, ,

Copyright© Fun-Desire-Blog  , 2021 All Rights Reserved Powered by STINGER.