卓泰科技 发表于 2015-2-24 18:03 外部定时器 + arduino的外部中断? |
想要精确输出脉冲,试试定时器 |
大材小用,泪流满面的arduino 对于步进电机驱动器的控制要点在于,输出脉冲的尽量稳定。这就要求,充当控制器的单片机要专注,尽量减少其他无关的事情 比如串口通信,在9600下,哪怕4个字节的接收,也会带来3.6ms的延迟,在400us为周期下,这就是9个脉冲周期了 所以,如果字节数太多,就必然影响脉冲,所以,单字节控制,依靠ASCII码进行定义的控制方式就出现了~~~
|
djc5-3 反向时减速在加速的过程太快,导致噪音,所以直接去掉 /* 纯串口控制 加入脱机控制 */ //电机的高电平持续时间 us int maichongjiangeMax=1260; int maichongjiangeMin=120; long maichongjiangeSet=600; //电机的高电平持续时间的初始值 0us int maichongjiange=0; //脉冲的占空比为1/maichongzhankongbi int maichongzhankongbi=4; //加减速时速度每隔300us变化一次 int jiajiansubianhuashijian=300; //////////////////////////////////////////// int kongzhifangshi;//控制方式,低电平则为串口控制,高电平为按键控制 int jsq1=0; int tempint; char kongzhimingling[5]; boolean testxinxi=0; boolean fangxiang=0;//电机转动方向标识 int maichongjsq=0;//脉冲计数器 unsigned long time1=micros(); unsigned long time2=micros(); void setup(){ //为防止意外,先行定义为20%的运行速度 kongzhimingling[0]=fangxiang+48; kongzhimingling[1]=49; kongzhimingling[2]=48; kongzhimingling[3]=79;//ascII 79=O ON Serial.begin(9600); /* 暂定A0 analogRead(0)的值来确定转速 为方便演示,此处为使用1K 多圈精密可调电阻,A0就接在中间脚上 那么可见,其电压大致为0-5v之间,现在就电压区间进行分级 如果粗分为10档,就意味着每100个返回单位对应10%的速度 */ pinMode(7, OUTPUT);// EN+,脱机,高电平有效 pinMode(8, OUTPUT);// CW+,方向 pinMode(9, OUTPUT);// CLK+,频率(转速) digitalWrite(7, HIGH);//电机默认脱机 digitalWrite(8, LOW);// digitalWrite(9, LOW); } void loop(){ while (Serial.available() > 0) { //格式:方向(1位),速度百分比(2位),脱机(1位) 如012O / 012F //kongzhimingling[jsq1]= Serial.read(); tempint=Serial.read(); if(jsq1==0){ if(tempint==48 || tempint==49)kongzhimingling[0]= tempint; }else if(jsq1==1 || jsq1==2){ if(tempint>47 && tempint<58)kongzhimingling[jsq1]= tempint; }else if(jsq1==3){ if(tempint==79 || tempint==70) kongzhimingling[3]= tempint; } if(jsq1<3)delayMicroseconds(1200); jsq1++; testxinxi=1; } if(testxinxi){ testxinxi=0; jsq1=0; Serial.print("get:"); Serial.println(kongzhimingling); //脱机 if(kongzhimingling[3]==79)digitalWrite(7, LOW); else if(kongzhimingling[3]==70){ digitalWrite(7, HIGH); Serial.println("off-line"); } //速度调节 maichongjiangeSet = 625/(0.5+4.5*((kongzhimingling[1]-48)*10+kongzhimingling[2]-48)/100);//0-1023 Serial.print("maichongjiangeSet:"); Serial.println(maichongjiangeSet); //方向调节 if(kongzhimingling[0]-48 != fangxiang){ //有效高电平且现在电机转速与设置相反 Serial.println("change"); //2、记录新的方向 fangxiang=!fangxiang; //3、反方向 digitalWrite(8, fangxiang); }else Serial.println("keep"); } //加速过程 while(maichongjiange>maichongjiangeSet){ jiasu(); maichongqudong(); } //加减过程 while(maichongjiange<maichongjiangeSet){ jiansu(); maichongqudong(); } //在脉冲频率无变化的时候驱动电机正常运行 maichongqudong(); } void jiasu() //脉冲加速过程 { if(micros()-time1>jiajiansubianhuashijian && maichongjiange>maichongjiangeMin){//加速过程,xxx us加速一次,加速到 yyy为止 maichongjiange--; time1=micros(); } } void jiansu()//脉冲减速过程 { if(micros()-time1>jiajiansubianhuashijian && maichongjiange<maichongjiangeMax){ maichongjiange++; time1=micros(); } } void maichongqudong()//脉冲驱动 { //步进电机控制脉冲 if (micros()-time2 > maichongjiange){ maichongjsq++;//每过一个“脉冲间隔”时间段,则“脉冲计数器”自增1 maichongjsq=maichongjsq%maichongzhankongbi;//对“脉冲计数器”取模,这个取摸结果实质就是对占空比的调节(占空比为1/模),以4为例,则“脉冲计数器”的变化为:0——1——2——3——0 if(maichongjsq==0)digitalWrite(9, HIGH);//输出控制步进电机的电平 else digitalWrite(9, LOW); time2= micros(); } } |
卓泰科技 发表于 2015-2-19 18:11 上程序,蓝牙的 控制上 正:1 反:0 速度上:axx,a其实是占位符
|
囧囧大神威武 |
|
|Archiver|手机版|狗趴(GodPub) Arduino&Raspberry Pi开源硬件学习与实践[QQ群:20085629]
GMT+8, 2024-5-14 18:43 , Processed in 0.052376 second(s), 34 queries .
Powered by Discuz! X3.2
© 2001-2013 Comsenz Inc.