arduino Mega proteus仿真 舵机

这段代码在ARDUINO中编写已经不会报错了,但是烧录在PROTEUS里面无法按照预定目标工作,求帮!
目标就是完成一段使用ARDUINO通过4个按键,分别作用为,开启电机开关(INT2c),选择电机(INT3),电机正转按钮(INT4),电机反转按钮(INT5),通过这四个开关选择控制7个舵机正反转。
目前问题,程序在编译后无问题,导入protues后系统无法运行。最后有附上代码程序和仿真程序的链接,希望有人能帮忙!

 #include <Servo.h>                //使用servo库
Servo motora,motorb,motorc,motord,motore,motorf,motorg;    //创建7个servo对象
const int INT2judge = 9;//电机开关
const int INT3judge = 10;//正反转
const int INT4judge = 11;
const int INT5judge = 12;
int INT2c = 0; 
int INT3c = 0;
int INT4c = 0;
int INT5c = 0;
char ch;//情况
int cm=0;
int moveStep = 3; 
int DSD = 15; //Default Servo Delay (默认电机运动延迟时间)
              //此变量用于控制电机运行速度.增大此变量数值将
              //降低电机运行速度从而控制机械臂动作速度。
int motoramin = 0;
int motoramax = 180;
int motorbmin = 0;
int motorbmax = 180;
int motorcmin = 0;
int motorcmax = 180;
int motordmin = 0;
int motordmax = 180;
int motoremin = 0;
int motoremax = 180;
int motorfmin = 0;
int motorfmax = 180;
int motorgmin = 0;
int motorgmax = 180;
void setup() {
  motora.attach(2);     // base 伺服舵机连接引脚11 舵机代号'b'
  delay(200);          // 稳定性等待
  motorb.attach(3);     // rArm 伺服舵机连接引脚10 舵机代号'r'
  delay(200);          // 稳定性等待
  motorc.attach(4);      // fArm 伺服舵机连接引脚9  舵机代号'f'
  delay(200);          // 稳定性等待
  motord.attach(5);        
  delay(200);         // 稳定性等待
  motore.attach(6);     // base 伺服舵机连接引脚11 舵机代号'b'
  delay(200);          // 稳定性等待
  motorf.attach(7);     // base 伺服舵机连接引脚11 舵机代号'b'
  delay(200);          // 稳定性等待
  motorg.attach(8);     // base 伺服舵机连接引脚11 舵机代号'b'
  delay(200);          // 稳定性等待

  motora.write(20); 
  delay(10);
  motorb.write(20); 
  delay(10);
  motorc.write(20); 
  delay(10);
  motord.write(20);
  delay(10); 
  motore.write(20);
  delay(10);
  motorf.write(20);
  delay(10);
  motorg.write(20);
  delay(10);
  
  pinMode(INT2judge, INPUT);
  pinMode(INT3judge, INPUT);
  pinMode(INT4judge, INPUT);
  pinMode(INT5judge, INPUT);

  Serial.begin(9600);  
}

void loop() {
  INT2c = digitalRead(INT2judge);
  INT3c = digitalRead(INT2judge);
  INT4c = digitalRead(INT4judge);
  INT5c = digitalRead(INT5judge);
  motorchoise();
  motorjudge();
  while(INT2c==LOW){
  armJoyCmd(ch);
  INT2c = digitalRead(INT2judge);
  }

}
void motorchoise(){
  if(INT2c=HIGH){
    delay(500);
    if(INT2c=1){
      choise();
      }
  }
}
void choise(){
   if(cm<=5 ||INT2c==HIGH){
     cm++;
     delay(50000); 
    }else{
      cm=0;
      delay(50000);
      }
}

