[雙A計劃] Part9:藍牙遙控機器手臂車

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

[雙A計畫] 常見問題整理

[雙A計劃] Part0:App Inventor 透過藍牙傳送訊號給 Arduino

[雙A計劃] Part1:App Inventor 經由藍牙控制 Arduino LED 亮滅

[雙A計劃] Part2:App Inventor 經由藍牙控制 Arduino LED 漸明漸暗

[雙A計劃] Part3:Android 手機透過藍牙接收 Arduino 類比腳位狀態

[雙A計劃] Part4:App Inventor 藍牙遙控 Arduino 雙輪機器人

[雙A計劃] Part5:Paperduino 藍牙控制 LED 閃爍

[雙A計畫]Part6:Arduino 傳兩筆資料到 Android 手機

[雙A計劃] Part7:Arduino超音波感測距離回傳數值給Android手機

[雙A計劃] Part8:Android 手機對 Arduino 同時進行資料收發

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

準備以下材料:

1 Android系統智慧型手機

2.Arduino相容開發板 (本文使用 86Duino Educake)

3.藍牙收發接收器(本系列使用JY-MCU04 或 JY-MCU05)

4.麵包板

5.MeArm 或其他相同配置的四自由度機器手臂,使用四個伺服馬達

6.雙輸出行動電源或電池

IMG_0373

這個slideshow需要JavaScript。

台南 Maker Faire 現場展示很受歡迎喔 本範例使用 86duino Educake來製作電路,您可使用各種相容 Arduino 板子。以下是主程式流程,還需要匯入其他函式庫,在此就不列出囉,請直接下載檔案即可。 2015-12-25 13.40.54

共有四個 ino 檔:

  • Car_Motion.ino 控制車身動作,接腳與 L293D 馬達控制晶片接腳位有關
  • Educake_RobotArmCar2.ino   程式主流程,負責接受外部的藍牙訊號來執行對應動作
  • initial.ino 初始化
  • Servoe_Motion.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);
  }
}
Educake_RobotArmCar2.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);
}
Car_Motion.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);
}
initial.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);
}
Servoe_Motion.ino

About CAVEDU 阿吉 - 雜工 (2521 Articles)
CAVEDU 教育團隊 打雜
Contact: Website

Leave a comment

Your email address will not be published.


*