我尝试用一个使用协议的程序来控制步进电机(见下文) 我能够使用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 将电机的速度设置为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 旋转停止。 旋转样本命令序列
电机编号作为字符传递,但为简单起见,步数和速度作为3字节的二进制传递。 发送:V回复:^ R1R2R3R4 发送:S1M1791回复:^ 191 发送:D1CWLO回复:^ 发送:I1M100回复:^ B1100
答案 0 :(得分:0)
我的论文工作有一个类似的项目,我通过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");
}