【问题标题】:Arduino stepper control by programArduino步进控制程序
【发布时间】:2014-11-25 08:55:51
【问题描述】:

我尝试使用使用协议的程序来控制步进电机(见下文) 我可以使用 Accelstepper(见下文)控制步进器,但不知道如何对 Arduino 进行编程,以便它能够通过串行端口根据 te 协议进行通信。

#include <AccelStepper.h>

// Define a stepper and the pins it will use
AccelStepper stepper(1, 3, 4);

int pos = 8192; 

void setup()
{  
  stepper.setMaxSpeed(5000);
  stepper.setAcceleration(1500);
}

void loop()
{
  if (stepper.distanceToGo() == 0)
  {
    delay(500);
    pos = -pos;
    stepper.moveTo(pos);
  }
  stepper.run();
}

发送到转台的所有命令都是简单的字符格式,包括电机编号。只有标记为 xxx 的部分作为字节数据传递给表。例如,如果您希望表 1 旋转 4 步而不是传递“I1M004”,则传递“I1M”+ (char)0 + (char)0 + (char)4 一般来说,所有命令都会以如下形式得到回复:^XXXXXX

命令

V 请求转台的状态。通常的回复是 ^R1R2R3R4 表示旋转 1 准备好,旋转 2 准备好等。^B1xxxR2R3R4 表示旋转 1 忙,其中 xxx 是 3 个字节,表示旋转还需要执行多少步。

SmMxxx 将电机 m 的速度设置为 xxx,其中 xxx 是一个 3 字节的数据,表示速度。示例代码:port.Write("S1M" + (char)0 + (char)6 + (char)255); // 将电机 1 的速度设置为 1791。我们转台的标准速度范围是:0x000001 到 0x0012FF(1 到 4863)。控制器将响应 ^mxx 镜像电机编号和速度设置的最后 2 个字节。

Immxxx 转动电机 m xxx 步数。控制器将通过 ^Bmxxx

进行确认

DmCWLO 设置电机编号 m 顺时针旋转(因此每个连续命令旋转电机 m 都会顺时针旋转)。

DmCWHi 设置旋转 m 逆时针旋转。

EmHALT 旋转 m 停止。 旋转采样命令序列

为了简单起见,电机编号以字符形式传递,但步数和速度以 3 个字节的二进制形式传递。 发送:V 回复:^R1R2R3R4 发送:S1M1791 回复:^191 发送:D1CWLO 回复:^ 发送:I1M100 回复:^B1100

【问题讨论】:

    标签: arduino


    【解决方案1】:

    我的论文工作有一个类似的项目,我通过 arduino uno 从 PC 控制倒立摆。我假设你有一个 PC 程序向 arduino 发送命令,问题是在 Arduino 板上接收和解释它。 我在here的主要帮助(一些复制粘贴修改)下编写了下面的代码

    它基本上是打开 com 端口,然后监听来自 PC 的传入命令。当接收到命令时,它会将其分解(传入的命令采用#00 参数格式)。所有命令都以#开头。下面的2位数字定义了命令本身,后面的文字/数字是命令的参数。

    一旦知道命令及其参数,就可以执行与命令相关的实际过程。在您的情况下,这应该是与传入命令相关的电机控制。下面的代码显然需要更新以匹配您的电机控制功能,但传入的命令处理工作正常。

    String inputString = "";         // a string to hold incoming data
    boolean stringComplete = false;  // whether the incloming string is complete
    
    float kp = 10;     //sample parameter 1
    float kd = 5;      //sample parameter 2
    float ki = 2;      //sample parameter 3
    
    
    void setup() 
    {
      Serial.begin(9600);          //Start serial communication  
      inputString.reserve(200);      //Reserves 200 bytes for the string
    }
    
    void loop()
    {
      //This becomes true when the serial port receives a "\n" character (end of line)
      if (stringComplete)            
      {
        SerialProc();                //the function which runs when a full line is received
        inputString = "";            //once processed, the string is cleared
        stringComplete = false;      //set flag to false to indicate there is nothing in the buffer waiting
      }
    }
    
    void serialEvent()              //This serial event runs between each loop cycles
    {
      while (Serial.available())    //if there is anything in the incoming buffer this while loop runs
      {
        // get the next new byte:
        char inChar = (char)Serial.read(); 
        // add it to the inputString:
        inputString += inChar;
        // if the incoming character is a newline, set a flag
        // so the main loop can do something about it:
        if (inChar == '\n') 
        {
          stringComplete = true;    //This indicates the line is complete, and the main program can process it
        } 
      }
    }
    
    void SerialProc()  //the function which processes the incoming commands. It needs to be modified to your needs
    {
       //cmd is the first three characters of the incoming string / line
       String cmd = inputString.substring(0,3);  //first three characters in incoming string specifies the command
    
       //param is the rest of the string to the end of the line (excluding the first three characters)
       String param = inputString.substring(3, inputString.length());  //rest of incoming string is making up the parameter
    
       //creating a buffer as an array of characters, same size as the length of the parameters string
       char buf[param.length()];
       //moving the parameters from string to the char array
       param.toCharArray(buf,param.length());
    
       //the above string to char array conversion is required for the string to float 
       //conversion below (atof)
    
       //the below part is the command execution. Could have used a switch below, but the series of ifs
       //just did the trick
    
        if (cmd == "#00")
          SendReply();                      //Executing command 1
        else if (cmd == "#01")
          kp = atof(buf);                   //executing command 2 (setting parameter kp)
        else if (cmd == "#02")
          kd = atof(buf);                   //executing command 3 (setting parameter kd)
        else if (cmd == "#03")
          ki = atof(buf);                   //executing command 4 (setting parameter ki)
    }
    
    void SendReply()
    {
      //This is called from the SerialProc function when the #00 command is received
      //After the last parameter (TimeDelay) it sends the carrige return characters via the Serial.println
      Serial.println("reply");
    }
    

    【讨论】:

      猜你喜欢
      • 2014-05-21
      • 2018-12-15
      • 1970-01-01
      • 1970-01-01
      • 2016-02-15
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 1970-01-01
      相关资源
      最近更新 更多