[arduino] 菜鸟玩步进电机 与 TB6560 驱动频率的测试

http://www.tudou.com/programs/view/4gizAAwbJS8/




一个可变电阻+2个微动的程序

//电机的高电平持续时间 us
int maichongjiangeMax=8000;
int maichongjiangeMin=100;
long maichongjiangeSet;
 
//电机的高电平持续时间的初始值 8000us
int maichongjiange=8000;
 
//脉冲的占空比为1/maichongzhankongbi
int maichongzhankongbi=4;
 
//加减速时速度每隔300us变化一次
int jiajiansubianhuashijian=300;
 
 
////////////////////////////////////////////
 
int Pinval;//存储IO口(Pin5、Pin6)高低电平的值
 
boolean fangxiang=0;//电机转动方向标识
int maichongjsq=0;//脉冲计数器
 
 
unsigned long time1=micros();
unsigned long time2=micros();
 
 
void setup(){
 
 Serial.begin(9600);
 
 //pin5(High pin8 输出 LOW 默认)、pin6(High pin8 输出 High 方向) 输入状态,就读取值来确定电机的转动方向
 pinMode(5, INPUT);  
 pinMode(6, INPUT);  
 
/*
暂定A0 analogRead(0)的值来确定转速
为方便演示,此处为使用1K 多圈精密可调电阻,A0就接在中间脚上
那么可见,其电压大致为0-5v之间,现在就电压区间进行分级
如果粗分为10档,就意味着每100个返回单位对应10%的速度
*/
 
pinMode(7, OUTPUT);// EN+,脱机,高电平有效
pinMode(8, OUTPUT);// CW+,方向
pinMode(9, OUTPUT);// CLK+,频率(转速)
 
digitalWrite(7, LOW);//电机默认联机
digitalWrite(8, LOW);//
digitalWrite(9, LOW);
}
 
 
void loop(){
 
 
 
 
 //转速调节,通过可变电阻实现无极调速
 
  //可能是读取过于频繁,导致夹杂着无效数值,所以此处做个循环
  do
  {
maichongjiangeSet = analogRead(0);//0-1023
}while(maichongjiangeSet >1024);
 
  maichongjiangeSet = maichongjiangeSet*(maichongjiangeMax-maichongjiangeMin)/1024+maichongjiangeMin;//0-1023
 
 
 //加速过程
 while(maichongjiange>maichongjiangeSet){
  jiasu();
  maichongqudong();
  }
 
  //加减过程
 while(maichongjiange<maichongjiangeSet){
  jiansu();
  maichongqudong();
  }
 
 //在脉冲频率无变化的时候驱动电机正常运行
 maichongqudong();
 
 
fangxiangchange(); //转动方向的切换
 
 
}
 
 
 
 
 
 
 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();
 }
 
}
 
 
 void fangxiangchange() //转动方向的切换
 {
 
 
 
  //关于反向,虽然直接对引脚进行控制也是可以的,但加入一个,减速——取反——加速的过程应该更好
 /*本例中,
pin7, EN+,脱机,高电平有效
pin8, CW+,方向
pin9, CLK+,频率(转速)
已经用掉了,假设加减速、方向都由外部控制,那么很显然,就会出现2种控制方式:
A、模拟方式,即通过测量2个点电阻变化所导致的分压变化,即可实现强弱、方向的调节,具体类似于ACS712的读取,此方式可以类似于“无级变速”
B、数字方式,即通过摇杆或4个微动开关,来分别实现加减速、方向的切换
 
就实际操作而言,速度上测电阻分压,方向上用微动开关比较合适,即用2个数字口+1个PWM口实现具体控制
 */
 
 Pinval = digitalRead(5);  //pin5(High pin8 输出 LOW 默认)、pin6(High pin8 输出 High 方向)
 
 if(Pinval==1 && fangxiang){ //有效高电平且现在电机转速与设置相反
 
 //1、把速度降到最低
 while(maichongjiange<maichongjiangeMax){
 jiansu();
 maichongqudong();
   }
 //2、反方向
 digitalWrite(8, LOW);
 //3、记录新的方向
 fangxiang=0;
 //4、在把速度加到原来值
 while(maichongjiange<maichongjiangeSet){
 jiasu();
 maichongqudong();
   }
 
 }
 
 Pinval = digitalRead(6);  //pin5(High pin8 输出 LOW 默认)、pin6(High pin8 输出 High 方向)
 
 if(Pinval==1 && !fangxiang){ //有效高电平且现在电机转速与设置相反
 
 //1、把速度降到最低
 while(maichongjiange<maichongjiangeMax){
 jiansu();
 maichongqudong();
   }
 //2、反方向
 digitalWrite(8, HIGH);
 //3、记录新的方向
 fangxiang=1;
 //4、在把速度加到原来值
 while(maichongjiange<maichongjiangeSet){
 jiasu();
 maichongqudong();
   }
 
 }
 
 
 
 
 }

