PWM/サーボシールド(PCA9685)を動かしてみます(2/2)

(1/2) (XBeeラジコン) 〔マイコンのトップに戻る〕


前ページ(1/2)でPWM/サーボシールドの動作確認は終わったと思います。
このページでは、ジョイスティックを取り付けてサーボモータを動かしたいと思います。
又、前ページでの動作確認は、"Adafruit-PWM-Servo-Driver-Library"のライブラリを使いましたが、
このライブラリはコメントが英語だしぃ、PIC用に移植する事を考えるとぉ、自分でライブラリを
作成した方が良さげぇなのでぇ"skPWMServo"ライブラリを作る事にしました。

ジョイスティック

ジョイスティック 今回の実験で使用したジョイスティックは、秋月通商の
こちらの物です。
XY軸それぞれに10KΩの可変抵抗が取付けて有のでアナログ値を表示させて見たら
0-1023(5.0V)でした。
ですがぁ、ツマミを放せば中央に自動復帰(1024/2=512)を行うのですがぁ、
例えばX軸左に倒して手を放すと"509"位で、右に倒して放せば"606"位とズレる。
サーボの水平位置(90°)が変わると言う事になってしまいますぅ。
このジョイスティックの性能(能力)なのでしょうか?、それともぉこんな物なのでしょうか?。
ラジコンの様な物を作る場合は他のジョイスティックが良さげぇな感じぃみたいなぁ。
なので、今回はスケッチで補正を架けています。

PS. *1)
こちらの”2軸ジョイスティック・モジュール”を購入し値を表示させて見た。
4-1015位の範囲で、中央が502/504とズレ幅も上記のジョイスティックよりましですね。

《実態配線図》

実態配線図
制御用電源はUSBからの5.0Vで、サーボ用電源は外部から5.0Vです。

ジョイスティックは"CN1"側を配線し、"CN2"側はどこにも繋がっていません。
サーボの接続でほとんどのサーボには、サーボドライバのヘッダーに直接接続する標準の
3ピンメスコネクタが付属しています、必ずプラグをアース線(GND:通常は黒または茶色)に合わせ、
底部の行と信号線(PWM:通常は黄色または白色)を上にして下さい。

チャンネル0のサーボがX軸で、チャンネル1のサーボがY軸方向です。

《サンプルプログラムについて》

↓ここからArduino用サンプルスケッチファイルをダウンロードして下さい。
skPWMServo.zip

解凍すると下の様に展開されます。
[skPWMServo]──┬[examples]─────┬─[ServoTest]------ ServoTest.ino
                ├ skPWMServo.cpp    ├─[PWMservoOne]---- PWMservoOne.ino
                ├ skPWMServo.h      └─[PWMservoTwo]---- PWMservoTwo.ino
                └ keywords.txt
ArduinoIDE 1.8.1 がインストールされているフォルダー、インストール先を変更していないなら
[C:\Program Files\arduino-1.8.1\libraries]です。
この場所に上記解凍ファイルを[skPWMServo]ディレクトリ丸ごと移動します。
また、ライブラリの登録や利用方法などの話はこちらを参考にして下さい。

ServoTest.ino  ・・・・・・・本体のサンプルスケッチ(サーボの動作確認用)
PWMservoOne.ino  ・・・・・本体のサンプルスケッチ(ジョイスティックとサーボ1個)
PWMservoTwo.ino  ・・・・・本体のサンプルスケッチ(ジョイスティックとサーボ2個)
skPWMServo.cpp ・・・・・・PWM/サーボ(PCA9685)用関数ライブラリのソースファイル
skPWMServo.h ・・・・・・・PWM/サーボ(PCA9685)用関数のヘッダファイル
keywords.txt ・・・・・・・・キーワードファイル

ServoTest.ino

サーボの動作確認用サンプルです、ServoTest.inoを開くには、
IDEを起動して、メニューバーの「ファイル」→「スケッチの例」→「skPWMServo」→[ServoTest]
をクリック操作すればファイルが開かれます。
次に、IDEツールバーの「Upload」ボタンをクリックしてコンパイルとarduinoボードに書込みを行います。

