最耀眼的晨星 发表于 2014-10-13 19:58:57

请大家帮忙看看舵机自动正反转的程序有什么问题。

用按键控制舵机,按键按下时舵机开始转动。
正向转动到180度时反向转动,反向转动到1度时开始正向转动,无论何时松开按键舵机均停止工作。程序设定有两个LED灯,指示舵机转动方向。
检测没有问题,但写入之后只能反向转动1圈,然后舵机就停止工作了。请各位大神帮看看。谢谢。

程序代码:
#include <Servo.h>
Servo myservo;//创建一个舵机控制对象
// 使用Servo类最多可以控制8个舵机
int pos = 0;    // 该变量用与存储舵机角度位置
int chePos = 1;    // 设置正反转检测,1为反正,0为正转
int analogINT = 1;// 按键检测口
int i;            // 按键检测参数
int x=180;          //全局角度
/*~~~~~~~~~~~~~~~~~~~~~~~~~~华丽的分割线~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void setup()
{
myservo.attach(9);// 该舵机由arduino第九脚控制
pinMode(7,OUTPUT);// 数字7为输出口
pinMode(6,OUTPUT);// 数字6为输出口
pinMode(3,OUTPUT);// 数字3为输出口
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~华丽的分割线 ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void Clockwise(void)            //正转程序
{
pos=x;
for(pos; pos < 180; pos += 1)// 从0度到180度运动
{                              // 每次步进一度
    i=analogRead(analogINT);
    myservo.write(pos);      // 指定舵机转向的角度
    delay(15);               // 等待15ms让舵机到达指定位置
    x=pos;                     
    if (i<1000)                //检测按键是否按下,如果没有按下则跳出循环
      return;
}

if (x>=170)               //检测舵机角度,超过170度,设定为反转
    chePos=1;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~华丽的分割线 ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void Anti-clockwisefan(void)   //反转程序
{
pos=x;
for(pos ; pos >= 2; pos -= 1)// 从180度到0度运动
{                                                   // 每次步进一度
    i=analogRead(analogINT);
    myservo.write(pos);      // 指定舵机转向的角度
    delay(15);                     // 等待15ms让舵机到达指定位置
    x=pos;
    if (i<1000)                //检测按键是否按下,如果没有按下则跳出循环
      return;
}
if (x<=3)               //检测舵机角度,低于3度,设定为正转         
    chePos=0;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~华丽的分割线 ~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void loop()
{
digitalWrite(3,HIGH);            //数字3口为高电平
while(1)                     //循环,条件永远为真
{
    i=analogRead(analogINT);   //i为模拟1口电压

    if (i>1000)                  //如果i>1000,判断按键按下
      if (chePos=0)               //如果chePos为0,运行正转程序
      {
      digitalWrite(7,HIGH);       //数字7口高电平,点亮LED
      digitalWrite(6,LOW);      //数字6口低电平,熄灭LED
      Clockwise();                //运行正转程序

      }
      else
      {
      digitalWrite(6,HIGH);            //数字6口高电平,点亮LED
      digitalWrite(7,LOW);            //数字7口低电平,熄灭LED
      Anti-clockwisefan();            //运行反转程序
      }
}
}


i7456 发表于 2014-10-14 10:27:59

本帖最后由 i7456 于 2014-10-14 10:40 编辑

#include <Servo.h>
Servo myservo;
int dir = 1;
int pos = 90;
void setup()
{
myservo.attach(9);// 该舵机由arduino第九脚控制
pinMode(8,INPUT_PULLUP);//数字8为输入口。按键的一个管脚接8,另一个接GND。
pinMode(7,OUTPUT);// 数字7为输出口
pinMode(6,OUTPUT);// 数字6为输出口
}
void loop()
{
while(digitalRead(8)==LOW)
{
    if(abs(pos-90) >= 89)
    dir = -dir;
   
    myservo.write(pos);
    pos += dir;
    delay(50);

    if(dir>0){
      digitalWrite(7,HIGH);
      digitalWrite(6,LOW);}
    else{
      digitalWrite(7,LOW);
      digitalWrite(6,HIGH);}
}
}你的电路,按键输入用的是模拟口,按键未按下时是悬空的,状态不确定,
有可能是大于1000的状态,也可能是小于1000的状态。

最耀眼的晨星 发表于 2014-10-14 20:02:15

感谢大家的回复,原因找到了,可不知道如何解决。
变量chePos在从子程序返回到主程序时,参数变成了程序开始指定的参数。
比如我在前面指家chePos=1,在 Anti-clockwisefan程序中将参数改为0了,但回到主程序后参数又变回了1,导致只能执行反转程序,无法继续执行正转。

请教下如何指定全局变量,或者在如何传递参数到子程序。谢谢

最耀眼的晨星 发表于 2014-10-14 21:15:01

问题找到了,已解决
在loop程序内,if (chePos=0)应为if (chePos==0)


小问题找了几天。好久没弄过程序了,印像中if 后面的应为逻辑表达式,没想到在这里可以直接赋值,还是看运算符号说明才想起来 等于应为==不是=

感谢大家的回复

wolfcolorful 发表于 2016-7-20 17:11:10

本帖最后由 wolfcolorful 于 2016-7-20 17:15 编辑

学习了!
做了一点改变。

代码如下:
#include <Servo.h>
Servo myservo;//创建一个舵机控制对象, 使用Servo类最多可以控制8个舵机
int pos = 0;    // 该变量用与存储舵机角度位置
int chePos;    // 设置正反转检测,1为反转,0为正转
int analogINT = 1;// 按键检测口
int i;            // 按键检测参数
int x=180;          //全局角度

void setup()
{
pinMode(9,OUTPUT);//舵机控制线为输出口
pinMode(7,OUTPUT);// 红色LED电源端为输出口
pinMode(6,OUTPUT);// 绿色LED电源端为输出口
myservo.attach(9);// 该舵机由arduino第九脚控制
}

void Clockwise(void)            //正转程序
{
chePos=0;
//pos=x;
for(pos; pos < 180; pos++)// 从0度到180度运动
{                              // 每次步进一度
    i=analogRead(analogINT);
    myservo.write(pos);      // 指定舵机转向的角度
    delay(15);               // 等待15ms让舵机到达指定位置
    x=pos;                     
    if (i<1000) return;       //检测按键是否按下,如果没有按下则跳出循环      
}
if (x>=170) chePos=1;   //检测舵机角度,超过170度,设定为反转   
}

void Anti_clockwisefan(void)   //反转程序
{
chePos=1;
pos=x;
for(pos ; pos >= 2; pos--)// 从180度到0度运动,每次步进一度
{                              
    i=analogRead(analogINT);
    myservo.write(pos);      // 指定舵机转向的角度
    delay(15);                // 等待15ms让舵机到达指定位置
    x=pos;
    if (i<1000) return;      //检测按键是否按下,如果没有按下则跳出循环      
}
if (x<=3) chePos=0;   //检测舵机角度,低于3度,设定为正转
}

void loop()
{
while(1)                     //循环,条件永远为真
{
    i=analogRead(analogINT);   //i为模拟1口电压
    if (i>1000)                  //如果i>1000,判断按键按下
    {
      if (chePos==0)                //如果chePos为0,运行正转程序
      {
      digitalWrite(7,HIGH);       //数字7口高电平,点亮LED
      digitalWrite(6,LOW);      //数字6口低电平,熄灭LED
      Clockwise();                //运行正转程序
      }
      else
      {
      digitalWrite(6,HIGH);            //数字6口高电平,点亮LED
      digitalWrite(7,LOW);            //数字7口低电平,熄灭LED
      Anti_clockwisefan();            //运行反转程序
      }
    }
    else
    {
      digitalWrite(7,LOW);
      digitalWrite(6,LOW);
      digitalWrite(9,LOW);
    }
}
}

不过还是有个缺陷:程序初始化的时候舵机一定会归零后再开始转动。也就是说,如果在任意角度位置放开按键,重新下载程序到板上,此时舵机将快速回零(零位是相对的,视程序中取消哪一个pos=x),再旋转、限位后反向旋转。
暂时还不知道是什么原因,研究中……

laozjx 发表于 2016-9-13 08:12:29

谢谢楼主,学习。
页: [1]
查看完整版本: 请大家帮忙看看舵机自动正反转的程序有什么问题。