maichongjiangeSet = maichongjiangeSet*(maichongjiangeMax-maichongjiangeMin)/1024+maichongjiangeMin
转速=1000000*1.8/maichongjiangeSet

在说一下这个程序的特色,即分压阻值与转速是幂函数,即转速=1/(a*R+b),

类似于下图:X轴是阻值,Y轴是转速


简单来说,就是虽然阻值的变化是线性的,但速度的增加却是指数型的
具体来说就是,开始的时候,速度变化很快,而后变化越发的不明显
这个对手动调节来说,恐怕不是很舒服,所以解决方式为:
1、对阻值与速度进行手工映射
2、修改速度与阻值的对应关系

//电机的高电平持续时间 us
int maichongjiangeMax=3584;
int maichongjiangeMin=207;
long maichongjiangeSet;
 
//电机的高电平持续时间的初始值 8000us
int maichongjiange=8000;
 
//脉冲的占空比为1/maichongzhankongbi
int maichongzhankongbi=4;
 
//加减速时速度每隔300us变化一次
int jiajiansubianhuashijian=100;
 
 
////////////////////////////////////////////
 
int Pinval;//存储IO口(Pin5、Pin6)高低电平的值
 
boolean fangxiang=0;//电机转动方向标识
int maichongjsq=0;//脉冲计数器
 
 
unsigned long time1=micros();
unsigned long time2=micros();
 
 
void setup(){
 
 Serial.begin(9600);
 
 //pin5(High pin8 输出 LOW 默认)、pin6(High pin8 输出 High 方向) 输入状态,就读取值来确定电机的转动方向
 pinMode(5, INPUT);  
 pinMode(6, INPUT);  
 
/*
暂定A0 analogRead(0)的值来确定转速
为方便演示,此处为使用1K 多圈精密可调电阻,A0就接在中间脚上
那么可见,其电压大致为0-5v之间,现在就电压区间进行分级
如果粗分为10档,就意味着每100个返回单位对应10%的速度
*/
 
pinMode(7, OUTPUT);// EN+,脱机,高电平有效
pinMode(8, OUTPUT);// CW+,方向
pinMode(9, OUTPUT);// CLK+,频率(转速)
 
digitalWrite(7, LOW);//电机默认联机
digitalWrite(8, LOW);//
digitalWrite(9, LOW);
}
 
 
void loop(){
 
 
 
 
 //转速调节,通过可变电阻实现无极调速
 
  //可能是读取过于频繁,导致夹杂着无效数值,所以此处做个循环
  do
  {
maichongjiangeSet = analogRead(0);//0-1023
}while(maichongjiangeSet >1024);
 
 //被注释掉的,其起转速随测试点的电压降低而成指数增加,简单的说就是不好控制,开始太慢,之后激增
 // maichongjiangeSet = maichongjiangeSet*(maichongjiangeMax-maichongjiangeMin)/1024+maichongjiangeMin;//0-1023
 //映射表 28段
 /*
 1/2细分                                                        对应分压
R/min        步/s        us/步 占空比25%        序号        1024
180         1200         833         208         1        922 
162         1080         926         231         2        829 
146         972         1029         257         3        746 
131         875         1143         286         4        672 
118         787         1270         318         5        605 
106         709         1411         353         6        544 
96                 638         1568         392         7        490 
86                 574         1742         436         8        441 
77                 517         1936         484         9        397 
70                 465         2151         538         10        357 
63                 418         2390         597         11        321 
56                 377         2656         664         12        289 
51                 339         2951         738         13        260 
46                 305         3278         820         14        234 
41                 275         3643         911         15        211 
37                 247         4047         1012         16        190 
33                 222         4497         1124         17        171 
30                 200         4997         1249         18        154 
27                 180         5552         1388         19        138 
24                 162         6169         1542         20        124 
22                 146         6854         1714         21        112 
20                 131         7616         1904         22        101 
18                 118         8462         2116         23        91 
16                 106         9402         2351         24        82 
14                 96                 10447         2612         25        74 
13                 86                 11608         2902         26        66 
12                 78                 12898         3224         27        60 
10                 70                 14331         3583         28        54 
 
 */
 if(maichongjiangeSet>922)maichongjiangeSet=208;
 else if(maichongjiangeSet>829)maichongjiangeSet=231;
 else if(maichongjiangeSet>746)maichongjiangeSet=257;
 else if(maichongjiangeSet>672)maichongjiangeSet=282;
 else if(maichongjiangeSet>605)maichongjiangeSet=318;
 else if(maichongjiangeSet>544)maichongjiangeSet=353;
 else if(maichongjiangeSet>490)maichongjiangeSet=392;
 else if(maichongjiangeSet>441)maichongjiangeSet=436;
  else if(maichongjiangeSet>397)maichongjiangeSet=484;
  else if(maichongjiangeSet>357)maichongjiangeSet=538;
  else if(maichongjiangeSet>321)maichongjiangeSet=597;
  else if(maichongjiangeSet>289)maichongjiangeSet=664;
  else if(maichongjiangeSet>260)maichongjiangeSet=738;
  else if(maichongjiangeSet>234)maichongjiangeSet=820;
   else if(maichongjiangeSet>211)maichongjiangeSet=911;
   else if(maichongjiangeSet>190)maichongjiangeSet=1012;
   else if(maichongjiangeSet>171)maichongjiangeSet=1124;
   else if(maichongjiangeSet>154)maichongjiangeSet=1249;
   else if(maichongjiangeSet>138)maichongjiangeSet=1388;
   else if(maichongjiangeSet>124)maichongjiangeSet=1542;
   else if(maichongjiangeSet>112)maichongjiangeSet=1714;
   else if(maichongjiangeSet>101)maichongjiangeSet=1904;
   else if(maichongjiangeSet>91)maichongjiangeSet=2116;
   else if(maichongjiangeSet>82)maichongjiangeSet=2351;
   else if(maichongjiangeSet>74)maichongjiangeSet=2612;
   else if(maichongjiangeSet>66)maichongjiangeSet=2902;
   else if(maichongjiangeSet>60)maichongjiangeSet=3224;
   else maichongjiangeSet=3583;
 //min
 
 
 
 
 
 
 
 //加速过程
 while(maichongjiange>maichongjiangeSet){
  jiasu();
  maichongqudong();
  }
 
  //加减过程
 while(maichongjiange<maichongjiangeSet){
  jiansu();
  maichongqudong();
  }
 
 //在脉冲频率无变化的时候驱动电机正常运行
 maichongqudong();
 
 
fangxiangchange(); //转动方向的切换
 
 
}
 
 
 
 
 
 
 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();
 }
 
}
 
 
 void fangxiangchange() //转动方向的切换
 {
 
 
 
  //关于反向,虽然直接对引脚进行控制也是可以的,但加入一个,减速——取反——加速的过程应该更好
 /*本例中,
pin7, EN+,脱机,高电平有效
pin8, CW+,方向
pin9, CLK+,频率(转速)
已经用掉了,假设加减速、方向都由外部控制,那么很显然,就会出现2种控制方式:
A、模拟方式,即通过测量2个点电阻变化所导致的分压变化,即可实现强弱、方向的调节,具体类似于ACS712的读取,此方式可以类似于“无级变速”
B、数字方式,即通过摇杆或4个微动开关,来分别实现加减速、方向的切换
 
就实际操作而言,速度上测电阻分压,方向上用微动开关比较合适,即用2个数字口+1个PWM口实现具体控制
 */
 
 Pinval = digitalRead(5);  //pin5(High pin8 输出 LOW 默认)、pin6(High pin8 输出 High 方向)
 
 if(Pinval==1 && fangxiang){ //有效高电平且现在电机转速与设置相反
 
 //1、把速度降到最低
 while(maichongjiange<maichongjiangeMax){
 jiansu();
 maichongqudong();
   }
 //2、反方向
 digitalWrite(8, LOW);
 //3、记录新的方向
 fangxiang=0;
 //4、在把速度加到原来值
 while(maichongjiange<maichongjiangeSet){
 jiasu();
 maichongqudong();
   }
 
 }
 
 Pinval = digitalRead(6);  //pin5(High pin8 输出 LOW 默认)、pin6(High pin8 输出 High 方向)
 
 if(Pinval==1 && !fangxiang){ //有效高电平且现在电机转速与设置相反
 
 //1、把速度降到最低
 while(maichongjiange<maichongjiangeMax){
 jiansu();
 maichongqudong();
   }
 //2、反方向
 digitalWrite(8, HIGH);
 //3、记录新的方向
 fangxiang=1;
 //4、在把速度加到原来值
 while(maichongjiange<maichongjiangeSet){
 jiasu();
 maichongqudong();
   }
 
 }
 
 
 
 
 }

