GPSからの受信状況は以下に示す。
GPSアンテナからは東側の空しか見えず、非常に悪い環境なのがわかる。
これを見ると、片側が受信できている様子がなんとなくわかる。
また、この状態でGPSの位置を見ると結構ずれており、このままではあまり使えない。
軸のレンジが少しわかりにくいのだが、一番小さい円から2.5m刻みである。
なので、一番外側の円が10mの誤差となる。
これをできるだけ精度を高めるためには、いくつかのノウハウがある。
まずは、全天を見張らせるところで実験してみると、結構そのまま使えるデータになることもある。いろいろとGPSモジュールの設定を変えるなどして試してみるとよい。上記はGPSモジュールを固定して長時間データ収集した結果である。
U-Centerとの接続
設定用ソフトウェア(Windows版GNSS評価ソフトウェア)であるu-center Windows (https://www.u-blox.com)と接続してみる。
先に使った設定では、GPSモジュールはCOM3に接続され、9600bpsの通信速度になっている。
U-Centerは起動すると、デフォルトの通信速度が9600bpsであり、COM Portも表示してくれるので、Com Portだけを設定すればよい。
下の図の矢印のところあたりでPortと通信速度が設定できる。
すると、通信を始める。
あとは、U-Centerのマニュアルを見ながらいろいろと試してもらいたい。
ちなみに、GPSデータは以下の様に出力される。位置情報は黒塗りさせてもらっているが、雰囲気はわかっていただけたと思う。
GPSモジュールとPCを接続
実際にGPSモジュールとPCを接続してみる。
多くの方がそうだと思うが、PCとGPSモジュールを接続した状態で、GPS信号をそのまま受信できる環境を持っている人は多くないと思われる。
窓の近くにPCと接続されたGPSモジュールを持っていくことになり、これが結構面倒である。
たまたま、自宅に古い電話線の余りが15mほどあったので、その電話線を延長ケーブルとして使っている。
実は、こんな小さい工夫がちょっとした実験に役立っている。
電話線を使ったのは、細くて柔らかいからであり、実際には4本以上の配線があればよいので、LANケーブルを使ってしまってもよい。
信号線にはツイストペアが良いという話は確かにあるが、この実験程度では気にしなくてよい。
もちろん端末処理は行い、GPSモジュール用のコネクタも作成した。
ちなみに、このGPSモジュールで使われているコネクタの種類は、
DF13シリーズ 1.25mmピッチ である。 結構探すのに苦労した。
目的が違う基盤なのだが、たまたまピッチがあったので代用させてもらった。
このUSB-シリアル変換は5Vの出力があるので、GPSモジュールはこの5V,GNDを赤黒で接続。
(ここは、大体想像がつくのだが、ケーブル配線については、自己責任で行ってください。)
そのあと、TXDとRXD、RXDとTXDを接続する。
PCは端末側であり、GPSモジュールはセンサー側であるが、これも一つの端末として考えるケースが多い。
その場合、端末と端末を接続するために、TXDとRXDを接続。 RXDとTXDを接続する。
一般にクロスといわれる接続方法である。
参考までに、端末とモデムなどの延長機器を接続する場合は、TXDとTXD。 すなわちストレートといわれる接続方法である。
この延長機器には、ネットワークに接続する機器であったり、長距離の延長ケーブルを用いるための信号変換だったりする。
ただ、世の中にはDTE機器、DCE機器があやふやなものも多く、筆者はあまり厳密に考えないで試行錯誤を繰り返して決めている。
さて、今回は入手してから一度も設定変更をしていないGPSモジュールを用いた。
それに、PC側で用いるTera Termもインストールしなおしてそのままの設定。
配線も終わり、USB-Serialコンバータを接続。 動作を示す電源のLEDが付けば、USB-Serial側は大丈夫。
GPSもモジュールを見てみて、どこかにLEDなどが点灯していれば大丈夫。
もちろん、GPSモジュールの種類に左右されるのは言うまでもない。
ダメなときは、まず電源を確認をすることとなる。
このGPSモジュールは毎秒データを送信してくれるので、USB-シリアル変換も毎秒通信を示すLEDが点滅していれば大丈夫。
もしLEDが点滅していなければ、TXD/RXDの配線を入れ替えてみることとなる。
次はPC側。 USB-Serialコンバータがどのポートに割りついたかを把握するのだが、ここで把握しなくとも、通信ソフトとなるTera Termで想像できることが多い。
なので、まず、Tera Termを起動する。起動画面でTCP/IPとシリアルの選択ができるのだが、USB-シリアル変換が正しく認識できていないとこのシリアルの選択ができない。
認識されている場合、下図のようになるので、シリアルを選択する。
その段階でデータが表示し始めた。
今回は、GPSモジュールとTera Termの通信設定が一致していたためにすぐに通信が開始した。
その通信設定とは、
通信速度:9600bps
データ長:8bit
パリティ検査:なし
ストップビット:1bit
フロー制御:なし
である。
設定画面の後ろに$GN….と表示されているのがひっさいにGPSモジュールからきた信号である。
“,”が多いのは、GPSモジュールは生きているが、GPS信号は受信できていないことを示す。
この状態が確認できたら、GPSモジュールを空が見えるところに持っていってほしい。
少し、場合によっては数分程度待つと数字がたくさん表示されてくる。
PCとGPSモジュールの接続方法
ここではGPS Moduleについて記載する。
GPSモジュールはたくさんのベンダーから出されているので、各製品にあった使い方が必要である。
いきなりGPSモジュールをArduinoに接続して使うのではなく、
まずGPSモジュールとPCをつなげて動作確認や各種の設定を行うことを強く推奨する。
PCで使うためには、いくつかの環境が必要である。
筆者の環境を参考までに記載すると、
GPS Module(アンテナ込 パッケージ品)
NEO-M8N (https://www.u-blox.com)
設定用ソフトウェア(Windows版GNSS評価ソフトウェア)
u-center Windows (https://www.u-blox.com)
USB-TTLコンバータ
CP2102 (製品名不明 300-400円程度で仕入れたもの)
である。
接続のイメージは以下である。
筆者は、複数のGPSモジュールを持っているが、配線色がバラバラなので、
注意してもらいたい。
4本配線があるコネクタは
各々が、+5V,GND,TXD,RXDとなっていた。
これを接続すればGPSが動作する。
一方、2本配線があるコネクタは
GPSモジュールに内蔵されているI2Cの地磁気コンパスであり、
ここからのは、SDA,SCLである。
ステアリングサーボを動かす
ステアリングサーボはスピードコントローラと同じなのでプログラムの変更はほとんどないので、細かい説明は省略する。
サーボを動作させるためのSteering_Valの値は、以下のとおりである。
50:ステアリングを左に切った状態
90:中立
130:ステアリングを右に切った状態
また、シリアルモニタからの入力で3,4を入力することにより、Steering_Valの値が上下するようになっている。
#include <Servo.h> // Built-in Servo library Servo servo[2]; // create servo object for speed controller and steering servo int SerialInputValue; // Inputed value from serial monitor for debug void setup() { //***** set serial port speed (bps) Serial.begin(115200); //***** set servo pin servo[0]..servo[1] servo[0].attach(9); // Pin 9 is for Stering Servo servo[1].attach(10); // Pin 10 is for Speed Controller } void loop() { static int Steering_Val = 90; // 50-90-130 Steering value (90:center) static int Motor_Val = 94; // 70-92 Speeding Value (70 is fast) SerialRead(); // read inputted numeric key if (SerialInputValue ==3 && Steering_Val >=52){ Steering_Val -= 2; // '3' is inputted from serial monitor } if (SerialInputValue ==4 && Steering_Val <=128){ Steering_Val += 2; // '4' is inputted from serial monitor } if (SerialInputValue ==1 && Motor_Val >=72){ //73 Motor_Val -= 2; // '1' is inputted from serial monitor } if (SerialInputValue ==2 && Motor_Val <=100){ //83 Motor_Val += 2; // '2' is inputted from serial monitor } servo[0].write(Steering_Val); // Servo output (Steering) Serial.print("Steering Value="); Serial.print(Steering_Val); servo[1].write(Motor_Val); // Servo output (Speeding) Serial.print(" Motor Speed="); Serial.println(Motor_Val); }
下記は実験しているときの写真である。
ArduinoからはGNDと9Pin,10Pinの③本だけが出ている。それらがスピードコントローラやステアリングサーボと接続されている。
配線図としては以下となる。
スピードコントローラに与える値
スピードコントローラに与える値はどうすればよいか?
具体的には、
servo[1].write(Motor_Val);
のMotor_Valの値である。 各々実験してもらうことを前提に、このモータとスピードコントローラのケースを記載しておく。
69以下 最高速
70-92 スピードが段階的に変化(70側が高速、90側が低速)
93-174 停止
175 以上 最高速 ←正しく制御できていない
Arduinoでスピードコントローラ経由のモータを動かす
スピードコントローラやステアリングサーボはON/OFFの信号の比率で制御できる。PWM(Pulse Width Modulation:パルス幅変調)方式である。
今回の開発環境であるArduino IDEにはサーボ制御用のライブラリ(Servo)が用意されているので、これを用いるのが簡単である。
Arduinoのスケッチを抜き出してみると、準備として以下の定義が必要である。
#include <Servo.h> // Built-in Servo library
Servo servo[2]; // create servo object for speed controller and steering servo
その後Setup()内でピンの指定を行う。
servo[0].attach(9); // Pin 9 is for Stering Servo
servo[1].attach(10); // Pin 10 is for Speed Controller
Arduino UNOではPWMで使用できるピンが決まっているので、そのピンの番号を記載する必要がある。
この例ではスピードコントローラには10ピン、ステアリングサーボには9ピンを割り付けた。
ピンに出力を出すのは
servo[1].write(Motor_Val)
という記載を行う。 ここではMotor_Valという変数にスピードに相当する値を入れる。
実際に入れる数値は、スピードコントローラによって微妙に差があるので実機に合わせてテストするとよい。
ここで全く違う話になってしまうのだが、実験する過程では、シリアルモニタで数値を上下しながらテストできるようにする必要がある。
そこで、前出のデバック手法を用いる。 さらに、開発環境のIDE上で違うタブに分けた例とした。
下記はスピードコントローラのタブ部分(Speedcontroller.iso)
#include <Servo.h> // Built-in Servo library Servo servo[2]; // create servo object for speed controller and steering servo int SerialInputValue; // Inputed value from serial monitor for debug void setup() { //***** set serial port speed (bps) Serial.begin(115200); //***** set servo pin servo[0]..servo[1] servo[0].attach(9); // Pin 9 is for Stering Servo servo[1].attach(10); // Pin 10 is for Speed Controller } void loop() { static int Steering_Val = 90; // 70-115 Steering value (90:center) static int Motor_Val = 94; // 70-92 Speeding Value (70 is fast) SerialRead(); // read inputted numeric key if (SerialInputValue ==1 && Motor_Val >=72){ //73 Motor_Val -= 2; // '1' is inputted from serial monitor } if (SerialInputValue ==2 && Motor_Val <=100){ //83 Motor_Val += 2; // '2' is inputted from serial monitor } servo[1].write(Motor_Val); // Servo output Serial.print("Motor Speed="); Serial.println(Motor_Val); }
下記はスピードコントローラのタブ部分(SerialMonitor.iso)
void SerialRead(){ int InValue; InValue = Serial.read(); // Read one character if(48 <= InValue and InValue <=57){ // Check between '0' to '9' by ascii code SerialInputValue = InValue-48; // Calculate inputted numeric key } else SerialInputValue = -1; // Other keys or no input }
IDEの表示は以下のようになっている。
スケッチのタブを分ける方法
これからスケッチを作る過程において関数などが増えることになるので、ここでスケッチをタブで分ける方法をメモしておく。
Arduino IDEの右の矢印のところをクリックするとプルダウンメニューにある”新規タブ”をクリックすればよい。
スピードコントローラとArduinoの配線
スピードコントローラ、Arduino、モータ、バッテリの接続例である。
この例ではArduinoの10ピンを制御用の信号として用いている。
スピードコントローラとステアリングサーボの制御
スピードコントローラやステアリングサーボはON/OFFの信号の比率によってによって制御される。
Arduinoで簡単に制御するためには、Servoというライブラリを用いる。
使用することに対する定義例は下記となる。
#include <Servo.h> // Built-in Servo library
Servo servo[2]; // create servo object for speed controller and steering servo
その後Setup()内でピンの指定を行う。
servo[0].attach(9); // Pin 9 is for Stering Servo
servo[1].attach(10); // Pin 10 is for Speed Controller
Arduino UNOではPWMで使用できるピンが決まっているので、そのピンの番号を記載する必要がある。
この例ではスピードコントローラには10ピン、ステアリングサーボには9ピンを割り付けた。
ピンに出力を出すのは
servo[1].write(Motor_Val)
という記載を行う。 ここではMotor_Valという変数にスピードに相当する値を入れる。
実際に入れる数値は、スピードコントローラによって微妙に差がある。
なので実機に合わせてテストするとよい。
この場合、シリアルモニタで数値を上下しながらテストできるように、前出のデバック手法を用いる。 (スケッチの公開は順次。。。)