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、多圈的精密电阻,却是太难调节了
所以,具体的映射恐怕还要修改