0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何通过代码HodgePodging加快最大步进速度

454398 来源:网络整理 作者:网络整理 2019-11-18 09:03 次阅读

第1步:

我使用了很多单词来描述我的方法,但是我也尊重每个人都会从另一个地方来处理这个问题。如果您有经验,请多说些抱歉,但是,如果您不熟悉arduino,并且想以比当前使用accelstepper更快的速度运行步进电机,那么请问所有问题。

计划:

Accelstepper使用非线性加速度曲线,以逐渐增加步进电机的步进率。它在stepper.run()调用期间以非常抽象的方式执行此操作,这是一个(粗略的想法)函数,用于检查您是否应进行新步骤,如果是,则步进驱动程序并计算下一次执行的时间步骤已到。您需要经常调用它,但是您可以在控制循环中执行其他操作。因此,例如,在这里您可能会看到:

同时(digitalRead(someSensor)== high){

//做东西

//做更多东西

stepper.run();

}

只要“填充”时间不长,stepper.run()就会非常频繁地运行,并且步进操作。但是stepper.run()并不是一个非常快速的函数,在某些时候它是限制因素!然后,此while循环会花费太长时间。

所以我的建议和方法是执行以下操作:

//starting from the non-moving position

while(condition){

//do stuff

stepper.run();

if (stepper.Speed()==maxAccelstepperSpeed){

//Extrafast mode is a simple linear acceleration program. Not as nice as stepper.run(), but much faster.

break; //let‘s get out of this while loop!

}

//extraFastMode()伪代码:

//calculate a starting stepdelay based on what speed you’re transitioning away from the accelstepper library.

The new method of stepping will just be:

“While(condition){

”Do stuff/ check extra if statements

Take a step

wait manually with a delay

add to a counter

//if the counter hits a trigger number, and you‘re not at your final target speed,

then decrease your delay [which increases your motor speed“

}//loop back to the top

这有意义吗?下一步,让我们深入研究同样冗长的注释代码,如果有任何问题,请返回。

步骤2:哇,代码!

我从我的项目中提取了一个完整的程序,并在保留大部分表单的同时将其剥离了下来。 “功能”模式。我可以说原始代码有效,但是我只测试了新代码可以编译。

此代码是否完美?否。

此代码是执行此操作的最佳还是最快方法?否。

但这行得通吗?是。我希望我已使其功能尽可能透明。

它最初是作为函数调用编写的,在我的程序中可以使用几个不同的马达(调用accellstepper的不同实例),但在此示例中我将其简化了一些。

建议:如果签出附带的.ino,则可以在您喜欢的文本编辑器中查看代码。它的显示效果会好得多,我不建议整体复制此代码块,因为它可能会稍微变形。

/*This document should end up as a short introduction to one particular method of

sidestepping Accelstepper’s somewhat low step-rate limit using default stepper.run()

protocol. It is not the only and certainly not the best method. But it works.*/

//Extra note about the purpose: This lets you use the nice accelstepper acceleration

algorithm for the initial acceleration and then a much cruder linear ramp thereafter.

#include

const int stepPin=23;

const int directionPin=14;

/*Accelstepper SetMotorIdentifier(TYPE, STEP, DIRECTION) We are using type 1 because I‘m using a classic STEP/DIR stepper Driver.

Different types might ask for things other than step&direction [see Accelsteppr documentation]*/

AccelStepper stepper(1,stepPin,directionPin);

long actuatorDistance = 158400; //This varies depending on your purpose. I wanted to go 158,400 steps. That corresponded with 99 rotations of my 1.8 deg stepper motor with 1/8th microstepping.

int actuatorSpeed=3900; //This corresponded to 487.5 steps/second, or 2.47 revs/second, which for me corresponding to about 40 seconds for my actuator.

unsigned long actuatorTimeout =19000; //This might not be used in the tutorial, but it’s good to have a timeout threshold if you think your actuator might stall out and you want some backup timeout.

int actuatorAcceleration=8500; //This acceleration value was chosen by experimentation, and only corresponds to the initial actuatorSpeed trigger point - after that your linear acceleration takes over.

const byte programOverhead=26; //measured in mS.

//During the fast-stepping function you may want to check a few sensors (in my case, for an end-stop)。 The thing is you want your initial linear step-delay to be pretty close to whatever step rate the accelstepper actuatorSpeed was. For this to work, you need to know roughly how much time your control loop takes excluding the step delay. If your sketch is similar to mine in what it‘s checking, you can start with my numbers.

const byte minPulseWidth=3; //different drivers require different minimum step pulses to register a line change.。.The basic reprap drivers are 1-2mS, this is sort of an unnecessary variable I used for extra fluff, you can probably do without it.

//FINAL STEP RATE VALUE

byte stepDelayTarget=90-minPulseWidth-programOverhead; // This should never add up to 《0. Check manually.

//This number, here shown as 90, relates to your target final step max speed. 90 is in uS, so I went up to 1000,000/90 = 11,111.1.。 steps/second. That’s an improvement over the default max of 3900 steps/seconds and was rate limited in my application by the physical system. I don‘t know how high you can expect an arduino to go. I would guess around 30uS for the mega with my specific code (ergo 33,000 steps/s)

const int systemEndstop=24;

const int enablePin=53; //This is another extra variable I kept in the example code. You can ignore it, but it refers to a pin that is controlling the enable pin of my DRV8825 driver. Because it’s 53 you can see I wrote this probably for an arduino mega.

//Global variables as part of the program functions.

unsigned long timeStart; //We want to be able to reset timeStart in different parts of the program. It‘s a global variable redeclared by a number of functions. Be aware. Another ’extra variable‘ I kept in the example code.

void setup(){ //Void setup runs once during initial boot of microprocessor, but not after.

stepper.setPinsInverted(false,false,true); // setPinsInverted(bool Dir,bool Step,bool Enable) Bool enable is == true because my enable pin is OFF when HIGH and ON when LOW. This is opposite of the default, so we enable the invert function. I believe the default is set for an A4988 driver, and this use case is for the Pololu DRV8825 breakout.

//the following should be familiar if you’ve used the accelstepper program before.

stepper.setMaxSpeed(actuatorSpeed);

stepper.setAcceleration(actuatorAcceleration);

stepper.setEnablePin(enablePin);

stepper.setMinPulseWidth(3); //Remember the minPulseWidth variable from before? This is the accelstepper version.

// declare pinmodes

pinMode(systemEndstop,INPUT);

digitalWrite(systemEndstop,HIGH); //This sets internal 20k pull-up resistor. It is usually necessary for a hall sensor to have a pull-up resistor, and in this case I was using a hall-sensor endstop.

} //end of void setup

void fastSteppingFunction(){ //This function will be used later as the linear-ramp portion of the code.

//Ok! StepDelay needs to be set so that it creates a stepping speed approximately equal to the stepping speed that accelstepper leaves off at. Much different, and you will have caused an instantaneous acceleration that the stepper motor will fail to keep up with.

byte stepDelay=((1000000/actuatorSpeed)-minPulseWidth-programOverhead);

//IMPORTANT NOTE: If your actuatorSpeed is less than 3900steps/s, you might want to change stepDelay to a uint_16t or otherwise ”uint.“ Bytes are less overhead to work with, but can‘t be 》255

//In my original code, I actually hard coded the stepDelay start at 250 instead of (100000/actuatorSpeed)。 The math for my values would put 1,000,000/actuatorSpeed at 256 steps/second, and for some reason I chose 250. But this math step allows for you to change your actuatorSpeed without needing to change the value here.

byte counter = 0;

//counter is used as a way to make a very quick conditional statement that overflows every 256 digits. There are other ways to implement the linear ramp. This is the way I chose. I thought it would be fast although it’s no longer clear to me why I chose exactly this method.

while(digitalRead(systemEndstop)==HIGH){ //remember this is our ending condition. In my code we are not relying on our steps to be counted. You can count steps too, by setting your condition to be when a bigger counter reaches a certain number. Then you need to implement a counter that increments during each step.

digitalWrite(stepPin,HIGH);

delayMicroseconds(minPulseWidth);

digitalWrite(stepPin,LOW);

delayMicroseconds(stepDelay);

if (actuatorTimeout《(millis()-timeStart)){ //Did you notice we said ”timeStart=millis()“ at the start of actuation? This is because I recommend your system has a timeout in case your motor stalls out and you never reach your endstop.

//make an error function and call it here.

//make a function to get back up to speed, assuming you want to do that after you resolve the error. Optional not included.

//recursively return to the fastSteppingFunction();

}

/*Next step is to increment the counter. This will run each time you repeat the loop.

My method is not very adjustable to changing the slope of the ramp, and if I were to rewrite

this code today I would probably choose something else. Consider this when implementing

your code.

*/

counter=counter+2; /*always manipulate this counter so that you understand when your

counter will reach the condition in the if statement below. In my case, it will reach the

the condition every 256/2 steps, i.e, every 128 steps. If I chose a number like ”3“ instead

of ”2“ I would have a problem because the counter would not reach 0 until a third overflow

of the byte counter, so I would be decreasing the slope of my linear ramp six times.

Meanwhile I can also decrease the slope by half by changing the number to 1. Or, I can double

the slope by saying 4. This lack of flexibility in changing the linear ramp slope is why

I suggest considering other methods to make a linear ramp. Try to implement your method with

minimum math. Ideally do not include multiplication in the loop, and especially not division.

*/

if (stepDelay》stepDelayTarget && counter==0){ //So this condition is looking to see if you‘re reached your max speed target, and if you haven’t yet and the counter has reached its trigger point [0], then it decreases the delay.

stepDelay--; //Stepdelay-- is a fast way of saying ”stepdelay=stepdelay-1“, i.e, your decreasing the step delay. By decreasing the step delay, you are increasing the frequency of steps/ the speed of your motor.

}

}

}

}

void moveActuatorForward(){

//Hey! You‘re about to start moving a motor. In a lot of cases that means you should make some safety check. The following commented if statement is a filler for that.

/*if ([insert errorCondition]){

//stepper.disableOutputs();

//error();

}*/

stepper.enableOutputs(); //This is redundant, in fact. It’s already been called.

stepper.move(actuatorDistance); //You need to tell accelstepper how far you‘re going!

timeStart = millis(); //I used a global variable in other parts of the code, maybe you want to use a local variable.

//Hey we’re finally starting!!

while(1){ //Title: ”Basic Moving While Loop“

if (digitalRead(systemEndstop)==LOW){ //checks if we hit the endstop before reaching the accelstepper max speed

//This never happened for my application, but maybe does for yours.

break; //break removes you from the while loop called ”Basic Moving While loop“

}

stepper.run(); //this makes your initial acceleration completely abstract.

if(stepper.speed() fastSteppingFunction();

break;

}

}

stepper.DisableOutputs();

//Hey we‘re done!

}

void loop(){

//do stuff other than moving your motors, if you have other stuff to do.

stepper.disableOutputs(); //I tend to add extra disableOutputs in case I made mistakes in the code, because my stepper motors were set to a high current that would eventually make those little motors overheat. For simple programs this isn’t a big deal, but once you start running around with more program states you want to be sure you don‘t let your motor overheat while you’re doing something else.

if (1){ //Here I‘m just suggesting that you probably want to run the actuator based on some condition.

//Now this is a stripped version of the code. Let’s just look at it as a goal to ”actuate“ a linear actuator. There are two endstops for this device but we‘re only looking at moving the actuator from ”home“ to ”endstop“

stepper.enableOutputs();

stepper.setCurrentPosition(0); //My physical system had a lot of friction, so I never decelerated my load. This meant that when I start the motor, accelstepper sometimes wants to ”slow down“ before it accelerates again. This is even if it was in fact not running. SetCurrentPosition(0) acts as a reset to the accelstepper code.

moveActuatorForward();

stepper.disableOutputs();

}

}

步骤3:PS,您注意到了吗?

我的“线性斜坡”实际上不是线性斜坡。我每128步(大约每20mS)减少1uS步之间的延迟。最初,步进延迟为250mS,步进增加的速率为每32mS 1uS。到我的驱动结束时,每11.5mS的增加速率为1uS。这是一个非线性的斜坡,在接近终点时加速度增加。可能有很多很好的方法可以使此线性化,或更改执行速度增加的方法。但是我的执行器已经运行了好几个月,所以我认为该方法已经足够好了。

事实是,直到我编写此可指导的代码并梳理我的代码之前,我才注意到它。

责任编辑:wv

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 步进电机
    +关注

    关注

    150

    文章

    3112

    浏览量

    147558
收藏 人收藏

    评论

    相关推荐

    通过具体案例,选择合适的步进电机

    选型原则,并通过具体实例加以说明,帮助读者更好地理解和应用步进电机的选型方法。       步进电机选型的基本要素       步进电机选型主要依据三大要素:步距角、静力矩和电流。  
    的头像 发表于 12-13 07:34 258次阅读
    <b class='flag-5'>通过</b>具体案例,选择合适的<b class='flag-5'>步进</b>电机

    行星减速步进电机与步进电机的区别

    步进电机是一种将电脉冲信号转变为角位移或线位移的开环控制电机。其工作原理是通过电子电路将直流电分为多相序控制电流,使用这种电流给步进电机供电,步进电机才能正常工作。每输入一个电脉冲,
    的头像 发表于 11-16 15:11 297次阅读
    行星减速<b class='flag-5'>步进</b>电机与<b class='flag-5'>步进</b>电机的区别

    PLC控制步进电动机的基本原理

    “步距角”。通过精确控制脉冲的数量,可以实现对步进电动机角位移量的精细调控,从而实现高精度的定位任务。 除了位置控制外,步进电动机的速度和加速度
    的头像 发表于 09-24 11:28 345次阅读

    步进电机的伺服控制方法有哪些

    和脉冲序列,使电机准确移动到目标位置。这种控制模式适用于需要精确定位的应用场景。 2. 速度模式 定义 :在速度模式下,步进伺服电机根据输入的速度指令,
    的头像 发表于 09-04 09:48 571次阅读

    步进电机伺服控制系统的作用

    步进电机伺服控制系统是一种精密的电机控制系统,它通过精确控制电机的步进角度来实现对机械运动的精确控制。这种系统广泛应用于自动化设备、机器人、精密仪器等领域。 步进电机伺服控制系统的作用
    的头像 发表于 09-04 09:46 683次阅读

    步进电机型号与步进电机命名规则

    混合式步进电机代码:SM。 系列代码:H、高性能二相步进电机;C、三相步进电机;E、五相步进
    的头像 发表于 08-26 09:42 162次阅读
    <b class='flag-5'>步进</b>电机型号与<b class='flag-5'>步进</b>电机命名规则

    步进电机通过什么控制转动角度

    步进电机是一种电磁驱动的旋转电机,它具有精确控制转动角度的特性。步进电机的工作原理是通过改变线圈的电流来改变磁场,从而实现对转子的控制。本文将详细介绍步进电机的控制原理、控制方式以及实
    的头像 发表于 06-12 09:49 1612次阅读

    步进电机控制器怎么调速度

    引言 步进电机是一种将电脉冲信号转换为角位移的电机,具有控制精度高、响应速度快、结构简单等优点。在自动化设备、机器人、数控机床等领域得到了广泛应用。步进电机控制器是实现步进电机控制的关
    的头像 发表于 06-12 09:17 2116次阅读

    SOLIDWORKS教育版使学生了解如何加快设计项目的速度

    在当今信息爆炸的时代,设计项目的速度和效率对于工程专业的学生来说至关重要。SOLIDWORKS教育版作为一款专门为学生设计的3D CAD软件,不仅提供了强大的设计工具,更致力于帮助学生了解如何加快设计项目的速度,提升他们的设计能
    的头像 发表于 04-09 16:00 335次阅读

    ST MotorControl Workbench反转到最大速度,低压警告就报警是哪里出了问题?

    ST MotorControl Workbench生成的代码,为啥调试电机的时候,速度设定为2000转,它总是反转到最大速度,然后低压警告就报警呀?
    发表于 03-28 07:14

    步进电机如何减速?

    步进电机是一种直接将电脉冲转化为机械运动的机电装置,通过控制施加在电机线圈上的电脉冲顺序、 频率和数量, 可以实现对步进电机的转向、 速度和旋转角度的控制。在不借助带位置感应的闭环反馈
    的头像 发表于 03-23 08:42 472次阅读
    <b class='flag-5'>步进</b>电机如何减速?

    stm32h743是不是可以直接用ICache加快一些速度

    stm32h743是不是可以直接用ICache加快一些速度,而不用DCache,DCache配置ram麻烦?
    发表于 03-08 08:01

    arduino控制步进电机代码

    Arduino是一种开放源代码的电路板平台,它可以用于控制各种不同的电子设备,包括步进电机。步进电机是一种电动机,可以通过下达特定的指令来控制每个
    的头像 发表于 02-14 16:29 2070次阅读

    步进电机为什么会用到光耦?

    步进电机是一种通过输入脉冲信号控制旋转角度和速度的电动机。
    的头像 发表于 01-30 11:41 1782次阅读

    步进电机控制方法 步进电机控制器参数设置

    步进电机是一种在控制系统中常见的电机类型,它以步进角度为单位进行旋转,并且可以精确控制位置和速度。在许多应用领域,如精密仪器、印刷设备和医疗设备中,步进电机都得到广泛使用。 为了实现对
    的头像 发表于 01-19 10:50 2982次阅读