起動させると、サーボモータ(チャンネル0)が約90°(水平位置)付近に回転すると思います。
このサンプルは、サーボ回転範囲の最小/最大値を見極める為に使用すれば良いでしょう。

各サーボによって、制御信号の出力デュティ比のONパルス幅時間(us)が少々異なります。
なのでぇ、このサンプルにてシリアルモニタを表示させて値を少しづつ入れて調べましょう。
サーボの可動範囲以上の値を与えると壊れる恐れが有ります、最小/最大値の見極めは注意しましょう。
尚、今回使ったサーボ回転範囲は、最小660us(右回転 180°)、最大2320(左回転 0°)でした。

PWMservoOne.ino

ジョイスティックとサーボ1個でのサンプルです、PWMservoOne.inoを開くには、
IDEを起動して、メニューバーの「ファイル」→「スケッチの例」→「skPWMServo」→[PWMservoOne]
をクリック操作すればファイルが開かれます。

@ ServoTest.inoで調べた最小/最大値(PWM出力の分解解像度(0-4095:135-475)を書き換えます。
A IDEツールバーの「Upload」ボタンをクリックしてコンパイルとarduinoボードに書込みを行います。
B 起動させ、ジョイスティックのY軸方向を"UP"させればサーボモータ(チャンネル0)が右回転し、
  "DOWN"させれば左回転すると思います。

※ このサンプルは、SetDutyRatio( )関数を使いPWM出力の分解解像度で回転指示を与えるものです。

PWMservoTwo.ino

ジョイスティックとサーボ2個でのサンプルです、PWMservoTwo.inoを開くには、
IDEを起動して、メニューバーの「ファイル」→「スケッチの例」→「skPWMServo」→[PWMservoTwo]
をクリック操作すればファイルが開かれます。

@ "skPWMServo.h"に記述の#define "SERVOMIN_US"/"SERVOMAX_US"に、
  ServoTest.inoで調べた最小/最大値(出力デュティ比のONパルス幅時間)で書き換えます。
A IDEツールバーの「Upload」ボタンをクリックしてコンパイルとarduinoボードに書込みを行います。
B 起動させ、ジョイスティックのY軸方向はPWMservoOne.inoと同じです、
  但し、回転指示はSetServoOnTime( )関数を使い出力デュティ比のONパルス幅時間(us)で与えています
  X軸方向の回転指示はSetServoAngle( )関数を使い回転角度(0-180°)で与えています、
  なので"LEFT"させればサーボモータ(チャンネル1)が左回転し、"RIGHT"させれば右回転するでしょう

※ このサンプルは、出力デュティ比のONパルス幅時間・回転角度で回転指示を与えるものです。

SetServoOnTime( )/SetServoAngle( )関数を使うとmap( )関数の記述が増えてプログラム量も増え、
  その分速度も掛かるでしょう。
  SetDutyRatio( )関数を使い、直接にPWM出力の分解解像度値で指示すれば効率が良いと思われるがぁ

《ライブラリの説明》

skPWMServo.h

SetServoOnTime( )/SetServoAngle( )関数を使う場合は必ず使用するサーボの回転範囲を設定します。
#define SERVOMIN_US			660		// パルスの最小幅時間us
#define SERVOMAX_US			2320		// パルスの最大幅時間us
skPWMServo.cpp

PWM/サーボ(PCA9685)の制御を行う為の関数集です。
まず利用する場合は下記2行をスケッチの最初に記述します。
#include <Wire.h>
#include <skPWMServo.h>

関数の使い方を説明します。

PWM/サーボ(PCA9685)の関数ライブラリを使用する為に必要な宣言を行います。

skPWMServo Servo(0x40) ;   // PWM/サーボのオブジェクト作成(PCA9685のI2Cアドレス)

Servoの名前は変更出来ますが、以下の例は"Servo"での説明です。

ans=Servo.Init( )
 デバイスの初期化を行う処理。

 int ans:戻り値、0=正常終了 それ以外I2C通信エラー下記
                     1 = 送ろうとしたデータが送信バッファのサイズを超えた
                     2 = スレーブ・アドレスを送信し、NACKを受信した
                     3 = データ・バイトを送信し、NACKを受信した
                     4 = その他のエラー
                     5 = データ受信エラー

 ※ 初期化はMODE1レジスタのみ行っています、MODE2レジスタを変更する場合は御自分で追加
   しましょう。

ans=Servo.SetFrequency(val)
 PWMの出力周波数設定を行う処理。

 float val:出力する周波数値を指定します(24Hz〜1526Hz)
 int   ans:戻り値、0=正常終了 それ以外 Init() のans値を参照

 ※ 50Hzと指定しても実際は、 計測すると50.11Hz程出ています。
PWM出力波形1
PWM出力波形2
こんな感じです。
SetFrequency(val)関数内で
val *= 0.95 ;
で調整しています。

ans=Servo.SetDutyRatio(channel,on_val,off_val)
 PWMの出力デュティ比設定を行う処理。
 デュティ比(0-4095)がレジスタに設定された後、I2CのSTOP信号で実際にPWM出力が開始されます。

 int channel:PWM出力するチャンネル(0〜15)を指定します
                        0                  4095
                         __| ̄ ̄ ̄|___|_ 
 unsigned int  on_val: ---->|                  出力波形の立上げ開始タイミング(0-4095)を指定します
 unsigned int off_val: ------------>|          出力波形の立下げ開始タイミング(0-4095)を指定します
 int        ans:戻り値、0=正常終了 それ以外 Init() のans値を参照

 ※ 今回はサーボモータの制御を行うので、出力波形は"on_val=0"で0から立ち上げます。

Servo.SetServoAngle(channel,angle)
 サーボの回転を角度で指定する処理。

 int             channel:PWM出力するチャンネル(0〜15)を指定します
 unsigned int angle:角度(0-180°)を指定します(90°で水平位置)

 ※ SetFrequency(50)と周波数を設定している事。
 ※ "skPWMServo.h"にてSERVOMIN_US/SERVOMAX_USを設定する事。

Servo.SetServoOnTime(channel,t_us)
 サーボの回転を出力デュティ比のONパルス幅で指定する処理。

 int           channel:PWM出力するチャンネル(0〜15)を指定します
 unsigned int t_ua:ONパルス幅の時間(us)を指定します

 ※ SetFrequency(50)と周波数を設定している事。
 ※ "skPWMServo.h"にてSERVOMIN_US/SERVOMAX_USを設定する事。

ans=Servo.Send(reg_adrs,*data,kosu)
 デバイスに指定個数のデータを送信する処理。

 char           reg_adrs:書出すデータのレジスタアドレスを指定します
             連続的に書出す場合は、書出すレジスタの先頭アドレスを指定します。
 unsigned char *data:書出すデータの格納先を指定します
 char                  kosu:書出すデータのバイト数を指定します
 int                       ans:戻り値、0=正常終了 それ以外 Init() のans値を参照

ans=Servo.Receive(reg_adrs,*data,kosu)
 デバイスから指定個数のデータを受信する処理。

 char           reg_adrs:読出すデータのレジスタアドレスを指定します
             連続的に読出す場合は、読出すレジスタの先頭アドレスを指定します。
 unsigned char *data:読出したデータの格納先を指定します
 char                  kosu:読出すデータのバイト数を指定します
 int                       ans:戻り値、0=正常終了 それ以外 Init() のans値を参照

《 その他 》

実験時の写真 探しまくったら6Pのピンソケットが2個出て来たのでぇ、
電源部分とアナログピンの所に半田付けした。
デジタル部分は何かの部品注文時でも取り寄せよう。
とりあえずはジョイスティック取り付けられた。

後は、XBee等の無線機器を使ってラジコン化実験を
行いたいがぁ....
XBee何だかぁ新型になっているぞぉ、こまるなぁ
又、マイHPの見直しが必要になってしまいますぅ。
シールド無しPCA9685、新しいジョイスティック、
新型XBee....金が無い....
どうしましょぉ... 「(´へ`;

PS.
”ラジコン化実験”はこちらで記事にしています。




記事一部追記(*1) 2018/02/04


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2018 Shigehiro Kimura All Rights Reserved.