但映射版也有问题:
1、就实际感知而言,初期确实有点慢,人的感官也远不数字精确,依旧觉得前期慢,后期快
2、多圈的精密电阻,却是太难调节了

所以,具体的映射恐怕还要修改

尼玛只要把电阻分压对应到圈/每秒上,就能实现感官上的无极调速
我TM前面的程序怎么写成对应周期长度了


//电机的高电平持续时间 us
int maichongjiangeMax=1260;
int maichongjiangeMin=120;
long maichongjiangeSet;

//电机的高电平持续时间的初始值 0us
int maichongjiange=0;

//脉冲的占空比为1/maichongzhankongbi
int maichongzhankongbi=4;

//加减速时速度每隔300us变化一次
int jiajiansubianhuashijian=300;


////////////////////////////////////////////

int Pinval;//存储IO口(Pin5、Pin6)高低电平的值

boolean fangxiang=0;//电机转动方向标识
int maichongjsq=0;//脉冲计数器
 
 
unsigned long time1=micros();
unsigned long time2=micros();

 
void setup(){
 
 Serial.begin(9600);
 
 //pin5(High pin8 输出 LOW 默认)、pin6(High pin8 输出 High 方向) 输入状态,就读取值来确定电机的转动方向
 pinMode(5, INPUT);  
 pinMode(6, INPUT);  
 
/*
暂定A0 analogRead(0)的值来确定转速
为方便演示,此处为使用1K 多圈精密可调电阻,A0就接在中间脚上
那么可见,其电压大致为0-5v之间,现在就电压区间进行分级
如果粗分为10档,就意味着每100个返回单位对应10%的速度
*/
 
pinMode(7, OUTPUT);// EN+,脱机,高电平有效
pinMode(8, OUTPUT);// CW+,方向
pinMode(9, OUTPUT);// CLK+,频率(转速)
 
digitalWrite(7, LOW);//电机默认联机
digitalWrite(8, LOW);//
digitalWrite(9, LOW);
}
 
 
void loop(){
 


 
 //转速调节,通过可变电阻实现无极调速
 
  //可能是读取过于频繁,导致夹杂着无效数值,所以此处做个循环
  do
  {
maichongjiangeSet = analogRead(0);//0-1023
}while(maichongjiangeSet >1024);
 
 // 25% us =1000,000/(圈/每秒*400*4)=625/(0.5【min】+4.5×analogRead(0)/1024)
 //即把电压线性到转速上
  maichongjiangeSet = 625/(0.5+4.5*maichongjiangeSet/1024);//0-1023
 
 
 //加速过程
 while(maichongjiange>maichongjiangeSet){
  jiasu();
  maichongqudong();
  }

  //加减过程
 while(maichongjiange<maichongjiangeSet){
  jiansu();
  maichongqudong();
  }
 
 //在脉冲频率无变化的时候驱动电机正常运行
 maichongqudong();
 
 
fangxiangchange(); //转动方向的切换
 

}
 
 
 



 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();
 }

}
 

 void fangxiangchange() //转动方向的切换
 {
 
 
 
  //关于反向,虽然直接对引脚进行控制也是可以的,但加入一个,减速——取反——加速的过程应该更好
 /*本例中,
pin7, EN+,脱机,高电平有效
pin8, CW+,方向
pin9, CLK+,频率(转速)
已经用掉了,假设加减速、方向都由外部控制,那么很显然,就会出现2种控制方式:
A、模拟方式,即通过测量2个点电阻变化所导致的分压变化,即可实现强弱、方向的调节,具体类似于ACS712的读取,此方式可以类似于“无级变速”
B、数字方式,即通过摇杆或4个微动开关,来分别实现加减速、方向的切换

就实际操作而言,速度上测电阻分压,方向上用微动开关比较合适,即用2个数字口+1个PWM口实现具体控制
 */

 Pinval = digitalRead(5);  //pin5(High pin8 输出 LOW 默认)、pin6(High pin8 输出 High 方向)

 if(Pinval==1 && fangxiang){ //有效高电平且现在电机转速与设置相反

 //1、把速度降到最低
 while(maichongjiange<maichongjiangeMax){
 jiansu();
 maichongqudong();
   }
 //2、反方向
 digitalWrite(8, LOW);
 //3、记录新的方向
 fangxiang=0;
 //4、在把速度加到原来值
 while(maichongjiange<maichongjiangeSet){
 jiasu();
 maichongqudong();
   }
 
 }
 
 Pinval = digitalRead(6);  //pin5(High pin8 输出 LOW 默认)、pin6(High pin8 输出 High 方向)

 if(Pinval==1 && !fangxiang){ //有效高电平且现在电机转速与设置相反

 //1、把速度降到最低
 while(maichongjiange<maichongjiangeMax){
 jiansu();
 maichongqudong();
   }
 //2、反方向
 digitalWrite(8, HIGH);
 //3、记录新的方向
 fangxiang=1;
 //4、在把速度加到原来值
 while(maichongjiange<maichongjiangeSet){
 jiasu();
 maichongqudong();
   }
 
 }
 
 
 
 
 }
 

 

