プロジェクト12 超音波追従タンク

説明
プロジェクト11では、障害物回避カーを作成しました。実は、テストコードを少し変更するだけで、障害物回避カーを追従カーに変換することができます。このレッスンでは、超音波追従ロボットを作成します。超音波センサーはスマートカーと障害物の間の距離を検出し、タンクカーを動かします。
超音波追従ロボットの具体的なロジックは以下の通りです:
検出 |
前方障害物の測定距離 |
距離(単位:cm) |
|---|---|---|
設定 |
サーボ角度90° |
|
8X16 LEDパネルに「V」アイコンを表示 |
||
条件 |
20≤ 距離 ≤60 |
|
状態 |
前進(PWMを200に設定) |
|
条件 |
10<距離<20 |
|
距離>60 |
||
状態 |
停止 |
|
条件 |
距離 ≤10 |
|
状態 |
後退(PWMを200に設定) |
フローチャート

接続図

配線に関する注意:
1.8x16 LEDパネル |
V5 センサーシールド |
|
|---|---|---|
GND |
→ |
-(GND) |
VCC |
→ |
+(VCC) |
SDA |
→ |
SDA |
SCL |
→ |
SCL |
テストコード
/*
keyestudio Mini Tank Robot V2.1
lesson 12
ultrasonic follow tank
http://www.keyestudio.com
*/
// 配列、パターンのデータを保存するために使用されます。自分で計算するか、モジュラスツールから取得できます
unsigned char start01[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
unsigned char front[] = {0x00,0x00,0x00,0x00,0x00,0x24,0x12,0x09,0x12,0x24,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char back[] = {0x00,0x00,0x00,0x00,0x00,0x24,0x48,0x90,0x48,0x24,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char left[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x28,0x10,0x44,0x28,0x10,0x44,0x28,0x10,0x00};
unsigned char right[] = {0x00,0x10,0x28,0x44,0x10,0x28,0x44,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char STOP01[] = {0x2E,0x2A,0x3A,0x00,0x02,0x3E,0x02,0x00,0x3E,0x22,0x3E,0x00,0x3E,0x0A,0x0E,0x00};
unsigned char clear[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
#define SCL_Pin A5 // クロックピンをA5に設定
#define SDA_Pin A4 // データピンをA4に設定
#define ML_Ctrl 13 // 左モーターの方向制御ピンを定義
#define ML_PWM 11 // 左モーターのPWM制御ピンを定義
#define MR_Ctrl 12 // 右モーターの方向制御ピンを定義
#define MR_PWM 3 // 右モーターのPWM制御ピンを定義
#define Trig 5 // 超音波トリガーピン
#define Echo 4 // 超音波エコーピン
int distance;
int pulsewidth;
#define servoPin 9 // サーボピン
void setup(){
Serial.begin(9600);
pinMode(SCL_Pin,OUTPUT);
pinMode(SDA_Pin,OUTPUT);
matrix_display(clear); // ディスプレイをクリア
matrix_display(start01); // スタートパターンを表示
pinMode(servoPin, OUTPUT);
procedure(90); // サーボを90°に設定
pinMode(Trig, OUTPUT);
pinMode(Echo, INPUT);
pinMode(ML_Ctrl, OUTPUT);
pinMode(ML_PWM, OUTPUT);
pinMode(MR_Ctrl, OUTPUT);
pinMode(MR_PWM, OUTPUT);
}
void loop(){
distance = checkdistance(); // 超音波センサーで検出した距離をdistanceに代入
if (distance >= 20 && distance <= 60) // 前進する範囲
{
Car_front();
}
else if (distance > 10 && distance < 20) // 停止する範囲
{
Car_Stop();
}
else if (distance <= 10) // 後退する範囲
{
Car_back();
}
else // その他の状況では停止
{
Car_Stop();
}
}
/***********モーター動作用の関数****************/
void Car_front()
{
digitalWrite(MR_Ctrl,LOW);
analogWrite(MR_PWM,200);
digitalWrite(ML_Ctrl,LOW);
analogWrite(ML_PWM,200);
}
void Car_back()
{
digitalWrite(MR_Ctrl,HIGH);
analogWrite(MR_PWM,200);
digitalWrite(ML_Ctrl,HIGH);
analogWrite(ML_PWM,200);
}
void Car_left()
{
digitalWrite(MR_Ctrl,LOW);
analogWrite(MR_PWM,200);
digitalWrite(ML_Ctrl,HIGH);
analogWrite(ML_PWM,200);
}
void Car_right()
{
digitalWrite(MR_Ctrl,HIGH);
analogWrite(MR_PWM,200);
digitalWrite(ML_Ctrl,LOW);
analogWrite(ML_PWM,200);
}
void Car_Stop()
{
digitalWrite(MR_Ctrl,LOW);
analogWrite(MR_PWM,0);
digitalWrite(ML_Ctrl,LOW);
analogWrite(ML_PWM,0);
}
/******************ドットマトリックス********************/
// ドットマトリックス表示用の関数
void matrix_display(unsigned char matrix_value[])
{
IIC_start(); // データ送信開始の関数を呼び出し
IIC_send(0xc0); // アドレスを選択
for(int i = 0;i < 16;i++) // パターンデータは16ビット
{
IIC_send(matrix_value[i]); // パターンを伝達するデータ
}
IIC_end(); // データパターン伝達を終了
IIC_start();
IIC_send(0x8A); // パルス幅4/16を選択し、表示を制御
IIC_end();
}
// データ送信開始の条件
void IIC_start()
{
digitalWrite(SCL_Pin,HIGH);
delayMicroseconds(3);
digitalWrite(SDA_Pin,HIGH);
delayMicroseconds(3);
digitalWrite(SDA_Pin,LOW);
delayMicroseconds(3);
}
// データを送信
void IIC_send(unsigned char send_data)
{
for(char i = 0;i < 8;i++) // 各バイトは8ビット
{
digitalWrite(SCL_Pin,LOW); // クロックピンSCL_Pinを下げてSDAの信号を変更
delayMicroseconds(3);
if(send_data & 0x01) // 各ビットの1または0に応じてSDA_Pinの高低レベルを設定
{
digitalWrite(SDA_Pin,HIGH);
}
else
{
digitalWrite(SDA_Pin,LOW);
}
delayMicroseconds(3);
digitalWrite(SCL_Pin,HIGH); // クロックピンSCL_Pinを上げてデータ送信を停止
delayMicroseconds(3);
send_data = send_data >> 1; // ビットごとに検出するため、データを1ビット右にシフト
}
}
// データ送信終了の合図
void IIC_end()
{
digitalWrite(SCL_Pin,LOW);
delayMicroseconds(3);
digitalWrite(SDA_Pin,LOW);
delayMicroseconds(3);
digitalWrite(SCL_Pin,HIGH);
delayMicroseconds(3);
digitalWrite(SDA_Pin,HIGH);
delayMicroseconds(3);
}
/***************ドットマトリックス表示終了******************/
// サーボを制御する関数
void procedure(int myangle) {
for (int i = 0; i <= 50; i = i + (1)) {
pulsewidth = myangle * 11 + 500;
digitalWrite(servoPin,HIGH);
delayMicroseconds(pulsewidth);
digitalWrite(servoPin,LOW);
delay((20 - pulsewidth / 1000));
}}
// 超音波センサー制御関数 超音波を制御する関数
float checkdistance() {
digitalWrite(Trig, LOW);
delayMicroseconds(2);
digitalWrite(Trig, HIGH);
delayMicroseconds(10);
digitalWrite(Trig, LOW);
float distance = pulseIn(Echo, HIGH) / 58.20; // 58.20、つまり、2*29.1=58.2
delay(10);
return distance;
}
// ****************************************************************
テスト結果
コードをアップロードしました。DIPスイッチを右端に切り替え、サーボが90°に回転し、8X16 LEDパネルに「V」が表示され、スマートカーが障害物に応じて動きます。