void motorjudge(){ //电机状态判断函数
  if (cm=0||INT4c == HIGH)
  {
    delay(100); 
      if (cm=0||INT4c == HIGH)
      {
          ch='a'; 
          delay(100);
       } 
    return;
  } //1号电机正转

   if (cm=0||INT5c == HIGH)
  {
    delay(100); 
      if (cm=0||INT5c == HIGH)
      {
          ch='b'; 
          delay(100);
       } 
    return;
  } //1号电机反转

  if (cm=1||INT4c == HIGH)
  {
    delay(100); 
      if (cm=1||INT4c == HIGH)
      {
          ch='c'; 
          delay(100);
       } 
    return;
  } //2号电机正转

   if (cm=1||INT5c == HIGH)
  {
    delay(100); 
      if (cm=1||INT5c == HIGH)
      {
          ch='d'; 
          delay(100);
       } 
    return;
  } //2号电机反转  

  if (cm=2||INT4c == HIGH)
  {
    delay(100); 
      if(cm=2||INT4c == HIGH)
      {
          ch='e'; 
          delay(100);
       } 
    return;
  } //3号电机正转

   if (cm=2||INT5c == HIGH)
  {
    delay(100); 
      if (cm=2||INT5c == HIGH)
      {
          ch='f'; 
          delay(100);
       } 
    return;
  } //3号电机反转                                  

  if (cm=3||INT4c == HIGH)
  {
    delay(100); 
      if (cm=3||INT4c == HIGH)
      {
          ch='g'; 
          delay(100);
       } 
    return;
  } //4号电机正转

   if (cm=3||INT5c == HIGH)
  {
    delay(100); 
      if (cm=3||INT5c == HIGH)
      {
          ch='h'; 
          delay(100);
       } 
    return;
  } //4号电机反转
  
  if (cm=4||INT4c == HIGH)
  {
    delay(100); 
      if (cm=4||INT4c == HIGH)
      {
          ch='i'; 
          delay(100);
       } 
    return;
  } //5号电机正转

   if (cm=4||INT5c == HIGH)
  {
    delay(100); 
      if (cm=4||INT5c == HIGH)
      {
          ch='j'; 
          delay(100);
       } 
    return;
  } //5号电机反转
  
  if (cm=5||INT4c == HIGH)
  {
    delay(100); 
      if (cm=5||INT4c == HIGH)
      {
          ch='k'; 
          delay(100);
       } 
    return;
  } //6号电机正转

   if (cm=5||INT5c == HIGH)
  {
    delay(100); 
      if (cm=5||INT5c == HIGH)
      {
          ch='l'; 
          delay(100);
       } 
    return;
  } //6号电机反转
    if (cm=6||INT4c == HIGH)
  {
    delay(100); 
      if (cm=6||INT4c == HIGH)
      {
          ch='m'; 
          delay(100);
       } 
    return;
  } //7号电机正转

   if (cm=6||INT5c == HIGH)
  {
    delay(100); 
      if (cm=6||INT5c == HIGH)
      {
          ch='n'; 
          delay(100);
       } 
    return;
  } //7号电机反转
}
void armJoyCmd(char serialCmd){
  int motoraJoyPos;
  int motorbJoyPos;
  int motorcJoyPos;
  int motordJoyPos;
  int motoreJoyPos;
  int motorfJoyPos;
  int motorgJoyPos;
  
switch(serialCmd){
    case 'a':  // 1zhegnzhuang              
      motoraJoyPos = motora.read() + moveStep;
      servoCmd('o',motoraJoyPos, DSD);
      break;  
      
    case 'b':  // Base向右
      Serial.println("Received Command: Base Turn Right");                
      motoraJoyPos = motora.read() - moveStep;
      servoCmd('o',motoraJoyPos, DSD);
      break;        
 
    case 'c':  // rArm向下
      motorbJoyPos = motorb.read() + moveStep;
      servoCmd('p',motorbJoyPos, DSD);
      break; 
                 
    case 'd':  // rArm向上
      motorbJoyPos = motorb.read() - moveStep;
      servoCmd('p',motorbJoyPos, DSD);
      break; 
             
    case 'e':  // fArm向上
      motorcJoyPos = motorc.read() + moveStep;
      servoCmd('q',motorcJoyPos, DSD);
      break; 
      
    case 'f':  // fArm向下
      motorcJoyPos = motorc.read() - moveStep;
      servoCmd('q',motorcJoyPos, DSD);
      break; 
      
     case 'g':  // Claw关闭
      motordJoyPos = motord.read() + moveStep;
      servoCmd('r',motordJoyPos, DSD);
      break; 
      
    case 'h':  // Claw打开
      motordJoyPos = motord.read() - moveStep;
      servoCmd('r',motordJoyPos, DSD);
      break; 
       
    case 'i' :   //切换至指令模式 
      motoreJoyPos = motore.read() + moveStep;
      servoCmd('s',motoreJoyPos, DSD);
      break; 

     case 'j' :   //切换至指令模式 
      motoreJoyPos = motore.read() - moveStep;
      servoCmd('s',motoreJoyPos, DSD);
      break; 
      
    case 'k' :   //切换至指令模式 
      motorfJoyPos = motorf.read() + moveStep;
      servoCmd('t',motorfJoyPos, DSD);
      break; 

    case 'l' :   //切换至指令模式 
      motorfJoyPos = motorf.read() - moveStep;
      servoCmd('t',motorfJoyPos, DSD);
      break;  

    case 'm' :   //切换至指令模式 
      motorgJoyPos = motorg.read() + moveStep;
      servoCmd('u',motorgJoyPos, DSD);
      break; 

    case 'n' :   //切换至指令模式 
      motorgJoyPos = motorg.read() - moveStep;
      servoCmd('u',motorgJoyPos, DSD);
      break;
      
    default:
      return;
      
  }  
}
void servoCmd(char servoName, int toPos, int servoDelay){  
  Servo servo2go;  //创建servo对象  
  int fromPos; //建立变量,存储电机起始运动角度值 
  switch(servoName){
    case 'o':
    if(toPos >= motoramin && toPos <= motoramax){
     servo2go = motora;
     fromPos = motora.read();  // 获取当前电机角度值用于“电机运动起始角度值”
     break;
     }

    case 'p':
    if(toPos >= motorbmin && toPos <= motorbmax){
     servo2go = motorb;
     fromPos = motorb.read();  // 获取当前电机角度值用于“电机运动起始角度值”
     break;
     }
     
    case 'q':
    if(toPos >= motorcmin && toPos <= motorcmax){
     servo2go = motorc;
     fromPos = motorc.read();  // 获取当前电机角度值用于“电机运动起始角度值”
     break;
     }

    case 'r':
    if(toPos >= motordmin && toPos <= motordmax){
     servo2go = motord;
     fromPos = motord.read();  // 获取当前电机角度值用于“电机运动起始角度值”
     break;
     }
     
     case 's':
    if(toPos >= motoremin && toPos <= motoremax){
     servo2go = motore;
     fromPos = motore.read();  // 获取当前电机角度值用于“电机运动起始角度值”
     break;
     }
     
     case 't':
    if(toPos >= motorfmin && toPos <= motorfmax){
     servo2go = motorf;
     fromPos = motorf.read();  // 获取当前电机角度值用于“电机运动起始角度值”
     break;
     }

     case 'u':
    if(toPos >= motorgmin && toPos <= motorgmax){
     servo2go = motorg;
     fromPos = motorg.read();  // 获取当前电机角度值用于“电机运动起始角度值”
     break;
     }     
  }
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);
    }
  }
}

