【雙A計劃】Part9:藍牙遙控機器手臂車

整合性的範例就來一台機器手臂遙控機器人吧,把機器手臂裝在雙馬達車體上就完工了,一樣可以透過 App Inventor 來編寫。使用多個按鈕來控制機器人的各個動作。

雙A計畫文章總覽:

中文系列文章

English version

 

作者/攝影   曾吉弘
難度

★★★☆☆

材料表

【推薦套件】自學者的天堂|Arduino 入門到雲端基本套件包

下載 範例程式請點我下載(App Inventor中文學習網檔案庫)

 

IMG_0373

台南 Maker Faire 現場展示很受歡迎喔!!

 

本範例使用 86duino Educake來製作電路,您可使用各種相容 Arduino 板子。以下是主程式流程,還需要匯入其他函式庫,在此就不列出囉,請直接下載檔案即可。

2015-12-25 13.40.54

共有四個 ino 檔:

  • Car_Motion.ino 控制車身動作,接腳與 L293D 馬達控制晶片接腳位有關
  • Educake_RobotArmCar2.ino   程式主流程,負責接受外部的藍牙訊號來執行對應動作
  • initial.ino 初始化
  • Servoe_Motion.ino   控制伺服馬達,請注意轉動角度每台機器人可能略有差異,角度不要用到底以免機構干涉
Educake_RobotArmCar2.ino
#include <Servo.h>

Servo BottomServo; // 底盤旋轉馬達
Servo ArmAServo; // 後臂升降馬達
Servo ArmBServo; // 前臂馬達
Servo ClampServo; // 夾爪馬達


char command; //read the char
#define ServoDelayTime 50

void setup() {
// put your setup code here, to run once:
Serial.begin(9600); //The monitor UART
Serial1.begin(9600); //The Bluetooth UART

SetUp_Pin(); //Set the Servo and Motor Pin
Servo_stop();
}

void loop() {
// put your main code here, to run repeatedly:
if (Serial1.available() > 0)
{
command = Serial1.read();
Serial1.println(command);
Serial.println(command);
}
switch (command)
{
case 'F':
CarForward();
break;
case 'B':
CarBack();
break;
case 'R':
CarRight();
break;
case 'L':
CarLeft();
break;
case 'S':
CarStop();
break;
case '0':
Serial.println("Servo all stop");
//Servo_stop();
delay(ServoDelayTime);
break;
case '1':
Serial.println("MeArm turn Left");
//Servo_stop();
BottomLeft();
delay(ServoDelayTime);
break;
case '2':
Serial.println("MeArm turn Right");
//Servo_stop();
BottomRight();
delay(ServoDelayTime);
break;
case '3':
Serial.println("Arm A Up");
//Servo_stop();
Arm_A_Up();
delay(ServoDelayTime);
break;
case '4':
Serial.println("Arm A Down");
//Servo_stop();
Arm_A_Down();
delay(ServoDelayTime);
break;
case '5':
Serial.println("Arm B Up");
//Servo_stop();
Arm_B_Up();
delay(ServoDelayTime);
break;
case '6':
Serial.println("Arm B Down");
//Servo_stop();
Arm_B_Down();
delay(ServoDelayTime);
break;
case '7':
Serial.println("Clamp Open");
//Servo_stop();
ClampOpen();
delay(ServoDelayTime);
break;
case '8':
Serial.println("Clamp Close");
//Servo_stop();
ClampClose();
delay(ServoDelayTime);
break;
}

if (Serial.available() > 0)
{
command = Serial.read();
Serial.println(command);
}
}
Car_Motion.ino

void CarStop()
{
Serial.println("Car Stop");

//Right Motor
digitalWrite(4, LOW);
digitalWrite(5, LOW);
//Left Motor
digitalWrite(7, LOW);
digitalWrite(8, LOW);
}
void CarForward()
{
Serial.println("Car Forward");

//Right Motor
digitalWrite(4, HIGH);
digitalWrite(5, LOW);
//Left Motor
digitalWrite(7, HIGH);
digitalWrite(8, LOW);
}

void CarBack()
{
Serial.println("Car Back");

//Right Motor
digitalWrite(4, LOW);
digitalWrite(5, HIGH);
//Left Motor
digitalWrite(7, LOW);
digitalWrite(8, HIGH);
}

void CarLeft()
{
Serial.println("Car Left");

//Right Motor
digitalWrite(4, LOW);
digitalWrite(5, LOW);
//Left Motor
digitalWrite(7, HIGH);
digitalWrite(8, LOW);
}