25% 周期长度us——步进电机的分贝数


为了控制的迁移,串口控制是必须的:

当然,还是有待完善的地方,那就是对于串口字符串的检验


/*
djc3 无极调速 + 串口控制
规定Pin4口为一个判断点,
低电平则为串口控制,高电平为按键控制
 
 
*/
 
 
//电机的高电平持续时间 us
int maichongjiangeMax=1260;
int maichongjiangeMin=120;
long maichongjiangeSet;
 
//电机的高电平持续时间的初始值 0us
int maichongjiange=250;
 
//脉冲的占空比为1/maichongzhankongbi
int maichongzhankongbi=4;
 
//加减速时速度每隔300us变化一次
int jiajiansubianhuashijian=300;
 
 
////////////////////////////////////////////
int kongzhifangshi;//控制方式,低电平则为串口控制,高电平为按键控制
int jsq1=0;
char kongzhimingling[4];
boolean testxinxi=0;
 
int Pinval;//存储IO口(Pin5、Pin6)高低电平的值
 
boolean fangxiang=0;//电机转动方向标识
int maichongjsq=0;//脉冲计数器
 
 
unsigned long time1=micros();
unsigned long time2=micros();
 
 
void setup(){
 
 Serial.begin(9600);
 
 //pin5(High pin8 输出 LOW 默认)、pin6(High pin8 输出 High 方向) 输入状态,就读取值来确定电机的转动方向
 pinMode(5, INPUT);  
 pinMode(6, INPUT);  
 
/*
暂定A0 analogRead(0)的值来确定转速
为方便演示,此处为使用1K 多圈精密可调电阻,A0就接在中间脚上
那么可见,其电压大致为0-5v之间,现在就电压区间进行分级
如果粗分为10档,就意味着每100个返回单位对应10%的速度
*/
 
pinMode(7, OUTPUT);// EN+,脱机,高电平有效
pinMode(8, OUTPUT);// CW+,方向
pinMode(9, OUTPUT);// CLK+,频率(转速)
 
digitalWrite(7, LOW);//电机默认联机
digitalWrite(8, LOW);//
digitalWrite(9, LOW);
}
 
 
void loop(){
 
 kongzhifangshi = digitalRead(4); 
 
if(kongzhifangshi==1){
 
 //转速调节,通过可变电阻实现无极调速
 
  //可能是读取过于频繁,导致夹杂着无效数值,所以此处做个循环
  do
  {
maichongjiangeSet = analogRead(0);//0-1023
}while(maichongjiangeSet >1024);
 
 // 25% us =1000,000/(圈/每秒*400*4)=625/(0.5【min】+4.5×analogRead(0)/1024)
 //即把电压线性到转速上
  maichongjiangeSet = 625/(0.5+4.5*maichongjiangeSet/1024);//0-1023
 
 fangxiangchange(); //转动方向的切换
 
}else{
 
 
   while (Serial.available() > 0) {
 
   //格式:方向(1位),速度百分比(2位) 如012
   kongzhimingling[jsq1]= Serial.read();
 
 
delayMicroseconds(1200);
jsq1++;
if(jsq1==3) jsq1=0;
 
testxinxi=1;
  }
 
  if(testxinxi){
   testxinxi=0;
   jsq1=0;
   Serial.print("get:");
   Serial.println(kongzhimingling);  
   //速度调节
 
 
   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.print("bian");
 
 
   //1、把速度降到最低
   while(maichongjiange<maichongjiangeMax){
   jiansu();
   maichongqudong();
   }
 
   Serial.println("jiansuOK");
 
   //2、记录新的方向
   fangxiang=!fangxiang;
 
   //3、反方向
   digitalWrite(8, fangxiang);
 
   //4、在把速度加到原来值
   while(maichongjiange<maichongjiangeSet){
   jiasu();
   maichongqudong();
   }
 
   Serial.println("jiasuOK");
 
   }else  Serial.print("baochi");
 
 
   }
 
 
 
 
}
 
 
 
 //加速过程
 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();
 }
 
}
 
 
 void fangxiangchange() //转动方向的切换
 {
 
 
 
  //关于反向,虽然直接对引脚进行控制也是可以的,但加入一个,减速——取反——加速的过程应该更好
 /*本例中,
pin7, EN+,脱机,高电平有效
pin8, CW+,方向
pin9, CLK+,频率(转速)
已经用掉了,假设加减速、方向都由外部控制,那么很显然,就会出现2种控制方式:
A、模拟方式,即通过测量2个点电阻变化所导致的分压变化,即可实现强弱、方向的调节,具体类似于ACS712的读取,此方式可以类似于“无级变速”
B、数字方式,即通过摇杆或4个微动开关,来分别实现加减速、方向的切换
 
就实际操作而言,速度上测电阻分压,方向上用微动开关比较合适,即用2个数字口+1个PWM口实现具体控制
 */
 
 Pinval = digitalRead(5);  //pin5(High pin8 输出 LOW 默认)、pin6(High pin8 输出 High 方向)
 
 if(Pinval==1 && fangxiang){ //有效高电平且现在电机转速与设置相反
 
 //1、把速度降到最低
 while(maichongjiange<maichongjiangeMax){
 jiansu();
 maichongqudong();
   }
 //2、反方向
 digitalWrite(8, LOW);
 //3、记录新的方向
 fangxiang=0;
 //4、在把速度加到原来值
 while(maichongjiange<maichongjiangeSet){
 jiasu();
 maichongqudong();
   }
 
 }
 
 Pinval = digitalRead(6);  //pin5(High pin8 输出 LOW 默认)、pin6(High pin8 输出 High 方向)
 
 if(Pinval==1 && !fangxiang){ //有效高电平且现在电机转速与设置相反
 
 //1、把速度降到最低
 while(maichongjiange<maichongjiangeMax){
 jiansu();
 maichongqudong();
   }
 //2、反方向
 digitalWrite(8, HIGH);
 //3、记录新的方向
 fangxiang=1;
 //4、在把速度加到原来值
 while(maichongjiange<maichongjiangeSet){
 jiasu();
 maichongqudong();
   }
 
 }
 
 
 
 
 }