然后这个是我的仿真程序

img

[](链接:https://pan.baidu.com/s/1S4wohHKv2UX6tSzbnjH6HQ
提取码:1111
--来自百度网盘超级会员V3的分享)

你在Proteus中仿真的电路图和你的代码中使用的库的版本。此外,你可以提供更多详细信息来描述“无法按照预定目标工作”的问题是什么。是否所有舵机都不运动?还是只有一些舵机不运动?或者是电机没有响应?

另外,我注意到你的代码中有一些错误,这些错误可能会导致程序行为不正常。例如:

在 loop() 函数中,INT2c 的值只在 setup() 函数中读取一次,因此在循环中 INT2c 的值不会发生变化。这可能会导致你的程序陷入死循环。你需要在循环中读取 INT2judge 的值并将其赋值给 INT2c。

在 motorchoise() 函数中,你使用了赋值运算符 = 而不是比较运算符 ==。这会导致程序进入无限循环,因为执行 if 语句的条件永远为真。你需要将 if 语句中的 = 改为 ==。

在 motorjudge() 函数中,你使用了赋值运算符 = 而不是比较运算符 ==。这会导致程序无法正确判断电机的状态,从而无法控制舵机的正反转。你需要将多个 if 语句中的 = 改为 ==。

在 choise() 函数中,你使用了 delay() 函数来实现等待,但是你等待的时间非常长(50000 毫秒),这会导致程序的响应变得非常缓慢。你可以考虑使用 millis() 函数来实现非阻塞延迟。

在 servoCmd() 函数中,你没有对无效的 servoName 进行错误处理。如果传递给函数的 servoName 不是有效的值,函数将会继续执行并尝试读取无效的变量值,这可能会导致程序崩溃。你可以在函数开头添加一个错误处理代码,以确保传递给函数的 servoName 是有效的。

最后,你提到你的程序可能会陷入死循环。为了避免这种情况,你可以在程序中添加一些错误处理代码,例如添加一个计数器,当循环次数超过一定阈值时,退出循环并报告错误。或者在程序中添加一些打印语句,以便在程序执行时能够观察到程序的执行状态和变量的值,从而更容易地发现问题并进行调试。

可以参考下

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void 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 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}


先说一下预定目标啊

以下答案由GPT-4.5Plus大模型(语音)与博主A努力中.......共同编写:

使用Arduino控制4个按键,通过这4个按键控制7个舵机的正反转,完成机械臂的控制。
在Arduino IDE中编译程序没有问题,但是上传到Proteus仿真软件中,程序无法按预期工作。
根据这个问题描述,我有以下几点思考和建议:

  1. 首先需要确保Arduino IDE的板子类型和Proteus中的Arduino模块设置匹配,否则程序可能无法正常工作。如果设置不匹配,建议设置为Arduino UNO匹配。
  2. 验证Proteus环境设置是否正确,包括:
  • 7个舵机模型是否正确加载,舵机接口是否与代码中对应
  • 4个按键是否正确连接到Arduino,按键接口是否与代码中对应
  • 串口监视器波特率设置是否为9600,以观察Arduino输出日志
  1. 使用串口监视器观察Arduino的输出日志,看是否有错误报告。如果有错误报告请查阅原因。
  2. 逐步简化代码,将多余功能暂时移除,只保留最基本的按键控制一个舵机代码。先让简单程序在Proteus运行正确,然后逐步增加其他功能,以便定位问题。
  3. 检查Proteus仿真的参数设置,包括:
  • 仿真时钟频率设置,太高的频率可能导致仿真不稳定
  • 各个元件的处理器分配是否合理,过高可能导致仿真速度很慢
  1. 如果上述方法仍无法解决,可以将Arduino程序通过串口监视器的输出与Proteus仿真下的运行情况进行对比分析,找出两者的差异从而定位问题的原因。