Arduino基础学习——meArm(太极创客第二部分)
面包板电源模块为机器臂单独供电,机器臂本身有四个小电机驱动作用,如果单独靠arduino来为这四个小电机供电,机器臂可能不会稳定工作,将会抖动。
机械臂的四个动作主要靠四个电机来控制,这四个电机主要连接在我们的arduino控制器上,通过audino的编程,可以对这四个电机发送相应的指令,然后电机就会驱动机械臂做出相应的动作。
伺服电机
这四个电机学名叫做直流伺服电机(舵机)(下图为其结构)。
输出轴上往往会加上一个摇臂,摇臂就会驱动我们想用电机驱动的那些外界的装置了,输出轴下面连接了一个电位器,输出轴在转动的时候,底下电位器也会跟着旋转,电位器旋转的过程中,电压信号就会随之改变,电压信号发送到控制电路上面,控制电路根据接受的信号判断我们的输出是否跟arduino上控制的信号相同,从而调整电机。
#include <Servo.h>Servo myservo; // create servo object to control a servo
// twelve servo objects can be created on most boardsint pos = 0; // variable to store the servo positionvoid setup() {myservo.attach(9); // attaches the servo on pin 9 to the servo object
}void loop() {for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees// in steps of 1 degreemyservo.write(pos); // tell servo to go to position in variable 'pos'//Serial.print(pos);delay(15); // waits 15 ms for the servo to reach the position}for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degreesmyservo.write(pos); // tell servo to go to position in variable 'pos'delay(15); // waits 15 ms for the servo to reach the position}
}
串口通讯
上面返回值是一个数字(代表有几个字节),下面返回值是一个字符型数值。
读取的完整过程:
如果串口接收的是多个字节:逐个进行读取,读取一个清除一个
控制伺服电机
控制一个电机
#include<Servo.h>Servo myServo; //创建Servo对象myServoint dataIndex = 0; //存储输入数据序列号
void setup(){myServo.attach(6);Serial.begin(9600); //启动串口通讯Serial.println(" Please input serial data.");
}void loop(){ //检查串口缓存是否有数据等待传输if(Serial.available()>0){daaIndex++; //处理数据序列号并通过串口监视器显示Serial.print("dataIndex: ");Serial.print(dataIndex);Serial.print(",");int pos = Serial.parseInt(); //解析串口数据中的整数信息并赋值给变量posSerial.print("Set servo postion:");Serial.println(pos); //通过串口监视器显示myServo.write(pos); //使用pos变量数值设置伺服电机delay(15);}
}
结果图:
控制四个电机
#include<Servo.h>Servo base,fArm,rArm,claw; //创建4个电机对象int dataIndex = 0; //存储输入数据序列号
void setup(){base.attach(11); //base 伺服电机链接引脚11 brArm.attach(10); //rArm 伺服电机连接引脚10 rfArm.attach(9); //fArm 伺服电机连接引脚9 fclaw.attach(6); //claw 伺服电机链接引脚6 cSerial.begin(9600); //启动串口通讯Serial.println(" Please input serial data.");
}void loop(){ //检查串口缓存是否有数据等待传输if(Serial.available()>0){char servoName = Serial.read();//获取电机指令中电机编号信息Serial.print("servoName: ");Serial.print(servoName);Serial.print(",");int data = Serial.parseInt(); //获取电机指令中电机角度信息switch(servoName){ //根据电机指令中电机信息决定对哪一个电机进行角度设置case 'b': //电机指令b,设置base电机角度base.write(data);Serial.print("Set base servo value: ");Serial.pritnln(data);break;case 'r': //电机指令r,设置rArm电机角度rArm.write(data);Serial.print("Set rArm servo value: ");Serial.pritnln(data);break;case 'f': //电机指令f,设置rArm电机角度rArm.write(data);Serial.print("Set rArm servo value: ");Serial.pritnln(data);break;case 'c': //电机指令b,设置claw电机角度claw.write(data);Serial.print("Set claw servo value: ");Serial.pritnln(data);break;}Serial.print("Set servo postion:");Serial.println(pos); //通过串口监视器显示myServo.write(pos); //使用pos变量数值设置伺服电机delay(15);}
}
meArm机械臂组装
调试meArm机械臂
#include <Servo.h> //使用servo库
Servo base, fArm, rArm, claw ; //创建4个servo对象// 建立4个int型变量存储当前电机角度值
// 初始角度值为设备启动后初始状态所需要的电机角度数值
int basePos = 90;
int rArmPos = 90;
int fArmPos = 90;
int clawPos = 90;//存储电机极限值(const指定该数值为常量,常量数值在程序运行中不能改变)
const int baseMin = 0;
const int baseMax = 180;
const int rArmMin = 45;
const int rArmMax = 180;
const int fArmMin = 35;
const int fArmMax = 120;
const int clawMin = 25;
const int clawMax = 100;void setup(){base.attach(11); // base 伺服舵机连接引脚11 舵机代号'b'delay(200); // 稳定性等待rArm.attach(10); // rArm 伺服舵机连接引脚10 舵机代号'r'delay(200); // 稳定性等待fArm.attach(9); // fArm 伺服舵机连接引脚9 舵机代号'f'delay(200); // 稳定性等待claw.attach(6); // claw 伺服舵机连接引脚6 舵机代号'c'delay(200); // 稳定性等待Serial.begin(9600); Serial.println("Welcome to Taichi-Maker Robot Arm Tutorial.");
}void loop(){if (Serial.available()>0) { //使用串口监视器输入电机指令控制机械臂电机char serialCmd = Serial.read();//指令举例: b45,将底盘舵机调整到45度位置armDataCmd(serialCmd);}base.write(basePos); delay(10);fArm.write(fArmPos); delay(10);rArm.write(rArmPos); delay(10);claw.write(clawPos); delay(10);
}void armDataCmd(char serialCmd){Serial.print("serialCmd = ");Serial.print(serialCmd); int servoData = Serial.parseInt(); switch(serialCmd){case 'b': basePos = servoData;Serial.print(" Set base servo value: ");Serial.println(servoData);break;case 'c': clawPos = servoData;Serial.print(" Set claw servo value: ");Serial.println(servoData);break;case 'f': fArmPos = servoData;Serial.print(" Set fArm servo value: ");Serial.println(servoData);break;case 'r': rArmPos = servoData;Serial.print(" Set rArm servo value: ");Serial.println(servoData);break;case 'o': reportStatus();break;default:Serial.println(" Unknown Command.");}
}void reportStatus(){Serial.println("");Serial.println("");Serial.println("++++++ Robot-Arm Status Report +++++");Serial.print("Claw Position: clawPos = "); Serial.println(claw.read());Serial.print("Base Position: basePos = "); Serial.println(base.read());Serial.print("Rear Arm Position: rArmPos = "); Serial.println(rArm.read());Serial.print("Front Arm Position: fArmPos = "); Serial.println(fArm.read());Serial.println("++++++++++++++++++++++++++++++++++++");Serial.println("");
}
控制机械臂运行速度(顺畅完成指令)
就是要进行舵机转动速度控制
#include <Servo.h> //使用servo库
Servo base, fArm, rArm, claw ; //创建4个servo对象// 建立4个int型变量存储当前电机角度值
// 初始角度值为设备启动后初始状态所需要的电机角度数值
int basePos = 90;
int rArmPos = 90;
int fArmPos = 90;
int clawPos = 90;//存储电机极限值(const指定该数值为常量,常量数值在程序运行中不能改变)
const int baseMin = 0;
const int baseMax = 180;
const int rArmMin = 45;
const int rArmMax = 180;
const int fArmMin = 35;
const int fArmMax = 120;
const int clawMin = 25;
const int clawMax = 100;void setup(){base.attach(11); // base 伺服舵机连接引脚11 舵机代号'b'delay(200); // 稳定性等待rArm.attach(10); // rArm 伺服舵机连接引脚10 舵机代号'r'delay(200); // 稳定性等待fArm.attach(9); // fArm 伺服舵机连接引脚9 舵机代号'f'delay(200); // 稳定性等待claw.attach(6); // claw 伺服舵机连接引脚6 舵机代号'c'delay(200); // 稳定性等待Serial.begin(9600); Serial.println("Welcome to Taichi-Maker Robot Arm Tutorial");
}void loop(){if (Serial.available()>0) { //使用串口监视器输入电机指令控制机械臂电机char serialCmd = Serial.read();//指令举例: b45,将底盘舵机(舵机代号'b')调整到45度位置armDataCmd(serialCmd);}base.write(basePos); delay(10);fArm.write(fArmPos); delay(10);rArm.write(rArmPos); delay(10);claw.write(clawPos); delay(10);
}void armDataCmd(char serialCmd){ Serial.print("serialCmd = ");Serial.print(serialCmd); int fromPos; //起始位置int toPos; //目标位置int servoData = Serial.parseInt(); switch(serialCmd){case 'b': fromPos = base.read();//把舵机底盘当前的位置信息读出来toPos = servoData;//流畅过度到目标位置
// for(int i =fromPos;i<=toPos;i++){ //b135->b90,这个便不执行
// base.write(i);
// delay(15);
// }if(fromPos<=toPos){for(int i =fromPos;i<=toPos;i++){ //b135->b90,这个便不执行base.write(i);delay(15);}}else{for(int i =fromPos;i>=toPos;i--){ //b135->b90,这个便不执行base.write(i);delay(15);}}basePos = servoData;Serial.print(" Set base servo value: ");Serial.println(servoData);break;case 'c': clawPos = servoData;Serial.print(" Set claw servo value: ");Serial.println(servoData);break;case 'f': fArmPos = servoData;Serial.print(" Set fArm servo value: ");Serial.println(servoData);break;case 'r': rArmPos = servoData;Serial.print(" Set rArm servo value: ");Serial.println(servoData);break;case 'o': reportStatus();break;default:Serial.println(" Unknown Command.");}
}void reportStatus(){Serial.println("");Serial.println("");Serial.println("++++++ Robot-Arm Status Report +++++");Serial.print("Claw Position: clawPos = "); Serial.println(claw.read());Serial.print("Base Position: basePos = "); Serial.println(base.read());Serial.print("Rear Arm Position: rArmPos = "); Serial.println(rArm.read());Serial.print("Front Arm Position: fArmPos = "); Serial.println(fArm.read());Serial.println("++++++++++++++++++++++++++++++++++++");Serial.println("");
}
开发机械臂程序
控制机械臂速度函数封装优化:
#include <Servo.h> //使用servo库
Servo base, fArm, rArm, claw ; //创建4个servo对象//存储电机极限值(const指定该数值为常量,常量数值在程序运行中不能改变)
const int baseMin = 0;
const int baseMax = 180;
const int rArmMin = 45;
const int rArmMax = 180;
const int fArmMin = 35;
const int fArmMax = 120;
const int clawMin = 25;
const int clawMax = 100;int DSD = 15; //Default Servo Delay (默认电机运动延迟时间)//此变量用于控制电机运行速度.增大此变量数值将//降低电机运行速度从而控制机械臂动作速度。void setup(){base.attach(11); // base 伺服舵机连接引脚11 舵机代号'b'delay(200); // 稳定性等待rArm.attach(10); // rArm 伺服舵机连接引脚10 舵机代号'r'delay(200); // 稳定性等待fArm.attach(9); // fArm 伺服舵机连接引脚9 舵机代号'f'delay(200); // 稳定性等待claw.attach(6); // claw 伺服舵机连接引脚6 舵机代号'c'delay(200); // 稳定性等待base.write(90); delay(10);fArm.write(90); delay(10);rArm.write(90); delay(10);claw.write(90); delay(10); Serial.begin(9600); Serial.println("Welcome to Taichi-Maker Robot Arm Tutorial");
}void loop(){if (Serial.available()>0) { char serialCmd = Serial.read();armDataCmd(serialCmd);}
}void armDataCmd(char serialCmd){ //Arduino根据串行指令执行相应操作//指令示例:b45 底盘转到45度角度位置// o 输出机械臂舵机状态信息if (serialCmd == 'b' || serialCmd == 'c' || serialCmd == 'f' || serialCmd == 'r'){int servoData = Serial.parseInt();servoCmd(serialCmd, servoData, DSD); // 机械臂舵机运行函数(参数:舵机名,目标角度,延迟/速度)} else {switch(serialCmd){ case 'o': // 输出舵机状态信息reportStatus();break;default: //未知指令反馈Serial.println("Unknown Command.");}}
}void servoCmd(char servoName, int toPos, int servoDelay){ Servo servo2go; //创建servo对象//串口监视器输出接收指令信息Serial.println("");Serial.print("+Command: Servo ");Serial.print(servoName);Serial.print(" to ");Serial.print(toPos);Serial.print(" at servoDelay value ");Serial.print(servoDelay);Serial.println(".");Serial.println(""); int fromPos; //建立变量,存储电机起始运动角度值switch(servoName){case 'b':if(toPos >= baseMin && toPos <= baseMax){servo2go = base;fromPos = base.read(); // 获取当前电机角度值用于“电机运动起始角度值”break;} else {Serial.println("+Warning: Base Servo Value Out Of Limit!");return;}case 'c':if(toPos >= clawMin && toPos <= clawMax){ servo2go = claw;fromPos = claw.read(); // 获取当前电机角度值用于“电机运动起始角度值”break;} else {Serial.println("+Warning: Claw Servo Value Out Of Limit!");return; }case 'f':if(toPos >= fArmMin && toPos <= fArmMax){servo2go = fArm;fromPos = fArm.read(); // 获取当前电机角度值用于“电机运动起始角度值”break;} else {Serial.println("+Warning: fArm Servo Value Out Of Limit!");return;}case 'r':if(toPos >= rArmMin && toPos <= rArmMax){servo2go = rArm;fromPos = rArm.read(); // 获取当前电机角度值用于“电机运动起始角度值”break;} else {Serial.println("+Warning: rArm Servo Value Out Of Limit!");return;} }//指挥电机运行if (fromPos <= toPos){ //如果“起始角度值”小于“目标角度值”for (int i=fromPos; i<=toPos; i++){servo2go.write(i);delay (servoDelay);}} else { //否则“起始角度值”大于“目标角度值”for (int i=fromPos; i>=toPos; i--){servo2go.write(i);delay (servoDelay);}}
}void reportStatus(){ //舵机状态信息Serial.println("");Serial.println("");Serial.println("+ Robot-Arm Status Report +");Serial.print("Claw Position: "); Serial.println(claw.read());Serial.print("Base Position: "); Serial.println(base.read());Serial.print("Rear Arm Position:"); Serial.println(rArm.read());Serial.print("Front Arm Position:"); Serial.println(fArm.read());Serial.println("++++++++++++++++++++++++++");Serial.println("");
}
键盘控制机械臂程序初版
#include <Servo.h> //使用servo库
Servo base, fArm, rArm, claw ; //创建4个servo对象//存储电机极限值(const指定该数值为常量,常量数值在程序运行中不能改变)
const int baseMin = 0;
const int baseMax = 180;
const int rArmMin = 45;
const int rArmMax = 180;
const int fArmMin = 35;
const int fArmMax = 120;
const int clawMin = 25;
const int clawMax = 100;int DSD = 15; //Default Servo Delay (默认电机运动延迟时间)//此变量用于控制电机运行速度.增大此变量数值将//降低电机运行速度从而控制机械臂动作速度。void setup(){base.attach(11); // base 伺服舵机连接引脚11 舵机代号'b'delay(200); // 稳定性等待rArm.attach(10); // rArm 伺服舵机连接引脚10 舵机代号'r'delay(200); // 稳定性等待fArm.attach(9); // fArm 伺服舵机连接引脚9 舵机代号'f'delay(200); // 稳定性等待claw.attach(6); // claw 伺服舵机连接引脚6 舵机代号'c'delay(200); // 稳定性等待base.write(90); delay(10);fArm.write(90); delay(10);rArm.write(90); delay(10);claw.write(90); delay(10); Serial.begin(9600); Serial.println("Welcome to Taichi-Maker Robot Arm Tutorial");
}void loop(){if (Serial.available()>0) { char serialCmd = Serial.read();armDataCmd(serialCmd);}
}void armDataCmd(char serialCmd){ //Arduino根据串行指令执行相应操作//指令示例:b45 底盘转到45度角度位置// o 输出机械臂舵机状态信息if (serialCmd == 'b' || serialCmd == 'c' || serialCmd == 'f' || serialCmd == 'r'){int servoData = Serial.parseInt();servoCmd(serialCmd, servoData, DSD); // 机械臂舵机运行函数(参数:舵机名,目标角度,延迟/速度)} else {switch(serialCmd){ case 'o': // 输出舵机状态信息reportStatus();break;case 'i':armIniPos(); break;case 'p':playDice(); break;default: //未知指令反馈Serial.println("Unknown Command.");}}
}
void servoCmd(char servoName, int toPos, int servoDelay){ Servo servo2go; //创建servo对象//串口监视器输出接收指令信息Serial.println("");Serial.print("+Command: Servo ");Serial.print(servoName);Serial.print(" to ");Serial.print(toPos);Serial.print(" at servoDelay value ");Serial.print(servoDelay);Serial.println(".");Serial.println(""); int fromPos; //建立变量,存储电机起始运动角度值switch(servoName){case 'b':if(toPos >= baseMin && toPos <= baseMax){servo2go = base;fromPos = base.read(); // 获取当前电机角度值用于“电机运动起始角度值”break;} else {Serial.println("+Warning: Base Servo Value Out Of Limit!");return;}case 'c':if(toPos >= clawMin && toPos <= clawMax){ servo2go = claw;fromPos = claw.read(); // 获取当前电机角度值用于“电机运动起始角度值”break;} else {Serial.println("+Warning: Claw Servo Value Out Of Limit!");return; }case 'f':if(toPos >= fArmMin && toPos <= fArmMax){servo2go = fArm;fromPos = fArm.read(); // 获取当前电机角度值用于“电机运动起始角度值”break;} else {Serial.println("+Warning: fArm Servo Value Out Of Limit!");return;}case 'r':if(toPos >= rArmMin && toPos <= rArmMax){servo2go = rArm;fromPos = rArm.read(); // 获取当前电机角度值用于“电机运动起始角度值”break;} else {Serial.println("+Warning: rArm Servo Value Out Of Limit!");return;} }//指挥电机运行if (fromPos <= toPos){ //如果“起始角度值”小于“目标角度值”for (int i=fromPos; i<=toPos; i++){servo2go.write(i);delay (servoDelay);}} else { //否则“起始角度值”大于“目标角度值”for (int i=fromPos; i>=toPos; i--){servo2go.write(i);delay (servoDelay);}}
}void reportStatus(){ //舵机状态信息Serial.println("");Serial.println("");Serial.println("+ Robot-Arm Status Report +");Serial.print("Claw Position: "); Serial.println(claw.read());Serial.print("Base Position: "); Serial.println(base.read());Serial.print("Rear Arm Position:"); Serial.println(rArm.read());Serial.print("Front Arm Position:"); Serial.println(fArm.read());Serial.println("++++++++++++++++++++++++++");Serial.println("");
}void armIniPos(){Serial.println("+Command: Restore Initial Position.");int robotIniPosArray[4][3] = {{'b', 90, DSD},{'r', 90, DSD},{'f', 90, DSD},{'c', 90, DSD} }; for (int i = 0; i < 4; i++){servoCmd(robotIniPosArray[i][0], robotIniPosArray[i][1], robotIniPosArray[i][2]);}
}
void playDice(){Serial.println("+Command: Let's play some dice!");armIniPos();int diceMove1[21][3] = {{'c', 30, DSD},{'b', 90, DSD},{'f', 43, DSD},{'r', 126, DSD}, {'c', 90, DSD}, {'r', 90, DSD},{'b', 60, DSD}, {'f', 36, DSD}, {'r', 135, DSD}, {'c', 30, DSD},{'r', 90, DSD}, {'b', 90, DSD}, {'f', 36, DSD}, {'r', 135, DSD}, {'c', 90, DSD}, {'r', 90, DSD},{'b', 60, DSD}, {'f', 48, DSD}, {'r', 123, DSD}, {'c', 30, DSD}, {'r', 90, DSD}, };for (int i = 0; i < 21; i++){servoCmd(diceMove1[i][0], diceMove1[i][1], diceMove1[i][2]);delay(200);} armIniPos();int diceMove2[21][3]{{'c', 30, DSD}, {'b', 58, DSD}, {'f', 48, DSD}, {'r', 120, DSD}, {'c', 90, DSD}, {'r', 90, DSD}, {'b', 90, DSD}, {'f', 36, DSD}, {'r', 135, DSD}, {'c', 30, DSD},{'r', 90, DSD}, {'b', 60, DSD}, {'f', 36, DSD},{'r', 135, DSD}, {'c', 95, DSD}, {'r', 90, DSD}, {'b', 90, DSD}, {'f', 43, DSD}, {'r', 125, DSD}, {'c', 30, DSD}, {'r', 90, DSD}, };for (int i = 0; i < 21; i++){servoCmd(diceMove2[i][0], diceMove2[i][1], diceMove2[i][2]);delay(200);} armIniPos();
}
键盘控制机械臂程序终版(灵活版,不固定位置)
#include <Servo.h> //使用servo库
Servo base, fArm, rArm, claw ; //创建4个servo对象//存储电机极限值(const指定该数值为常量,常量数值在程序运行中不能改变)
const int baseMin = 0;
const int baseMax = 180;
const int rArmMin = 45;
const int rArmMax = 180;
const int fArmMin = 35;
const int fArmMax = 120;
const int clawMin = 25;
const int clawMax = 100;int DSD = 15; //Default Servo Delay (默认电机运动延迟时间)//此变量用于控制电机运行速度.增大此变量数值将//降低电机运行速度从而控制机械臂动作速度。
bool mode; //mode = 1: 指令模式, mode = 0: 手柄模式
int moveStep = 3; // 每一次按下手柄按键,舵机移动量(仅适用于手柄模式)
void setup(){base.attach(11); // base 伺服舵机连接引脚11 舵机代号'b'delay(200); // 稳定性等待rArm.attach(10); // rArm 伺服舵机连接引脚10 舵机代号'r'delay(200); // 稳定性等待fArm.attach(9); // fArm 伺服舵机连接引脚9 舵机代号'f'delay(200); // 稳定性等待claw.attach(6); // claw 伺服舵机连接引脚6 舵机代号'c'delay(200); // 稳定性等待base.write(90); delay(10);fArm.write(90); delay(10);rArm.write(90); delay(10);claw.write(90); delay(10); Serial.begin(9600); Serial.println("Welcome to Taichi-Maker Robot Arm Tutorial");
}void loop(){if (Serial.available()>0) { char serialCmd = Serial.read();if( mode == 1 ){armDataCmd(serialCmd); //指令模式} else {armJoyCmd(serialCmd); //手柄模式}}
}void armDataCmd(char serialCmd){ //Arduino根据串行指令执行相应操作//指令示例:b45 底盘转到45度角度位置// o 输出机械臂舵机状态信息//判断人类是否因搞错模式而输入错误的指令信息(指令模式下输入手柄按键信息)if ( serialCmd == 'w' || serialCmd == 's' || serialCmd == 'a' || serialCmd == 'd' || serialCmd == '5' || serialCmd == '4' || serialCmd == '6' || serialCmd == '8' ){Serial.println("+Warning: Robot in Instruction Mode..."); delay(100);while(Serial.available()>0) char wrongCommand = Serial.read(); //清除串口缓存的错误指令return;} if (serialCmd == 'b' || serialCmd == 'c' || serialCmd == 'f' || serialCmd == 'r'){int servoData = Serial.parseInt();servoCmd(serialCmd, servoData, DSD); // 机械臂舵机运行函数(参数:舵机名,目标角度,延迟/速度)} else {switch(serialCmd){ case 'm' : //切换至手柄模式 mode = 0; Serial.println("Command: Switch to Joy-Stick Mode.");break;case 'o': // 输出舵机状态信息reportStatus();break;case 'i':armIniPos(); break;default: //未知指令反馈Serial.println("Unknown Command.");}}
}void armJoyCmd(char serialCmd){ //Arduino根据手柄按键执行相应操作//判断人类是否因搞错模式而输入错误的指令信息(手柄模式下输入舵机指令)if (serialCmd == 'b' || serialCmd == 'c' || serialCmd == 'f' || serialCmd == 'r'){Serial.println("+Warning: Robot in Joy-Stick Mode...");delay(100);while(Serial.available()>0) char wrongCommand = Serial.read(); //清除串口缓存的错误指令return;} int baseJoyPos;int rArmJoyPos;int fArmJoyPos;int clawJoyPos;switch(serialCmd){case 'a': // Base向左Serial.println("Received Command: Base Turn Left"); baseJoyPos = base.read() - moveStep; //read获取角度ser voCmd('b', baseJoyPos, DSD);break; case 'd': // Base向右Serial.println("Received Command: Base Turn Right"); baseJoyPos = base.read() + moveStep;servoCmd('b', baseJoyPos, DSD);break; case 's': // rArm向下Serial.println("Received Command: Rear Arm Down"); rArmJoyPos = rArm.read() + moveStep;servoCmd('r', rArmJoyPos, DSD);break; case 'w': // rArm向上Serial.println("Received Command: Rear Arm Up"); rArmJoyPos = rArm.read() - moveStep;servoCmd('r', rArmJoyPos, DSD);break; case '8': // fArm向上Serial.println("Received Command: Front Arm Up"); fArmJoyPos = fArm.read() + moveStep;servoCmd('f', fArmJoyPos, DSD);break; case '5': // fArm向下Serial.println("Received Command: Front Arm Down"); fArmJoyPos = fArm.read() - moveStep;servoCmd('f', fArmJoyPos, DSD);break; case '4': // Claw关闭Serial.println("Received Command: Claw Close Down"); clawJoyPos = claw.read() + moveStep;servoCmd('c', clawJoyPos, DSD);break; case '6': // Claw打开Serial.println("Received Command: Claw Open Up"); clawJoyPos = claw.read() - moveStep;servoCmd('c', clawJoyPos, DSD);break; case 'm' : //切换至指令模式 mode = 1; Serial.println("Command: Switch to Instruction Mode.");break;case 'o': reportStatus();break;case 'i': armIniPos();break;default:Serial.println("Unknown Command.");return;}
}
void servoCmd(char servoName, int toPos, int servoDelay){ Servo servo2go; //创建servo对象//串口监视器输出接收指令信息Serial.println("");Serial.print("+Command: Servo ");Serial.print(servoName);Serial.print(" to ");Serial.print(toPos);Serial.print(" at servoDelay value ");Serial.print(servoDelay);Serial.println(".");Serial.println("");int fromPos; //建立变量,存储电机起始运动角度值switch(servoName){case 'b':if(toPos >= baseMin && toPos <= baseMax){servo2go = base;fromPos = base.read(); // 获取当前电机角度值用于“电机运动起始角度值”break;} else {Serial.println("+Warning: Base Servo Value Out Of Limit!");return;}case 'c':if(toPos >= clawMin && toPos <= clawMax){ servo2go = claw;fromPos = claw.read(); // 获取当前电机角度值用于“电机运动起始角度值”break;} else {Serial.println("+Warning: Claw Servo Value Out Of Limit!");return; }case 'f':if(toPos >= fArmMin && toPos <= fArmMax){servo2go = fArm;fromPos = fArm.read(); // 获取当前电机角度值用于“电机运动起始角度值”break;} else {Serial.println("+Warning: fArm Servo Value Out Of Limit!");return;}case 'r':if(toPos >= rArmMin && toPos <= rArmMax){servo2go = rArm;fromPos = rArm.read(); // 获取当前电机角度值用于“电机运动起始角度值”break;} else {Serial.println("+Warning: rArm Servo Value Out Of Limit!");return;} }//指挥电机运行if (fromPos <= toPos){ //如果“起始角度值”小于“目标角度值”for (int i=fromPos; i<=toPos; i++){servo2go.write(i);delay (servoDelay);}} else { //否则“起始角度值”大于“目标角度值”for (int i=fromPos; i>=toPos; i--){servo2go.write(i);delay (servoDelay);}}
}void reportStatus(){ //舵机状态信息Serial.println("");Serial.println("");Serial.println("+ Robot-Arm Status Report +");Serial.print("Claw Position: "); Serial.println(claw.read());Serial.print("Base Position: "); Serial.println(base.read());Serial.print("Rear Arm Position:"); Serial.println(rArm.read());Serial.print("Front Arm Position:"); Serial.println(fArm.read());Serial.println("++++++++++++++++++++++++++");Serial.println("");
}void armIniPos(){Serial.println("+Command: Restore Initial Position.");int robotIniPosArray[4][3] = {{'b', 90, DSD},{'r', 90, DSD},{'f', 90, DSD},{'c', 90, DSD} };for (int i = 0; i < 4; i++){servoCmd(robotIniPosArray[i][0], robotIniPosArray[i][1], robotIniPosArray[i][2]);}
}
HC06蓝牙模块——仅作为一个传输工具,无另外的程序编写
/*
---- 电路连接 ----
HC-06 Arduino Uno R3 引脚
TX 0 (RX)
RX 1 (TX)
VCC +5v
GND GNDLED Arduino Uno R3 引脚+ 11 (RX) - GND (通过220欧姆限流电阻)注意:
1. 须使用分压电路,确保HC-06 RX信号电压为3.3伏特。
2. 须先将此程序上传至ARDUINO后,再将HC-06连接在ARDUINO开发板的串口引脚上。否则程序将无法正常上传。*/
int brightness; //LED亮度变量
int serialData; //串口数据变量void setup() {Serial.begin(9600);pinMode(LED_BUILTIN, OUTPUT);pinMode(11, OUTPUT);
}void loop(){if( Serial.available()>0 ){ //如果串口缓存有数据serialData = Serial.parseInt(); //将串口缓存数值存储到serialData变量Serial.print("serialData = "); Serial.println(serialData); if (serialData >=0 && serialData <= 255) { if (serialData >= brightness){ //逐渐调节LED亮度for (brightness; brightness <= serialData; brightness++){analogWrite(11, brightness); Serial.print("brightness = "); Serial.println(brightness); delay(5);} } else {for (brightness; brightness >= serialData; brightness--){analogWrite(11, brightness); Serial.print("brightness = "); Serial.println(brightness); delay(5); } } } }
}
Arduino基础学习——meArm(太极创客第二部分)相关推荐
- Arduino基础学习——第一部分(太极创客)
核心:微控制器,通过引脚与其他设备相连. 三个端口:数字输入/输出端口.模拟输入端口.电源端口 rx.tx(0/1端口)最后使用. high--有电流(点亮),low--没电流(熄灭,GND) dig ...
- Arduino基础学习-声音信号输出
通过Arduino生成声音或者模拟电压,这个教学将介绍如何下面将教你如何建立一个基本的数字模拟转换器,然后你就可以是通过Arduino一些数字信号管脚的不同波形和波长的信号转换为模拟信号.(这篇文章我 ...
- 0基础学习ios开发笔记第二天
C语言的基本结构 c语言的入口函数是main函数. main函数的返回值行业标准是int return 数字:返回值 每条语句最后以分号结尾 注释:行注释.块注释 int main(void) {// ...
- Arduino学习笔记(1):太极创客 第一部分
Arduino学习笔记 太极创客 第一部分 笔记 1-5 变量 1-6 程序结构 1-7 变量操作 1-8/1-9 程序函数 1-10/1-11 数字输出 1-12 面包板 1-13/1-14 数字输 ...
- Mybatis基础学习之一级缓存和二级缓存的简单使用
前言: 小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师. 这个Mybatis ...
- 【ESP8266教程】零基础入门学用物联网-基础知识篇(太极创客团队)学习笔记
前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容. 提示:以下是本篇文章正文内容, ...
- 【太极创客】零基础入门学用Arduino 第一部分 合辑笔记
[太极创客]零基础入门学用Arduino 第一部分 合辑 笔记大多整理于B站评论区 https://www.bilibili.com/video/BV164411J7GE/?spm_id_from=3 ...
- 学习太极创客 — MQTT 第二章(七)ESP8266 MQTT 遗嘱应用
视频链接:http://www.taichi-maker.com/homepage/esp8266-nodemcu-iot/iot-tuttorial/mqtt-tutorial/esp8266-la ...
- 学习太极创客 — MQTT(四)服务端连接操作
视频链接:https://www.bilibili.com/video/BV1T54y1k7MQ/?spm_id_from=trigger_reload&vd_source=b91967c49 ...
最新文章
- 河科大c语言上机实验答案,2016年河南科技学院信息工程学院C语言上机编程考研复试题库...
- 聚焦和增强卷积神经网络
- qoq是什么意思的缩写_“yjgj他的pyq很zqsg”,90后从未觉得自己老,直到看到00后缩写的那一秒……...
- mysql generaton_Mysql 集成随机唯一id mysql unique number generation
- csdn 到底怎么了?不准转载?
- 侍魂服务器维修,侍魂胧月传说合服活动开启 4月15日更新内容预告
- Bitcoin-NG 可扩展的区块链协议
- MyBatis-Plus: 谨慎入坑
- 995. K 连续位的最小翻转次数
- Pthread多线程
- jdk版本问题:hour_day_of 0 -1
- 常见的数值积分方法 (欧拉、中值、龙格-库塔,【常用于IMU中】)
- 二叉树的中序遍历算法
- MPI实现求解10的八次方内素数的个数(版本一)
- js动态生成html表格
- 如何在表格里做计算机统计表,(excel怎么做统计表)excel表格如何制作数据表
- filter指定过滤不起作用
- 利用Office365进行个税改革员工信息收集
- win10摄像头在哪打开?【系统天地】
- 转:POI操作Excel:cell的背景颜色类型