void CarRight()
{
Serial.println("Car Right");

//Right Motor
digitalWrite(4, HIGH);
digitalWrite(5, LOW);
//Left Motor
digitalWrite(7, LOW);
digitalWrite(8, LOW);
}
initial.ino
#define Bottom_pin  3      // 底盤旋轉馬達
#define ArmA_pin 6 // 後臂升降馬達
#define ArmB_pin 9 // 前臂馬達
#define Clamp_pin 10 // 夾爪馬達

#define RightMotor1 4
#define RightMotor2 5
#define LeftMotor1 7
#define LeftMotor2 8

void SetUp_Pin()
{
BottomServo.attach(Bottom_pin);
ArmAServo.attach(ArmA_pin);
ArmBServo.attach(ArmB_pin);
ClampServo.attach(Clamp_pin);

//克定馬達正反轉腳位
pinMode(RightMotor1, OUTPUT);
pinMode(RightMotor2, OUTPUT);
pinMode(LeftMotor1, OUTPUT);
pinMode(LeftMotor2, OUTPUT);

digitalWrite(RightMotor1, LOW);
digitalWrite(RightMotor2, LOW);
digitalWrite(LeftMotor1, LOW);
digitalWrite(LeftMotor2, LOW);
}
Servoe_Motion.ino
//SG90: 500~2500us
//SG90 degree duration:11.1
//SG90 0 degree =500
//SG90 180 degree =2500

//MG90: 400~2400
//MG90 degree duration:11.1
//MG90 0 degree =400
//MG90 180 degree =2400

//define Servo name
//Servo BottomServo; // 底盤旋轉馬達
//Servo ArmAServo; // 後臂升降馬達
//Servo ArmBServo; // 前臂馬達
//Servo ClampServo; // 夾爪馬達

//Servo Range
#define Bottom_max 180 //Turn Left
#define Bottom_min 50 //Turn Right
#define Clamp_max 115 //close
#define Clamp_min 60 //open
#define ArmA_max 150
#define ArmA_min 50
#define ArmB_max 180
#define ArmB_min 70

//Servo Initial Degree
int Clamp_pos = Clamp_max;
int Bottom_pos = (Bottom_max + Bottom_min) / 2;
int ArmA_pos = ArmA_min;
int ArmB_pos = ArmB_max;

//servo degree duration
int delta = 5;
int delta_bottom = 2;


void Servo_stop()
{
BottomServo.write(Bottom_pos);
ClampServo.write(Clamp_pos);
ArmAServo.write(ArmA_pos);
ArmBServo.write(ArmB_pos);
}

void BottomLeft()
{
if (Bottom_pos + delta_bottom < Bottom_max) { Bottom_pos += delta_bottom; } MG90(1, Bottom_pos); } void BottomRight() { if (Bottom_pos - delta_bottom > Bottom_min)
Bottom_pos -= delta_bottom;
MG90(1, Bottom_pos);
}

void Arm_A_Up()
{
if (ArmA_pos + delta < ArmA_max) ArmA_pos += delta; SG90(2, ArmA_pos); } void Arm_A_Down() { if (ArmA_pos - delta > ArmA_min)
ArmA_pos -= delta;
SG90(2, ArmA_pos);
}

void Arm_B_Up()
{
if (ArmB_pos - delta > ArmB_min)
ArmB_pos -= delta;
SG90(3, ArmB_pos);
}

void Arm_B_Down()
{
if (ArmB_pos + delta < ArmB_max)
ArmB_pos += delta;
SG90(3, ArmB_pos);
}

void ClampOpen()
{
Clamp_pos = Clamp_min;
SG90(4, Clamp_pos);
}

void ClampClose()
{
Clamp_pos = Clamp_max;
SG90(4, Clamp_pos);
}


int SG90(int myServo, int angle)
{
angle = 500 + (angle * 11.1);

if (myServo == 2)
{
ArmAServo.writeMicroseconds(angle);
}
if (myServo == 3)
{
ArmBServo.writeMicroseconds(angle);
}
if (myServo == 4)
{
ClampServo.writeMicroseconds(angle);
}
return (angle);
}



int MG90(int myServo, int angle)
{
angle = 400 + (angle * 11.1);
if (myServo == 1)
{
BottomServo.writeMicroseconds(angle);
}
return (angle);
}

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *