标题:
二轴导轨系统的labview+arduino控制源码
[打印本页]
作者:
4515
时间:
2018-7-6 09:35
标题:
二轴导轨系统的labview+arduino控制源码
二轴导轨系统的labview控制和单片机代码
1.jpg
(40.06 KB, 下载次数: 45)
下载附件
2018-7-7 04:22 上传
0.png
(43.3 KB, 下载次数: 53)
下载附件
2018-7-7 04:23 上传
arduino源程序如下:
#define DirX 22
#define StepX 24
#define EnableX 26
#define ms1X 28
#define ms2X 30
#define ms3X 32
#define sleepX 34
#define resetX 36
#define DirY 23
#define StepY 25
#define EnableY 27
#define ms1Y 29
#define ms2Y 31
#define ms3Y 33
#define sleepY 35
#define resetY 37
int i; //循环计数用
int X; //当前横坐标
int Y; //当前纵坐标
int Xe; //起点横坐标
int Ye; //起点纵坐标
int Xm; //终点横坐标
int Ym; //终点纵坐标
int N; //要走的步数
int Fm; //偏差计算
int du; //画圆弧的度数
int R; //半径
byte comdata[100]={0};//定义数组数据,存放串口接收数据
int mode; //选择要画直线还是画圆弧
int highx=0; //横轴脉冲高电平宽度
int lowx=0; //横轴脉冲低电平宽度
int highy=0; //纵轴脉冲高电平宽度
int lowy=0; //纵轴脉冲低电平宽度
int fenliang=0; //用来计算通信时发送的字符串里的数值
void receive_data(void); //接受串口数据
void count(byte *data); //对串口数据进行处理
void qudong(void); //对驱动进行设置
void directrun(int p,int q); //先X轴后Y轴运动到指定坐标
void circle(void); //插补法圆弧运动到指定坐标(Xm,Ym一开始为绝对起点坐标,Xe,Ye一开始为圆心坐标)
void Npan(void); //判断圆弧运动的N值
void xiangxian1(void); //第一象限圆弧运动(当步数大于0时执行,点在Y轴或步数为0时停止)
void xiangxian2(void); //第二象限圆弧运动(当步数大于0时执行,点在X轴或步数为0时停止)
void xiangxian3(void); //第三象限圆弧运动(当步数大于0时执行,点在Y轴或步数为0时停止)
void xiangxian4(void); //第四象限圆弧运动(当步数大于0时执行,点在X轴或步数为0时停止)
void stringrun(void); //插补法直线运动到指定坐标
void runx1(void); //X轴正方向前进一步
void runx2(void); //X轴负方向前进一步
void runy1(void); //Y轴正方向前进一步
void runy2(void); //Y轴负方向前进一步
void setup()
{
Serial.begin(9600);//Serial.begin(9600)开启串口,通常置于设置()函数中。
//X轴
pinMode(DirX,OUTPUT); // Dir
pinMode(StepX,OUTPUT); // Step
pinMode(EnableX,OUTPUT); // Enable
pinMode(ms1X,OUTPUT); // ms1
pinMode(ms2X,OUTPUT); // ms2
pinMode(ms3X,OUTPUT); // ms3
pinMode(sleepX,OUTPUT); // sleep
pinMode(resetX,OUTPUT); // reset
digitalWrite(DirX,HIGH); // Set Dir high
digitalWrite(EnableX,LOW); // Set Enable low
digitalWrite(ms1X,LOW); // Set ms1 low
digitalWrite(ms2X,LOW); // Set ms2 high
digitalWrite(ms3X,LOW); // Set ms3 low
digitalWrite(sleepX,HIGH); // Set sleep low
digitalWrite(resetX,HIGH); // Set reset low
//Y轴
pinMode(DirY,OUTPUT); // Dir
pinMode(StepY,OUTPUT); // Step
pinMode(EnableY,OUTPUT); // Enable
pinMode(ms1Y,OUTPUT); // ms1
pinMode(ms2Y,OUTPUT); // ms2
pinMode(ms3Y,OUTPUT); // ms3
pinMode(sleepY,OUTPUT); // sleep
pinMode(resetY,OUTPUT); // reset
digitalWrite(DirY,HIGH); // Set Dir high
digitalWrite(EnableY,LOW); // Set Enable low
digitalWrite(ms1Y,LOW); // Set ms1 low
digitalWrite(ms2Y,LOW); // Set ms2 high
digitalWrite(ms3Y,LOW); // Set ms3 low
digitalWrite(sleepY,HIGH); // Set sleep low
digitalWrite(resetY,HIGH); // Set reset low
}
void loop()
{
if(Serial.available()) //Serial.available判断串口缓冲器的状态函数,用以判断数据是否送达串口
{
receive_data(); //接受数据
qudong(); //驱动设置
count(comdata); //数据处理
if(mode==0) //直线模式
stringrun();
if(mode==1) //圆弧模式
circle();
Fm=0;
highx=0;
highy=0;
lowx=0;
lowy=0;
X=0;
Y=0;
Xm=0;
Ym=0;
Xe=0;
Ye=0;
du=0;
}
}
void circle(void) //插补法圆弧运动到指定坐标(Xm,Ym一开始为绝对起点坐标,Xe,Ye一开始为圆心坐标)
{
digitalWrite(DirX,HIGH); // Set Dir high
digitalWrite(DirY,HIGH); // Set Dir high
directrun(Xm,Ym); //运行到起点处
X=Xm; //记录绝对横坐标
Y=Ym; //记录绝对纵坐标
Xm=Xm-Xe; //将Xm设成相对横坐标
Ym=Ym-Ye; //将Ym设成相对纵坐标
Xe=Xm*cos(du); //将Xe设成相对终点横坐标
Ye=Ym*sin(du); //将Ye设成相对终点纵坐标
R=sqrt(Xm^2+Ym^2); //计算半径
Npan(); //计算步数N
if(Xm>=0&&Ym>=0) //起点在第一象限
{
xiangxian1();
xiangxian2();
xiangxian3();
xiangxian4();
}
if(Xm<=0&&Ym>=0) //起点在第二象限
{
xiangxian2();
xiangxian3();
xiangxian4();
xiangxian1();
}
if(Xm<=0&&Ym<=0) //起点在第三象限
{
xiangxian3();
xiangxian4();
xiangxian1();
xiangxian2();
}
if(Xm>=0&&Ym<=0) //起点在第四象限
{
xiangxian4();
xiangxian1();
xiangxian2();
xiangxian3();
}
digitalWrite(DirX,LOW); // Set Dir high
digitalWrite(DirY,LOW); // Set Dir high
directrun(X,Y); //回到原点
}
void xiangxian1(void) //第一象限(当步数大于0时执行,点在Y轴或步数为0时停止)
{
if(N>0)
{
while(1)
{
if(Fm>=0)
{
runx2();
Fm=Fm-2*Xm+1;
Xm=Xm-1;
X=X-1;
N=N-1;
}
if(Fm<0)
{
runy1();
Fm=Fm+2*Ym+1;
Ym=Ym+1;
Y=Y+1;
N=N-1;
}
if(Xm==0||N==0)
break;
}
Fm=0;
}
}
void xiangxian2(void) //第二象限(当步数大于0时执行,点在X轴或步数为0时停止)
{
if(N>0)
{
while(1)
{
if(Fm>=0)
{
runy2();
Fm=Fm-2*Ym+1;
Ym=Ym-1;
Y=Y-1;
N=N-1;
}
if(Fm<0)
{
runx2();
Fm=Fm-2*Xm+1;
Xm=Xm-1;
X=X-1;
N=N-1;
}
if(Ym==0||N==0)
break;
}
Fm=0;
}
}
void xiangxian3(void) //第三象限(当步数大于0时执行,点在Y轴或步数为0时停止)
{
if(N>0)
{
while(1)
{
if(Fm>=0)
{
runx1();
Fm=Fm+2*Xm+1;
Xm=Xm+1;
X=X+1;
N=N-1;
}
if(Fm<0)
{
runy2();
Fm=Fm-2*Ym+1;
Ym=Ym-1;
Y=Y-1;
N=N-1;
}
if(Xm==0||N==0)
break;
}
Fm=0;
}
}
void xiangxian4(void) //第四象限(当步数大于0时执行,点在X轴或步数为0时停止)
{
if(N>0)
{
while(1)
{
if(Fm>=0)
{
runy1();
Fm=Fm+2*Ym+1;
Ym=Ym+1;
Y=Y+1;
N=N-1;
}
if(Fm<0)
{
runx1();
Fm=Fm+2*Xm+1;
Xm=Xm+1;
X=X+1;
N=N-1;
}
if(Ym==0||N==0)
break;
}
Fm=0;
}
}
void Npan(void) //判断圆弧运动的N值
{
if(Xm>=0&&Ym>=0) //起点在第一象限
{
if(Xe>=0&&Ye>=0) //终点在第一象限
{
if(Xe>Xm)
N=Xm+R-Ym+6*R+R-Xe+Ye;
if(Xe<=Xm)
N=Xm-Xe+Ye-Ym;
}
if(Xe<=0&&Ye>=0) //终点在第二象限
N=Xm-Xe+2*R-Ye-Ym;
if(Xe<=0&&Ye<=0) //终点在第三象限
N=Xm+R-Ym+2*R+R-abs(Xe)+abs(Ye);
if(Xe>=0&&Ye<=0) //终点在第四象限
N=Xm+R-Ym+4*R+Xe+R-abs(Ye);
}
if(Xm<=0&&Ym>=0) //起点在第二象限
{
if(Xe>=0&&Ye>=0) //终点在第一象限
N=R-abs(Xm)+Ym+4*R+R-Xe+Ye;
if(Xe<=0&&Ye>=0) //终点在第二象限
{
if(Xe>Xm)
N=R-abs(Xm)+Ym+6*R+abs(Xe)+R-Ye;
if(Xe<Xm)
N=Xm-Xe+Ym-Ye;
}
if(Xe<=0&&Ye<=0) //终点在第三象限
N=R-abs(Xm)+R-abs(Xe)+Ym+abs(Ye);
if(Xe>=0&&Ye<=0) //终点在第四象限
N=R-abs(Xm)+Ym+2*R+Xe+R-abs(Ye);
}
if(Xm<=0&&Ym<=0) //起点在第三象限
{
if(Xe>=0&&Ye>=0) //终点在第一象限
N=abs(Xm)+R-abs(Ym)+2*R+R-Xe+Ye;
if(Xe<=0&&Ye>=0) //终点在第二象限
N=abs(Xm)+R-abs(Ym)+4*R+abs(Xe)+R-Ye;
if(Xe<=0&&Ye<=0) //终点在第三象限
{
if(Xe>Xm)
N=Xe-Xm+Ym-Ye;
if(Xe<Xm)
N=abs(Xm)+R-abs(Ym)+6*R+R-abs(Xe)+abs(Ye);
}
if(Xe>=0&&Ye<=0) //终点在第四象限
N=abs(Xm)+R-abs(Ym)+Xe+R-abs(Ye);
}
if(Xm>=0&&Ym<=0) //起点在第四象限
{
if(Xe>=0&&Ye>=0) //终点在第一象限
N=R-Xm+abs(Ym)+R-Xe+Ye;
if(Xe<=0&&Ye>=0) //终点在第二象限
N=R-Xm+abs(Ym)+2*R+abs(Xe)+R-Ye;
if(Xe<=0&&Ye<=0) //终点在第三象限
N=R-Xm+abs(Ym)+4*R+R-abs(Xe)+abs(Ye);
if(Xe>=0&&Ye<=0) //终点在第四象限
{
if(Xe>Xm)
N=Xe-Xm+Ye-Ym;
if(Xe<Xm)
N=R-Xm+abs(Ym)+6*R+R-abs(Ye)+Xe;
}
}
if(Xm==Xe&&Ym==Ye) //起点和终点重合
N=8*R;
}
void stringrun(void) //插补法直线运动到指定坐标
{
N=abs(Xe-Xm)+abs(Ye-Ym);
digitalWrite(DirX,HIGH); // Set Dir high
digitalWrite(DirY,HIGH); // Set Dir high
directrun(Xm,Ym); //到起点位置
X=Xm;
Y=Ym;
while(N>0) //运行到终点位置
{
if(Fm>=0)
{
runx1();
X=X+1;
N=N-1;
Fm=Fm-Ye;
}
if(Fm<0)
{
runy1();
Y=Y+1;
N=N-1;
Fm=Fm+Xe;
}
}
digitalWrite(DirX,LOW); // Set Dir low
digitalWrite(DirY,LOW); // Set Dir low
directrun(X,Y); //回归到原点位置
}
void directrun(int p,int q) //先X轴后Y轴运动到指定坐标
{
for(i=0;i<p;i++)
{
digitalWrite(StepX,HIGH); // Step high
delayMicroseconds(highx); // Wait 1/2 a ms
digitalWrite(StepX,LOW); // Step low
delayMicroseconds(lowx); // Wait 1/2 a ms
}
delay(1000); // pause one second
for(i=0;i<q;i++)
{
digitalWrite(StepY,HIGH); // Step high
delayMicroseconds(highy); // Wait 1/2 a ms
digitalWrite(StepY,LOW); // Step low
delayMicroseconds(lowy); // Wait 1/2 a ms
}
delay(1000); // pause one second
}
void runx1(void) //X轴正方向前进一步
{
digitalWrite(DirX,HIGH); // Set Dir low
digitalWrite(StepX,HIGH); // Step high
delayMicroseconds(highx); // Wait 1/2 a ms
digitalWrite(StepX,LOW); // Step low
delayMicroseconds(lowx); // Wait 1/2 a ms
}
void runx2(void) //X轴负方向前进一步
{
digitalWrite(DirX,LOW); // Set Dir low
digitalWrite(StepX,HIGH); // Step high
delayMicroseconds(highx); // Wait 1/2 a ms
digitalWrite(StepX,LOW); // Step low
delayMicroseconds(lowx); // Wait 1/2 a ms
}
void runy1(void) //Y轴正方向前进一步
{
digitalWrite(DirY,HIGH); // Set Dir high
digitalWrite(StepY,HIGH); // Step high
delayMicroseconds(highy); // Wait 1/2 a ms
digitalWrite(StepY,LOW); // Step low
delayMicroseconds(lowy); // Wait 1/2 a ms
}
void runy2(void) //Y轴负方向前进一步
{
digitalWrite(DirY,LOW); // Set Dir high
digitalWrite(StepY,HIGH); // Step high
delayMicroseconds(highy); // Wait 1/2 a ms
digitalWrite(StepY,LOW); // Step low
delayMicroseconds(lowy); // Wait 1/2 a ms
}
void receive_data(void)
{
for(i=0;i<100; )
{
comdata[i]=Serial.read();
delay(2);//延时一会,让串口缓存准备好下一个字节,不延时可能会导致数据丢失
i++;
if(comdata[0]==0)
{
if(i==15+comdata[4]+comdata[5]+comdata[6]+comdata[7]+comdata[11]+comdata[12]+comdata[13]+comdata[14])
break;
}
else
{
if(i==18+comdata[4]+comdata[5]+comdata[6]+comdata[7]+comdata[11]+comdata[12]+comdata[13]+comdata[14])
break;
}
}
}
void count(byte *data)
{
//x轴
for(i=0;i<data[4];i++) //计算高电平宽度
{
fenliang=data[15+i]*pow(10,data[4]-i-1);
highx=highx+fenliang;
}
for(i=0;i<data[5];i++) //计算低电平宽度
{
fenliang=data[15+data[4]+i]*pow(10,data[5]-i-1);
lowx=lowx+fenliang;
}
for(i=0;i<data[6];i++) //计算横坐标起点位置
{
fenliang=data[15+data[4]+data[5]+i]*pow(10,data[6]-i-1);
Xm =Xm+ fenliang;
}
for(i=0;i<data[7];i++) //计算横坐标终点位置
{
fenliang=data[15+data[4]+data[5]+data[6]+i]*pow(10,data[7]-i-1);
Xe =Xe+ fenliang;
}
//y轴
for(i=0;i<data[11];i++) //计算高电平宽度
{
fenliang=data[15+data[4]+data[5]+data[6]+data[7]+i]*pow(10,data[11]-i-1);
highy=highy+fenliang;
}
for(i=0;i<data[12];i++) //计算低电平宽度
{
fenliang=data[15+data[4]+data[5]+data[6]+data[7]+data[11]+i]*pow(10,data[12]-i-1);
lowy=lowy+fenliang;
}
for(i=0;i<data[13];i++) //计算纵坐标起点位置
{
fenliang=data[15+data[4]+data[5]+data[6]+data[7]+data[11]+data[12]+i]*pow(10,data[13]-i-1);
Ym =Ym+ fenliang;
}
for(i=0;i<data[14];i++) //计算纵坐标终点位置
{
fenliang=data[15+data[4]+data[5]+data[6]+data[7]+data[11]+data[12]+data[13]+i]*pow(10,data[14]-i-1);
Ye =Ye+ fenliang;
}
for(i=0;i<data[15+data[4]+data[5]+data[6]+data[7]+data[11]+data[12]+data[13]+data[14]];i++) //计算度数
{
fenliang=data[16+data[4]+data[5]+data[6]+data[7]+data[11]+data[12]+data[13]+data[14]+i]*pow(10,data[15+data[4]+data[5]+data[6]+data[7]+data[11]+data[12]+data[13]+data[14]]-i-1);
du =du+ fenliang;
}
}
void qudong(void)
{
if(comdata[0]==0)
mode=0; // 直线模式
else
mode=1; // 圆弧模式
if(comdata[1]==0) // 全步进
{
digitalWrite(ms1X,LOW);
digitalWrite(ms2X,LOW);
digitalWrite(ms3X,LOW);
}
if(comdata[1]==1) // 半步进
{
digitalWrite(ms1X,HIGH);
digitalWrite(ms2X,LOW);
digitalWrite(ms3X,LOW);
}
if(comdata[1]==2) // 四分之一步进
{
digitalWrite(ms1X,LOW);
digitalWrite(ms2X,HIGH);
digitalWrite(ms3X,LOW);
}
if(comdata[1]==3) // 八分之一步进
{
digitalWrite(ms1X,HIGH);
digitalWrite(ms2X,HIGH);
digitalWrite(ms3X,LOW);
}
if(comdata[1]==4) // 十六分之一步进
{
digitalWrite(ms1X,HIGH);
digitalWrite(ms2X,HIGH);
digitalWrite(ms3X,HIGH);
}
if(comdata[2]==1)
digitalWrite(sleepX,HIGH); // Set sleep high
else
digitalWrite(sleepX,LOW); // Set sleep low
if(comdata[3]==1)
digitalWrite(resetX,HIGH); // Set reset high
else
digitalWrite(resetX,LOW); // Set reset low
//y轴
if(comdata[8]==0) // 全步进
{
digitalWrite(ms1Y,LOW);
digitalWrite(ms2Y,LOW);
digitalWrite(ms3Y,LOW);
}
if(comdata[8]==1) // 半步进
{
digitalWrite(ms1Y,HIGH);
digitalWrite(ms2Y,LOW);
digitalWrite(ms3Y,LOW);
}
if(comdata[8]==2) // 四分之一步进
{
digitalWrite(ms1Y,LOW);
digitalWrite(ms2Y,HIGH);
digitalWrite(ms3Y,LOW);
}
if(comdata[8]==3) // 八分之一步进
{
digitalWrite(ms1Y,HIGH);
digitalWrite(ms2Y,HIGH);
digitalWrite(ms3Y,LOW);
}
if(comdata[8]==4) // 十六分之一步进
{
digitalWrite(ms1Y,HIGH);
digitalWrite(ms2Y,HIGH);
digitalWrite(ms3Y,HIGH);
}
if(comdata[9]==1)
digitalWrite(sleepY,HIGH); // Set sleep high
else
digitalWrite(sleepY,LOW); // Set sleep low
if(comdata[10]==1)
digitalWrite(resetY,HIGH); // Set reset high
else
digitalWrite(resetY,LOW); // Set reset low
}
复制代码
所有资料51hei提供下载:
test 0405.rar
(103.78 KB, 下载次数: 23)
2018-7-6 09:35 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1