极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 16037|回复: 14

求助,关于步进电机机械臂的协作运行问题~~~~~~~~~~~

[复制链接]
发表于 2017-9-26 01:59:13 | 显示全部楼层 |阅读模式
本帖最后由  黄钊 于 2017-10-29 04:35 编辑

产生个想法,干脆把这问题做成一个学习记录得了。
2017/10/29
范围失控问题解决了,
因为xy坐标数据类型是int, 在float l = abs(sqrt(x * x + y * y));里 xy类型不匹配,应该改成float l = abs(sqrt((float)x *(float) x +(float) y * (float)y));

2017/10/27
问题还是存在,当传来的坐标处于时空范围的时候l会大于lTotal
2017/10/18
到现在为止机械臂运行还算成功,能在一定范围内按照传来的坐标大概准确的运动。但是出现一个新问题,当只要当l大于180的时候,stepper1 和stepper2就会同时失控(顺时针不停的转动)
怀疑出现问题部分代码:

//这是传过来的坐标总尺寸的对角线长度,代表机械臂最大运动范围
  float lTotal = abs(sqrt(320 * 320 + 240 * 240));
  //这是坐标系原点到坐标的长度,代表机械臂实时运动范围
  float l = abs(sqrt(x * x + y * y));
  //lt1Pos 存储上一个循环的l值
  double lt1Pos;
  double lt2Pos;
  //求转动的角度
  double theta = atan2(y, x);
  double thetaPos;
  double thetaDiff = theta - thetaPos;
  //l/lTotal是坐标到原点和对角线比值,用这个来mapping电机转动圈数。
  double lt1 = (l / lTotal) * (-2000);
  double lt2 = (l / lTotal) * (-1500);
  //求出与当前循环lt1上一个循环的lt1插值
  double lt1Diff = lt1 - lt1Pos;
  double lt2Diff = lt2 - lt2Pos;


2017/10/18
问题突然解决了,翻阅atan2资料发现要用double类型,把所有long改成double就好了。这个么简单的问题花了好长时间啊。。。

2017/10/17
现在问题就是如图片所示,只有鼠标跨过这条黑线上的点,电机才会有正反运动,其他坐标都没有反应。
2017/10/15
现在用LED来显示传输到ARDUINO的xy坐标的位置(比如x > 200时,led点亮),得到结果是传输到arduino上x,y的数据是正确的。但是电机只会在某一个特定的xy坐标上(如x>or<92, y>or<135)做出正反运动的反应,而且运动幅度都是一样的.
代码:
void headToPoint(int x, int y) {

  long theta = atan2(y, x);
  long thetaPos;
  long thetaDiff = theta - thetaPos;

  //  stepper3.move(thetaDiff * (180 / PI));
  //  delay(100);

  if (stepper3.distanceToGo() == 0) {
    stepper3.moveTo( thetaDiff * (180 / PI));
    thetaPos = theta;
    delay(100);
  }
    if (y < 200) {
      digitalWrite(led, HIGH);
    } else {
      digitalWrite(led, LOW);
    }
}


