error: 'MS_DCMotor' does not name a type 为什么呢?
作为一个完全的小白,大圣这是怎么办 error: 'MS_DCMotor' does not name a type程序如下
#include <MSMotorShield.h>
#include <Servo.h>
//串口输出一个字符串和一个值,用于调试
void output(const char* str, int x){
Serial.print(str);
Serial.println(x);
}
//初始化驱动板上4个直流电机的输出口
MS_DCMotor motor1(1, MOTOR12_1KHZ);
MS_DCMotor motor2(2, MOTOR12_1KHZ);
MS_DCMotor motor3(3, MOTOR12_1KHZ);
MS_DCMotor motor4(4, MOTOR12_1KHZ);
//一个定制的类,专门用来控制直流电机(当然,如果用来控制任何靠电压调节功率的硬件都是可以的,比如iRover就用了这个类来控制灯光系统)
class motorTask{
public:
//构造函数,需要传入控制哪个电机
motorTask(MS_DCMotor* m){
motor = m;
isTask = false;
};
//添加一个动作,该动作会在下一个执行周期内被执行
void addTask(uint8_t dir, uint8_t speed){
isTask = true;
mSpeed = speed;
mDir = dir;
};
//执行当前预约的动作,该函数应当在执行周期内被调用
void doTask(){
if(isTask){
motor->setSpeed(mSpeed);
motor->run(mDir);
isTask = false;
}
};
//清除当前预约的动作
void clearTask(){
isTask = false;
}
private:
MS_DCMotor* motor;
bool isTask;
uint8_t mDir;
uint8_t mSpeed;
};
//这里开始实例化电机了,首先实例化左右两个电机
motorTask mTaskR(&motor2);
motorTask mTaskL(&motor1);
//接着把前后大灯也作为电机类给实例了
motorTask mLedFront(&motor3);
motorTask mLedBack(&motor4);
//舵机的控制类,专门用来控制舵机
class servoTask{
public:
//构造函数,需要传入控制哪个舵机,舵机使用
servoTask(Servo* s, int pin, int degree){
servo = s;
servo->write(degree);
updateTime = millis();
currentDegree = degree;
targetDegree = degree;
};
//添加动作,即需要旋转的目标角度
void addTask(int degree){
targetDegree = degree;
};
//执行动作,向着目标角度转去.因为舵机不是一个及时响应的设备,所以每转动一定角度后都需要延时,为了不阻塞主循环,所以加上了时间判定
void doTask(){
if(currentDegree != targetDegree){
unsigned long now = millis();
if(now - updateTime >= 10){
targetDegree>currentDegree?currentDegree++:currentDegree--;
servo->write(currentDegree);
updateTime = now;
//output("currentDegree",currentDegree);
}
}
};
//清除当前预约的动作
void clearTask(){
targetDegree = currentDegree;
}
private:
Servo* servo;
int currentDegree;
int targetDegree;
unsigned long updateTime;
};
//定义两个舵机,一个控制左右转动,一个控制上下转动
Servo servoLR; // servo LR/L
Servo servoUD;
//将舵机绑定到自己的舵机控制类上,需要设定座机的初始位置.
servoTask sTaskLR(&servoLR, 9, 90);
servoTask sTaskUD(&servoUD, 10, 135);
//这是进行将串口读来的数据进行解析的环节
//iPhone发给小车的指令都是类似这样的字符串:"GL 100$ CH90$"
//这个函数会将读到的指令分解后放入para和paraInt中,并调用doPara()将指令下达给指定的设备.
#define max_para_cnt 5
#define max_para_len 16
char para[max_para_cnt][max_para_len];
int paraInt[max_para_cnt];
int pc=0;
int pl=0;
char cmd;
void resolveSerial() {
while(Serial.available()){
cmd = Serial.read();
if( (cmd>='A' && cmd<='Z') || (cmd>='a' && cmd<='z') || (cmd>='0' && cmd<='9') || cmd=='-' || cmd=='.'){
para[pc][pl] = cmd;
if(cmd>='0' && cmd<='9'){
if(paraInt[pc]==9999){
if(cmd!='0'){
paraInt[pc]=0-(cmd-'0');
}
}
else {
paraInt[pc]*=10;
if(paraInt[pc]>=0)
paraInt[pc]+=cmd-'0';
else
paraInt[pc]-=cmd-'0';
}
} else if(cmd == '-'){
if(paraInt[pc]==0)
paraInt[pc] = 9999;
else
paraInt[pc]*=-1;
}
pl++;
}
else if(cmd == '$'){
doPara();
memset(para,0,sizeof(char)*max_para_cnt*max_para_len);
memset(paraInt,0,sizeof(paraInt));
pc = 0;
pl = 0;
}
else {
if(pl>0){
pc++;
if(pc>=max_para_cnt){
Serial.println("Error : pc too long");
}
pl = 0;
}
}
};
}
//将解析好的指令下达给指定的设备.
//GL/GR 就是控制左右轮子电机的电压,电压的取值范围是-255到255(注意传入的数字并不是直接的电压值,而是一个间接值,输入200会比输入100,使得轮子获得更大的动力,但并不能保证获得2倍的速度),
//这里默认正为前进,负为后退. 比如GL 100$ 就是给左侧电机一个值为100的前进电压
//LF/LB 是控制灯光亮度的两个通路,也是改变电压的方法,但是为了防止把LED烧坏,会限制传入的数字不能大于35
//CV/CH 是控制云台上下\左右移动的,传入的数字是需要转动到的目标角度,如果没有限制,应该在0-180之间
void doPara(){
for(int i=0; i<max_para_cnt; i++)
{
if(paraInt[i]==9999)
paraInt[i] = 0;
}
Serial.print("Do para : ");
output(para[0],paraInt[1]);
if(para[0][0]=='G'){ //Go
uint8_t dir = paraInt[1]>=10?BACKWARD:(paraInt[1]<=10?FORWARD:RELEASE);
uint8_t speed = abs(paraInt[1]);
if(para[0][1]=='L'){
mTaskL.addTask(dir,speed);
}
else if(para[0][1]=='R'){
mTaskR.addTask(dir,speed);
}
}
else if(para[0][0]=='C'){ //See
uint8_t degree = abs(paraInt[1]);
if(para[0][1]=='V'){//UD
sTaskUD.addTask(degree);
}
else if(para[0][1]=='H'){//LR
sTaskLR.addTask(degree);
}
}
else if(para[0][0]=='L'){ //LED
uint8_t dir = abs(paraInt[1])==0?RELEASE:FORWARD;
uint8_t brightness = abs(paraInt[1]);
brightness = brightness>35?35:brightness; //控制电压,防止把led烧了
if(para[0][1]=='F'){
mLedFront.addTask(dir,brightness);
}
else if(para[0][1]=='B'){
mLedBack.addTask(dir,brightness);
}
}
}
//Arduino的初始化函数,在这里进行一些值的初始话
void setup() {
memset(para,0,sizeof(char)*max_para_cnt*max_para_len);
memset(paraInt,0,sizeof(paraInt));
Serial.begin(9600); // 启动串口
pinMode(13, OUTPUT);
motor1.setSpeed(0);
motor2.setSpeed(0);
motor3.setSpeed(0);
motor4.setSpeed(0);
servoLR.attach(9,0,180); // 绑定舵机到针脚,并且设定舵机的旋转范围.
servoUD.attach(10);
}
//Arduino的主循环,不停的读取动作,执行动作就可以了.
void loop() {
//读取串口输入(将所有的输入转换成预约的动作)
resolveSerial();
//执行动作,每个设备依次执行
mTaskL.doTask();
mTaskR.doTask();
sTaskLR.doTask();
sTaskUD.doTask();
mLedFront.doTask();
mLedBack.doTask();
}