设为首页收藏本站

极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: hi55234

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

[复制链接]
 楼主| 发表于 2015-2-10 16:35:19 | 显示全部楼层
本帖最后由 hi55234 于 2015-2-10 17:54 编辑

PPS=Pulse Per Second 秒脉冲
7、电机的共振点:————整步共振(54—60r/min)
      步进电机均有固定的共振区域,二、四相感应子式步进电机的共振区一般在180-250pps之间(步距角1.8度)或在400pps左右(步距角为0.9度),电机驱动电压越高,电机电流越大,负载越轻,电机体积越小,则共振区向上偏移,反之亦然,为使电机输出电矩大,不失步和整个系统的噪音降低,一般工作点均应偏移共振区较多。


1、现象:电机低速时振动或失步,高速时正常:这是驱动电压过高引起。
2\电机低速时正常,高速时失步:这是驱动电压过低引起。
电机长时间低速运转无发热现象(电机正常工作时可高达70至80度)驱动电流过小时,
电机工作时过热:驱动电流过大的原因。

解决方法:调节驱动器电流、驱动电压或更换驱动器。

2、
现象:电机低速或高速时不转动或者失步;负载过大。
电机起动或停止时有失步或振动;电机出力过大。
解决方法:调节驱动器电流或更换电机。

1、脉冲信号的产生。
      脉冲信号一般由单片机或CPU产生,一般脉冲信号的占空比为0.3-0.4左右,电机转速越高,占空比则越大。

4、力矩与功率换算
     步进电机一般在较大范围内调速使用、其功率是变化的,一般只用力矩来衡量,力矩与功率换算如下:
                P= Ω·M
                  Ω=2π·n/60
                   P=2πnM/60
    其P为功率单位为瓦,Ω为每秒角速度,单位为弧度,n为每分钟转速,M为力矩单位为牛顿·米
               P=2πfM/400(半步工作)
     其中f为每秒脉冲数(简称PPS)

(二)、应用中的注意点
      1、步进电机应用于低速场合---每分钟转速不超过1000转,(0.9度时6666PPS),最好在1000-3000PPS(0.9度)间使用,可通过减速装置使其在此间工作,此时电机工作效率高,噪音低。
      2、步进电机最好不使用整步状态,整步状态时振动大。

  5、电机在较高速或大惯量负载时,一般不在工作速度起动,而采用逐渐升频提速,一电机不失步,二可以减少噪音同时可以提高停止的定位精度。

7、电机不应在振动区内工作,如若必须可通过改变电压、电流或加一些阻尼的解决。
      8、电机在600PPS(0.9度)以下工作,应采用小电流、大电感、低电压来驱动。


回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-2-14 15:38:31 | 显示全部楼层
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x26,16,2);  // I2C 1602转接板的地址
 
 
int ACS712PinPin=0;//A0读取ACS712Pin 5A的电压的针脚
int ACS712PinVal=0;//A0读取ACS712Pin 5A的电压值(0-1023)
long ACS712PinValx=0;//A0读取ACS712Pin 5A的电压(换算为mV)
int mySensVals[10];//四次取均值,待平均的值暂存数组中
int jsq1=0;//四次取均值,取到第几次的计数器
int maichongjiange=100;//脉冲间隔
long pps=0;
 
 int maichongjsq=0;
 
 int jsq3=0;
 
unsigned long time1=millis();
unsigned long time2=micros();
unsigned long time3=millis();
long quantime=0;
 
long maichongpinlv = 0;//脉冲频率
float lilunquanshu=0;//理论圈数
 
boolean fangxiang=1;
 
void setup(){
Serial.begin(9600);
 
  lcd.init();    
  lcd.backlight();
 
pinMode(7, OUTPUT);// EN+,脱机,高电平有效
pinMode(8, OUTPUT);// CW+,方向
pinMode(9, OUTPUT);// CLK+,频率(转速)
 
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
}
 
 
void loop(){
 
  //电流读取部分
ACS712PinVal=analogRead(ACS712PinPin);
mySensVals[jsq1]=ACS712PinVal;
jsq1++;
 
 
if(jsq1==10){
 jsq1=0;
 time1=millis()-time1;
ACS712PinValx=(mySensVals[0]+mySensVals[1]+mySensVals[2]+mySensVals[3]+mySensVals[4]+mySensVals[5]+mySensVals[6]+mySensVals[7]+mySensVals[8]+mySensVals[9])*0.1;
ACS712PinValx=(ACS712PinValx-455)*4.69*1000/185;

  Serial.println(ACS712PinValx);//-1234

/*
1、497是acs712在不通电时的所取到的模拟值,每个值代表(vcc-GND)/1023 mv
2、4.69=(vcc-GND)/1023,因为实测只有4.88v的样子
3、acs712 5A ,是每185mv/A,所以每mv表示1000/185 mA
*/ 
         //digitalWrite(7, HIGH);

  }
  

 /*  步进电机控制信号
 High-----------| Low-----------|  Low-----------|  Low-----------| 
 maichongjiange | maichongjiange| maichongjiange | maichongjiange |
 
 */
 
 if (micros()-time2 > maichongjiange){
         
        maichongjsq++;//每过一个“脉冲间隔”时间段,则“脉冲计数器”自增1
        maichongjsq=maichongjsq%4;//对“脉冲计数器”取模,这个取摸结果实质就是对占空比的调节(占空比为1/模),以4为例,则“脉冲计数器”的变化为:0——1——2——3——0

 
 if(maichongjsq==0)digitalWrite(9, HIGH);
 else digitalWrite(9, LOW);

  
         time2= micros();
 }
 

 
 
}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-2-14 17:35:11 | 显示全部楼层
本帖最后由 hi55234 于 2015-2-14 17:37 编辑