2017/10/14
我用一个LED来显示thetaDiff的正负变化,是有正负的。弧度值现在也转换为角度值了,开始出现反方向运动了。但是新问题是,总是按照一个幅度频率一致的往复运动。好像并没有受xy坐标的控制。现在最新的headToPoint 修改内容如下:
void headToPoint(int x, int y) {

  long theta = atan2(y, x);
  long thetaPos;
  long thetaDiff = theta - thetaPos;
  //  if (thetaDiff > 0) {
  //    digitalWrite(led, HIGH);
  //  } else {
  //    digitalWrite(led, LOW);
  //  }
  if (stepper3.distanceToGo() == 0) {
    stepper3.moveTo( thetaDiff * (180 / PI));
    thetaPos = theta;
    delay(100);
  }



==========================================================================================

之前 最帅的老饼 指出我的问题太笼统,实在是因为当时不知道问题在哪。现在找到了,但解决不了,如果10位大神之一哪位有时间望帮我解答一下。
下面是修改过的问题和代码:

==========================================================================================

现在我在做一个用摄像头跟踪一个移动的黑点,然后想用一个带有三个步进电机的机械臂实时的把黑点的运动路径画在纸上。连抄带改,在Processing 端已经能跟踪黑点,并把byte信号传给arduino。我找到了accelStepper库,发现可以用在这个程序里。目前我只想先让控制机械臂顺时针逆时针转动的stepper3电机能够根据传来的坐标转动。这段代码里,x,y坐标已经成功传到ARDUINO里,而且电机也动了。但是不知道为什么一直按照一个频率往一个方向转动。三角函数算法这我检查很多遍,好像没有问题。xy坐标也在不断更新,很奇怪。在此献上一首陈小春的 神啊,救救我吧!
设备:a4988, 山寨dobot

arduino代码:

#include <AccelStepper.h>
//#include <MultiStepper.h>
const byte MOVETO = 0;
const byte LINETO = 1;
const byte ORIGIN = 2;
const float MOTOR_DIFF = 1.3;
const int MICROSTEPS = 16;
#define STEPPERX_DIR_PIN 5
#define STEPPERX_STEP_PIN 2

#define STEPPERY_DIR_PIN 6
#define STEPPERY_STEP_PIN 3

#define STEPPERZ_DIR_PIN 7
#define STEPPERZ_STEP_PIN 4

#define en 8

AccelStepper stepper1(AccelStepper:RIVER, STEPPERX_STEP_PIN, STEPPERX_DIR_PIN);
AccelStepper stepper2(AccelStepper:RIVER, STEPPERY_STEP_PIN, STEPPERY_DIR_PIN);
AccelStepper stepper3(AccelStepper:RIVER, STEPPERZ_STEP_PIN, STEPPERZ_DIR_PIN);

int xPos = 0;
int yPos = 0;

void setup() {
  Serial.begin(9600);
  stepper1.setMaxSpeed(200.0);
  stepper1.setAcceleration(100.0);
  // stepper1.moveTo(100000);

  stepper2.setMaxSpeed(300.0);
  stepper2.setAcceleration(100.0);
  //  stepper2.moveTo(1000000);

  stepper3.setMaxSpeed(300.0);
  stepper3.setAcceleration(100.0);
  // stepper3.moveTo(-1000000);
  pinMode(en, OUTPUT);
  digitalWrite(en, LOW);
}
void loop( ) {
  //receiving data (bytearrays) from Serial,
  if (Serial.available() >= 1) {
    byte type = Serial.read();
    byte xByte = Serial.read();
    byte xByte2 = Serial.read();
    byte xByte3 = Serial.read();
    byte xByte4 = Serial.read();
    byte yByte = Serial.read();
    byte yByte2 = Serial.read();
    byte yByte3 = Serial.read();
    byte yByte4 = Serial.read();

    //adding bytes for x and y parameter
    long x = (long) xByte + (long) xByte2 + (long) xByte3  + (long) xByte4;
    long y = (long) yByte + (long) yByte2 + (long) yByte3  + (long) yByte4;
   //compensating the different motors and gearwheels
    y *= MOTOR_DIFF;
    //motor driver requires 16 microsteps per full stepp
    y *= MICROSTEPS;
    x *= MICROSTEPS;
    headToPoint(x, y);
    stepper3.run();
}

//将xy坐标点转换成电机的转动
void headToPoint(long x, long y) {
//三角函数算出角度
  long theta = atan2(y, x);
  long thetaPos;
//角度变化
  long thetaDiff = theta - thetaPos;
  if (stepper3.distanceToGo()==0) {
  stepper3.move( thetaDiff*10);
  }
  thetaPos = theta;

  delay(10);
}

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2017-10-10 21:50:16 | 显示全部楼层
本帖最后由 最帅的老饼 于 2017-10-16 00:38 编辑

加油,同学习、同进步。
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2017-9-27 02:12:48 | 显示全部楼层
没有人能回答么。。。
回复 支持 反对

使用道具 举报

发表于 2017-10-9 20:37:14 | 显示全部楼层
你已经是大神了
回复 支持 反对

使用道具 举报

发表于 2017-10-9 22:02:32 | 显示全部楼层
本帖最后由 最帅的老饼 于 2017-10-16 00:40 编辑

同学习,同进步。
回复 支持 反对

使用道具 举报

发表于 2017-10-10 10:03:42 | 显示全部楼层
最帅的老饼 发表于 2017-10-9 22:02
你给出一堆代码,可知道代码是要和硬件配合工作的。
能单凭睇一大堆代码,从而了解写代码者意途和思路的大 ...

不只是刺眼,而且是很刺...难得人家第一次发主题,应该鼓励为主吧
虽然我看不懂,权当帮顶吧
回复 支持 反对

使用道具 举报

发表于 2017-10-10 10:08:08 | 显示全部楼层
那十个看得懂的大大神应该都很忙,
他们应该比较喜欢回答比较单一的问题,例如:身高年龄体重三围,是否单身?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-10-13 01:24:00 | 显示全部楼层
最帅的老饼 发表于 2017-10-10 21:50
我做计算题,得到答案是 2 。 我肯定自己答案是错的。
发个贴问这题错在那?
但是,题目没有给出来,只 ...

你说的有道理,提问的时候没有问详细的哪有问题是因为当时我也不知道问题出在哪,因为这个代码是我东拼西凑出来的(真的是新手)。
经过这几天研究,代码有了进展,也知道哪有问题了,我一会把之前的问题重新写一遍,谢谢建议
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-10-13 12:03:51 | 显示全部楼层
wing 发表于 2017-10-10 10:03
不只是刺眼,而且是很刺...难得人家第一次发主题,应该鼓励为主吧
虽然我看不懂,权当帮顶吧

谢谢,这应该是第一次在论坛提问,加上之前准备也不充分,确实让看的人很困惑,已经把问题重新修改了
回复 支持 反对

使用道具 举报

发表于 2017-10-13 14:08:49 | 显示全部楼层
本帖最后由 warriorkings 于 2017-10-13 14:10 编辑

在我看来代码的问题有几个问题:
1. atan2返回的是弧度值,后续的计算中也没有换成角度。 stepper的步距角不清楚,驱动器细分也不清楚。弧度差*10作为角度,精准度不清楚。
2. 读取serial的时候没用while, 在读取serial的循环里就控制stepper这个会正确么?

建议楼主做测试时代码里加入适当的print x,y来debug下。查明原因,本人也是小白。说的不对请大神们指正
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-10-13 15:47:27 | 显示全部楼层
warriorkings 发表于 2017-10-13 14:08
在我看来代码的问题有几个问题:
1. atan2返回的是弧度值,后续的计算中也没有换成角度。 stepper的步距角 ...

谢谢,我试着用Serial.print来显示坐标,但是看起来用processing传输数据到arduino的时候就能用串口监视器了。打开监视器就显示繁忙。
1,我几何水平很差,您说的转换我要再去研究一下,驱动器细分我记得好像是1/16,200步一圈。
2,这里用while的具体作用是什么,有没有例子可供参考,给个名字就可以。
谢谢了
回复 支持 反对

使用道具 举报

发表于 2017-10-16 00:40:09 | 显示全部楼层
黄钊 发表于 2017-10-13 01:24
你说的有道理,提问的时候没有问详细的哪有问题是因为当时我也不知道问题出在哪,因为这个代码是我东拼西 ...

我那么刺眼的评论你都能接受,那我前面的评论已经不合适存在了。
回复 支持 反对

使用道具 举报

发表于 2017-10-16 01:03:33 | 显示全部楼层
本帖最后由 最帅的老饼 于 2017-10-16 01:13 编辑

AccelStepper . h
很想了解下。
回复 支持 反对

使用道具 举报

发表于 2017-10-16 01:28:57 | 显示全部楼层
本帖最后由 最帅的老饼 于 2017-10-16 01:33 编辑

编程界有个叫《增量开发理念》
建议你先从一个步进电机做起。
硬件、软件都从控制一个电机做起,成功一步就增加一步。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-10-17 02:42:21 | 显示全部楼层
最帅的老饼 发表于 2017-10-16 01:28
编程界有个叫《增量开发理念》
建议你先从一个步进电机做起。
硬件、软件都从控制一个电机做起,成功一步 ...

谢谢
这个网页是ACCEL库的介绍
http://www.airspayce.com/mikem/arduino/AccelStepper/index.html

我去看看您说的增量开发理念。
目前这个程序就是在测试一个电机,想让他先能够完全受processing里一个坐标的控制,问题出在哪大概已经知道了,但是不知道怎么去解决。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-3-29 18:05 , Processed in 0.048462 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表