/*
djc3 无极调速 + 串口控制
规定Pin4口为一个判断点,
低电平则为串口控制,高电平为按键控制
对串口的输入做限制,必须为数字

*/


//电机的高电平持续时间 us
int maichongjiangeMax=1260;
int maichongjiangeMin=120;
long maichongjiangeSet;

//电机的高电平持续时间的初始值 0us
int maichongjiange=0;

//脉冲的占空比为1/maichongzhankongbi
int maichongzhankongbi=4;

//加减速时速度每隔300us变化一次
int jiajiansubianhuashijian=300;


////////////////////////////////////////////
int kongzhifangshi;//控制方式,低电平则为串口控制,高电平为按键控制
int jsq1=0;
int tempint;
char kongzhimingling[4];
boolean testxinxi=0;

int Pinval;//存储IO口(Pin5、Pin6)高低电平的值

boolean fangxiang=0;//电机转动方向标识
int maichongjsq=0;//脉冲计数器
 
 
unsigned long time1=micros();
unsigned long time2=micros();

 
void setup(){
 
 Serial.begin(9600);
 
 //pin5(High pin8 输出 LOW 默认)、pin6(High pin8 输出 High 方向) 输入状态,就读取值来确定电机的转动方向
 pinMode(5, INPUT);  
 pinMode(6, INPUT);  
 
/*
暂定A0 analogRead(0)的值来确定转速
为方便演示,此处为使用1K 多圈精密可调电阻,A0就接在中间脚上
那么可见,其电压大致为0-5v之间,现在就电压区间进行分级
如果粗分为10档,就意味着每100个返回单位对应10%的速度
*/
 
pinMode(7, OUTPUT);// EN+,脱机,高电平有效
pinMode(8, OUTPUT);// CW+,方向
pinMode(9, OUTPUT);// CLK+,频率(转速)
 
digitalWrite(7, LOW);//电机默认联机
digitalWrite(8, LOW);//
digitalWrite(9, LOW);
}
 
 
void loop(){
 
 kongzhifangshi = digitalRead(4); 
 
if(kongzhifangshi==1){
 
 //转速调节,通过可变电阻实现无极调速
 
  //可能是读取过于频繁,导致夹杂着无效数值,所以此处做个循环
  do
  {
maichongjiangeSet = analogRead(0);//0-1023
}while(maichongjiangeSet >1024);
 
 // 25% us =1000,000/(圈/每秒*400*4)=625/(0.5【min】+4.5×analogRead(0)/1024)
 //即把电压线性到转速上
  maichongjiangeSet = 625/(0.5+4.5*maichongjiangeSet/1024);//0-1023
 
 fangxiangchange(); //转动方向的切换
 
}else{

 
   while (Serial.available() > 0) {
   
   //格式:方向(1位),速度百分比(2位) 如012
 //kongzhimingling[jsq1]= Serial.read();
 if(jsq1==0){	 
  tempint=Serial.read();
  if(tempint==48 || tempint==49)kongzhimingling[0]= tempint;	 
 }else{
  tempint=Serial.read();
  if(tempint>47 && tempint<58)kongzhimingling[jsq1]= tempint;	
  
 }
 
delayMicroseconds(1200);
jsq1++;
if(jsq1==3) jsq1=0;

testxinxi=1;
  }
  
  if(testxinxi){
   testxinxi=0;
   jsq1=0;
   Serial.print("get:");
   Serial.println(kongzhimingling);  
   //速度调节

   
   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.print("bian");

   
  //1、把速度降到最低
  while(maichongjiange<maichongjiangeMax){
  jiansu();
  maichongqudong();
  }
  
  Serial.println("jiansuOK");
  
  //2、记录新的方向
  fangxiang=!fangxiang;
  
  //3、反方向
  digitalWrite(8, fangxiang);

  //4、在把速度加到原来值
  while(maichongjiange<maichongjiangeSet){
  jiasu();
  maichongqudong();
  }
  
  Serial.println("jiasuOK");
 
  }else  Serial.print("baochi");

  
 }


 
 
}
 
 
 
 //加速过程
 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();
 }

}
 

 void fangxiangchange() //转动方向的切换
 {
 
 
 
  //关于反向,虽然直接对引脚进行控制也是可以的,但加入一个,减速——取反——加速的过程应该更好
 /*本例中,
pin7, EN+,脱机,高电平有效
pin8, CW+,方向
pin9, CLK+,频率(转速)
已经用掉了,假设加减速、方向都由外部控制,那么很显然,就会出现2种控制方式:
A、模拟方式,即通过测量2个点电阻变化所导致的分压变化,即可实现强弱、方向的调节,具体类似于ACS712的读取,此方式可以类似于“无级变速”
B、数字方式,即通过摇杆或4个微动开关,来分别实现加减速、方向的切换

就实际操作而言,速度上测电阻分压,方向上用微动开关比较合适,即用2个数字口+1个PWM口实现具体控制
 */

 Pinval = digitalRead(5);  //pin5(High pin8 输出 LOW 默认)、pin6(High pin8 输出 High 方向)

 if(Pinval==1 && fangxiang){ //有效高电平且现在电机转速与设置相反

 //1、把速度降到最低
 while(maichongjiange<maichongjiangeMax){
 jiansu();
 maichongqudong();
   }
 //2、反方向
 digitalWrite(8, LOW);
 //3、记录新的方向
 fangxiang=0;
 //4、在把速度加到原来值
 while(maichongjiange<maichongjiangeSet){
 jiasu();
 maichongqudong();
   }
 
 }
 
 Pinval = digitalRead(6);  //pin5(High pin8 输出 LOW 默认)、pin6(High pin8 输出 High 方向)

 if(Pinval==1 && !fangxiang){ //有效高电平且现在电机转速与设置相反

 //1、把速度降到最低
 while(maichongjiange<maichongjiangeMax){
 jiansu();
 maichongqudong();
   }
 //2、反方向
 digitalWrite(8, HIGH);
 //3、记录新的方向
 fangxiang=1;
 //4、在把速度加到原来值
 while(maichongjiange<maichongjiangeSet){
 jiasu();
 maichongqudong();
   }
 
 }
 
 
 
 
 }
 
 

http://www.tudou.com/programs/view/T7hX0uNxjFA/

TNND 土豆的流畅完全不能看,算了@百度盘,原始视频

http://pan.baidu.com/s/1kTHv6T5


来顶贴喽