慢速——保持3s——平滑加速——快速——保持3s  循环

PS:i2c 1602 打印速度慢,延迟会导致电机转速慢,且不顺畅(破坏了脉冲频率)

int maichongjiange=8000;//脉冲间隔us

boolean bianhua=1;
boolean baochi=0;

 int maichongjsq=0;
 
 
unsigned long time1=micros();
unsigned long time2=micros();
unsigned long time3=millis();


boolean fangxiang=1;
 
void setup(){
Serial.begin(9600);


pinMode(7, OUTPUT);// EN+,脱机,高电平有效
pinMode(8, OUTPUT);// CW+,方向
pinMode(9, OUTPUT);// CLK+,频率(转速)
 
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
}
 
 
void loop(){
 

 if (micros()-time2 > maichongjiange){
         
        maichongjsq++;//每过一个“脉冲间隔”时间段,则“脉冲计数器”自增1
        maichongjsq=maichongjsq%4;//对“脉冲计数器”取模,这个取摸结果实质就是对占空比的调节(占空比为1/模),以4为例,则“脉冲计数器”的变化为:0——1——2——3——0

 
 if(maichongjsq==0)digitalWrite(9, HIGH);
 else digitalWrite(9, LOW);

  
         time2= micros();
 }
 
 
 
 
 
 if(bianhua && baochi){
         
                if(micros()-time1>300 && maichongjiange>100){
                maichongjiange--;
                time1=micros();
                }

  }else if(baochi){
        
                 if(micros()-time1>300 && maichongjiange<8000){
  maichongjiange++;
  time1=micros();
        }

 }
 
 
 if(maichongjiange==100 || maichongjiange==8000){
         bianhua=!bianhua;
         baochi=0;

 if(millis()-time3>3000){
         
 baochi=1;
 time3=millis();
 }
 
 }
 

 
 
}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-2-16 15:36:26 | 显示全部楼层
本帖最后由 hi55234 于 2015-2-17 16:00 编辑

针对9楼的接法,一个可变电阻+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轴是转速
4bed2e738bd4b31c9f175b3887d6277f9e2ff80e.jpg


简单来说,就是虽然阻值的变化是线性的,但速度的增加却是指数型的
具体来说就是,开始的时候,速度变化很快,而后变化越发的不明显
这个对手动调节来说,恐怕不是很舒服,所以解决方式为:
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、多圈的精密电阻,却是太难调节了

所以,具体的映射恐怕还要修改
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-2-18 12:45:14 | 显示全部楼层
尼玛只要把电阻分压对应到圈/每秒上,就能实现感官上的无极调速
我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——步进电机的分贝数

IMG_20150217_232821.jpg
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-2-18 12:51:19 | 显示全部楼层
为了控制的迁移,串口控制是必须的:

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


捕获1.PNG



/*
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();
    }
 
 }
 
 
 
 
 }
 
 
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-2-18 14:06:09 | 显示全部楼层
/*
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();
    }
 
 }
 
 
 
 
 }
 
 
回复 支持 反对

使用道具 举报

发表于 2015-2-19 12:35:55 | 显示全部楼层
好多代码..........
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-2-19 14:41:26 | 显示全部楼层
本帖最后由 hi55234 于 2015-2-19 14:49 编辑



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

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


步进电机的控制   蓝牙.3gp_20150219_144830.757.jpg
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-2-25 15:12:26 | 显示全部楼层

丧心病狂的单字节控制,0延迟,纯ASCII分拆

/*
 纯串口控制
  加入脱机控制
*/
 
 
//电机的高电平持续时间 us
int maichongjiangeMax=1260;
int maichongjiangeMin=120;
long maichongjiangeSet=600;
 
//电机的高电平持续时间的初始值 120us
int maichongjiange=120;
 
//脉冲的占空比为1/maichongzhankongbi
int maichongzhankongbi=4;
 
//加减速时速度每隔300us变化一次
int jiajiansubianhuashijian=300;
 
 
////////////////////////////////////////////

int tempint;
 
boolean fangxiang=0;//电机转动方向标识
int maichongjsq=0;//脉冲计数器
 
 
unsigned long time1=micros();
unsigned long time2=micros();
 
 
void setup(){
 
 Serial.begin(9600);
  
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) {
 
    //丧心病狂的单字节控制,0延迟,纯ASCII分拆
        //定义1 0-9表示转速,每一个表示10%
        //定义2 A正转、B反转
        //定义3 C联机、D脱机
        
   tempint=Serial.read();
   
   //调速度
   if(tempint>47 && tempint< 58) maichongjiangeSet = 625/(0.5+4.5*(tempint-48)/10);//0-1023
   //调方向
   if(tempint==65)digitalWrite(8, 0);
   if(tempint==66)digitalWrite(8, 1);
    //脱机
   if(tempint==67)digitalWrite(7, 0);
   if(tempint==68)digitalWrite(7, 1);
   
   tempint=0;

 }
 
 
 
 
 
 
 //加速过程
 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();
 }
 
}
 
 
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系我们|极客工坊 ( 浙ICP备09023225号  

GMT+8, 2017-3-31 02:38 , Processed in 0.221766 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表