Arduino课程设计的实训要求通过UNO开发板设计工程项目并且与自主开发的AndroidAPP实现连接,最后选择了完成一个可移动机械臂。下面是最终成果图。
最终的效果:可通过手机开发的AndroidApp实现控制小车上的蓝牙模块进行连接并且控制小车的运动和机械臂的运动。
这是开发的AndroidApp(时间受限,UI设计比较简陋。。。)
这是APP的蓝牙连接部分
接下来展示一下关于Arduino代码片段
#include <Servo.h>Servo myservo1,myservo2,myservo3,myservo4; // create servo object to control a servo
const int SERVOS = 4; //舵机数4个
int value[SERVOS], idle[SERVOS], currentAngle[SERVOS], MIN[SERVOS], MAX[SERVOS], INITANGLE[SERVOS], previousAngle[SERVOS],ANA[SERVOS]; char command; //read the char
#define ServoDelayTime 50int delta = 5; //舵机转动幅度
int delta_bottom = 2; //底座舵机转动幅度void setup() {// put your setup code here, to run once:Serial.begin(9600); //The monitor UART//-----电机IO口定-pinMode( 8, OUTPUT);pinMode( 9, OUTPUT);pinMode( 10, OUTPUT);pinMode( 11, OUTPUT);//机械手爪定义端口myservo1.attach(2); //手爪电机myservo2.attach(7); //上臂电机myservo3.attach(12); //下臂电机myservo4.attach(13); //底座电机 //手爪 ServoMIN[0] = 10;MAX[0] = 50;INITANGLE[0] = 30;//上臂电机MIN[1] = 10; // This should bring the lever to just below 90deg to groundMAX[1] = 140;INITANGLE[1] = 90; // This should bring the lever parallel with the ground//下臂电机MIN[2] = 40;MAX[2] = 170;INITANGLE[2] = 90;//底座电机MIN[3] = 0;MAX[3] = 170;INITANGLE[3] = 90;//初始化电机myservo1.write(INITANGLE[0]); myservo2.write(INITANGLE[1]); myservo3.write(INITANGLE[2]);myservo4.write(INITANGLE[3]); currentAngle[0]=INITANGLE[0];currentAngle[1]=INITANGLE[1];currentAngle[2]=INITANGLE[2];currentAngle[3]=INITANGLE[3];
}void loop()
{// put your main code here, to run repeatedly:if(Serial.available()>0){command = Serial.read();Serial.println(command);} switch (command){case 'F':forward(); //机器人前进break;case 'B':back(); //机器人后退break;case 'R':right(); //机器人右转break;case 'L':left(); //机器人左转break;case 'S':stop(); //机器人停止Serial.println("S");break; case '0':Serial.println("Servo all stop");delay(ServoDelayTime);break;case '1':Serial.println("MeArm turn Left");BottomLeft();delay(ServoDelayTime);break;case '2':Serial.println("MeArm turn Right");BottomRight();delay(ServoDelayTime);break;case '3':Serial.println("Arm A Up");Arm_A_Up(); delay(ServoDelayTime);break;case '4':Serial.println("Arm A Down");Arm_A_Down(); delay(ServoDelayTime);break;case '5':Serial.println("Arm B Up");Arm_B_Up(); delay(ServoDelayTime);break;case '6':Serial.println("Arm B Down");Arm_B_Down(); delay(ServoDelayTime);break;case '7':Serial.println("Clamp Open");ClampOpen(); //打开手爪 break;case '8':Serial.println("Clamp Close");ClampClose(); // 闭合手爪break; }}//---------------------------------手爪函数定义---------------------------------------void ClampOpen() //手爪打开
{myservo1.write(MAX[0]);delay(300);
}void ClampClose()
{myservo1.write(MIN[0]); //手爪闭合delay(300);
}
void BottomLeft() // 底座左转
{if(currentAngle[3] + delta_bottom < MAX[3]) {currentAngle[3] += delta_bottom;}myservo4.write(currentAngle[3]);
}void BottomRight() // 底座右转
{if(currentAngle[3] - delta_bottom > MIN[3]) currentAngle[3] -= delta_bottom;myservo4.write(currentAngle[3]);
}void Arm_A_Up() //上臂舵机向上
{if(currentAngle[1] + delta < MAX[1])currentAngle[1] += delta;myservo2.write(currentAngle[1]);
}void Arm_A_Down() //上臂舵机向下
{if(currentAngle[1] - delta > MIN[1])currentAngle[1] -= delta;myservo2.write(currentAngle[1]);
}void Arm_B_Up() //下臂舵机上升
{if(currentAngle[2] - delta > MIN[2])currentAngle[2] -= delta;myservo3.write(currentAngle[2]);
}void Arm_B_Down() //下臂舵机下降
{if(currentAngle[2] + delta < MAX[2])currentAngle[2] += delta;myservo3.write(currentAngle[2]);
}
void Servo_stop() //停止所有舵机
{myservo1.write(currentAngle[0]);myservo2.write(currentAngle[1]);myservo3.write(currentAngle[2]);myservo4.write(currentAngle[3]);
}//---------------------------------运动函数定义---------------------------------------
void forward()
{digitalWrite(8, LOW);digitalWrite(9, HIGH);digitalWrite(11, LOW); digitalWrite(10, HIGH);
}void right()
{digitalWrite(8, LOW);digitalWrite(9, HIGH);digitalWrite(11, LOW);digitalWrite(10, LOW);
}void back()
{digitalWrite(8, HIGH);digitalWrite(9, HIGH);digitalWrite(11, HIGH);digitalWrite(10, HIGH);
}void left()
{digitalWrite(8, LOW);digitalWrite(9, LOW);digitalWrite(11, LOW);digitalWrite(10, HIGH);
}void stop()
{digitalWrite(8, LOW);digitalWrite(9, LOW);digitalWrite(11, LOW);digitalWrite(10, LOW);
}
简单解释一下代码:初始化端口后,设置运动函数对应着小车的前进、后退、停止等运动,然后通过switch语句通过接收到的不同的字符来实现对小车的控制(字符就是从蓝牙客户端接收到的字符)。
接下来讲一下AndroidApp开发部分,本项目选择的是蓝牙的方式实现连接,这一部分的原生开发网上都找得到,就不多赘述了。这边简单介绍一个更简单的方法进行App开发—Appinventor
App Inventor 原是Google实验室(Google Lab)的一个子计划,由一群Google工程师和勇于挑战的Google使用者共同参与设计完成。Google App Inventor是一个完全在线开发的Android编程环境,抛弃复杂的程式代码而使用积木式的堆叠法来完成您的Android程式。除此之外它也正式支持乐高NXT机器人,对于Android初学者或是机器人开发者来说是一大福音。因为对于想要用手机控制机器人的使用者而言,他们不大需要太华丽的界面,只要使用基本元件例如按钮、文字输入输出即可。
这个是Appinventor中文版网址:MIT App Inventor
下面是我的蓝牙App的组件设计
在左边的选框中选择你需要的组件拖到右边的屏幕中,在拖动组件前先选择布局-如何放置你的组件。
因为是用蓝牙连接,所以需要在左边组件面板栏内选择通信连接中的蓝牙模块,然后添加客户端和服务端。到这边组件设计就基本完成,想要好看的界面可以再多琢磨一下。
接下来是逻辑设计(点击右上角的逻辑设计转换设计视图)
这边的是蓝夜的连接部分(就是点击连接可以出现搜索到的蓝牙)
先点击逻辑,从中找到当...执行的拼图,然后点击列表选择框1,就会出现可对列表选择框1进行的操作,点击拼图移动到对应的位置可自动完成连接,蓝牙拼图点击蓝牙客户端就可以找到。
蓝牙断开按钮的设计
按钮控制运动部分的设计,都是选择要设置的按钮,选择对应的松开或者按压操作,然后选择蓝牙客户端的发送文本拼图,接着点击文本选择字符框,然后填入之前在Arduino代码设置的字符。到这App的设计就彻底完成。
打包对应的apk发送到手机上,下载安装即可。
本人也是菜鸟,希望本文章能对在学习过程中遇到同样问题的人一些帮助。