Atm_AccelStepper.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
  1. // #ifdef AccelStepper_h
  2. #include "Atm_AccelStepper.h"
  3. /* Add optional parameters for the state machine to begin()
  4. * Add extra initialization code
  5. */
  6. Atm_AccelStepper& Atm_AccelStepper::begin(int step_pin, int dir_pin) {
  7. // clang-format off
  8. const static state_t state_table[] PROGMEM = {
  9. /* ON_ENTER ON_LOOP ON_EXIT EVT_DISABLE EVT_ENABLE EVT_ENABLED_TIMEOUT EVT_MOVE EVT_STOP EVT_EMERGENCY_STOP EVT_ON_LIMIT_LOW EVT_ON_LIMIT_HIGH EVT_ON_TARGET EVT_HOMING_LOW EVT_HOMING_HIGH ELSE */
  10. /* DISABLE */ ENT_DISABLED, -1, -1, -1, ENABLED, -1, RUNNING, -1, -1, DISABLE, DISABLE, -1, HOMING_LOW, HOMING_HIGH, -1,
  11. /* ENABLED */ ENT_ENABLED, -1, -1, DISABLE, -1, DISABLE, RUNNING, -1, -1, ENABLED, ENABLED, -1, HOMING_LOW, HOMING_HIGH, -1,
  12. /* RUNNING */ ENT_RUNNING, LP_RUNNING, -1, DISABLE, -1, -1, RUNNING, STOP, STOP, RUNNING, RUNNING, ENABLED, -1, -1, -1,
  13. /* STOP */ ENT_STOP, LP_STOP, -1, DISABLE, ENABLED, -1, RUNNING, STOP, STOP, STOP, STOP, ENABLED, -1, -1, -1,
  14. /* HOMING_LOW */ ENT_HOMING_LOW, LP_HOMING_LOW, EXT_HOMING_LOW, DISABLE, -1, -1, -1, STOP, STOP, HOMING_LOW, HOMING_LOW, -1, -1, -1, -1,
  15. /* HOMING_HIGH */ ENT_HOMING_HIGH, LP_HOMING_HIGH, EXT_HOMING_HIGH, DISABLE, -1, -1, -1, STOP, STOP, HOMING_HIGH, HOMING_HIGH, -1, -1, -1, -1,
  16. /* LIMIT_LOW */ ENT_LIMIT_LOW, LP_LIMIT_LOW, -1, -1, -1, -1, RUNNING, STOP, STOP, -1, -1, -1, -1, -1, -1,
  17. /* LIMIT_HIGH */ ENT_LIMIT_HIGH, LP_LIMIT_HIGH, -1, -1, -1, -1, RUNNING, STOP, STOP, -1, -1, -1, -1, -1, -1
  18. };
  19. // clang-format on
  20. Machine::begin( state_table, ELSE );
  21. stepper = new AccelStepper(1, step_pin, dir_pin);
  22. stepper->setMaxSpeed(max_speed);
  23. stepper->setAcceleration(acceleration);
  24. // idle_timer.set(ATM_TIMER_OFF);
  25. position_timer.set(POSITION_SEND_TIMER);
  26. limits_timer.set(LIMIT_UPDATE_RATE);
  27. limits_timer.setFromNow(this, LIMIT_UPDATE_RATE);
  28. return *this;
  29. }
  30. /* Add C++ code for each internally handled event (input)
  31. * The code must return 1 to trigger the event
  32. */
  33. int Atm_AccelStepper::event( int id ) {
  34. //bool tempState ;
  35. switch ( id ) {
  36. case EVT_DISABLE:
  37. return 0;
  38. case EVT_ENABLE:
  39. return 0;
  40. case EVT_ENABLED_TIMEOUT:
  41. return 0;
  42. case EVT_MOVE:
  43. return 0;
  44. case EVT_STOP:
  45. return 0;
  46. case EVT_EMERGENCY_STOP:
  47. return 0;
  48. case EVT_ON_LIMIT_LOW:
  49. if (limits_timer.expired(this)){
  50. switch(_limitLow_Mode) {
  51. case 0:
  52. break;
  53. case 1: //digital INPUT
  54. // Serial.println("digital");
  55. limitLow_State_raw = digitalRead(_limitLow_Pin);
  56. limitLow_State_raw = _limitLow_Reversed ? !limitLow_State_raw : limitLow_State_raw;
  57. break;
  58. case 2:
  59. int analogTemp = analogRead(_limitLow_Pin);
  60. limitLow_State_raw = (_limitLow_Thresholds[0] < analogTemp) && (analogTemp < _limitLow_Thresholds[1]);
  61. limitLow_State_raw = _limitLow_Reversed ? !limitLow_State_raw : limitLow_State_raw;
  62. // if(limitLow_State){
  63. // delay(3);
  64. // analogTemp = analogRead(_limitLow_Pin);
  65. // limitLow_State = (_limitLow_Thresholds[0] < analogTemp) && (analogTemp < _limitLow_Thresholds[1]);
  66. // limitLow_State = _limitLow_Reversed ? !limitLow_State : limitLow_State;
  67. // }
  68. break;
  69. }
  70. limitLow_State = limitLow_avg(limitLow_State_raw);
  71. changed = limitLow_State != limitLow_State_prev ? 1 : 0 ;
  72. limitLow_State_prev = limitLow_State ;
  73. //Serial.println(limitLow_State);
  74. if (changed){push( connectors, ON_ONLIMITLOW, 0, limitLow_State, 0 );}
  75. // Serial.println("in limit");
  76. return changed ;
  77. }
  78. else{return 0;}
  79. case EVT_ON_LIMIT_HIGH:
  80. if (limits_timer.expired(this)){
  81. switch(_limitHigh_Mode) {
  82. case 0:
  83. break;
  84. case 1: //digital INPUT
  85. limitHigh_State_raw = digitalRead(_limitHigh_Pin);
  86. limitHigh_State_raw = _limitHigh_Reversed ? !limitHigh_State_raw : limitHigh_State_raw;
  87. break;
  88. case 2:
  89. //Serial.println("analog");
  90. int analogTemp = analogRead(_limitHigh_Pin);
  91. limitHigh_State_raw = (_limitHigh_Thresholds[0] < analogTemp) && (analogTemp < _limitHigh_Thresholds[1]);
  92. limitHigh_State_raw = _limitHigh_Reversed ? !limitHigh_State_raw : limitHigh_State_raw;
  93. // if(limitHigh_State){
  94. // delay(3);
  95. // analogTemp = analogRead(_limitHigh_Pin);
  96. // limitHigh_State = (_limitHigh_Thresholds[0] < analogTemp) && (analogTemp < _limitHigh_Thresholds[1]);
  97. // limitHigh_State = _limitHigh_Reversed ? !limitHigh_State : limitHigh_State;
  98. // }
  99. break;
  100. }
  101. limitHigh_State = limitHigh_avg(limitHigh_State_raw);
  102. changed = limitHigh_State != limitHigh_State_prev ? 1 : 0;
  103. limitHigh_State_prev = limitHigh_State;
  104. if (changed){push( connectors, ON_ONLIMITHIGH, 0, limitHigh_State, 0 );}
  105. limits_timer.setFromNow(this, LIMIT_UPDATE_RATE);
  106. return changed ;
  107. }
  108. else{return 0;}
  109. case EVT_ON_TARGET:
  110. return runMode ? 0 : _currentStep == _targetStep; //only send when in positionning mode
  111. case EVT_HOMING_LOW:
  112. return 0;
  113. case EVT_HOMING_HIGH:
  114. return 0;
  115. }
  116. return 0;
  117. }
  118. /* Add C++ code for each action
  119. * This generates the 'output' for the state machine
  120. *
  121. * Available connectors:
  122. * push( connectors, ON_CHANGEPOSITION, 0, <v>, <up> );
  123. * push( connectors, ON_CHANGESTATE, 0, <v>, <up> );
  124. * push( connectors, ON_ONLIMITHIGH, 0, <v>, <up> );
  125. * push( connectors, ON_ONLIMITLOW, 0, <v>, <up> );
  126. * push( connectors, ON_ONTARGET, 0, <v>, <up> );
  127. * push( connectors, ON_STOP, 0, <v>, <up> );
  128. */
  129. void Atm_AccelStepper::action( int id ) {
  130. switch ( id ) {
  131. case ENT_DISABLED:
  132. push(connectors, ON_CHANGESTATE, 0, state(), 0);
  133. enabled = _enableReversed ? HIGH : LOW;
  134. digitalWrite(_enablePin, enabled);
  135. limits_timer.setFromNow(this, LIMIT_UPDATE_RATE);
  136. return;
  137. case ENT_ENABLED:
  138. // _isHoming = 0 ;
  139. stepper_update();
  140. if(last_trigger == EVT_ON_TARGET){push( connectors, ON_ONTARGET, 0, _currentStep, 0 );};
  141. push(connectors, ON_CHANGESTATE, 0, state(), 0);
  142. push(connectors, ON_CHANGEPOSITION, 0, stepper->currentPosition(), _currentSpeed);
  143. enabled = _enableReversed ? LOW : HIGH ;
  144. //reset limit state so that they trigger again if we're stopped on it
  145. limitLow_State = 0;
  146. limitHigh_State = 0;
  147. digitalWrite(_enablePin, enabled);
  148. limits_timer.setFromNow(this, LIMIT_UPDATE_RATE);
  149. return;
  150. case ENT_RUNNING:
  151. push(connectors, ON_CHANGESTATE, 0, state(), 0);
  152. if (last_trigger!=EVT_ON_LIMIT_LOW && last_trigger!=EVT_ON_LIMIT_HIGH){compensatePlay(_currentSpeed);break;}
  153. if (runMode){stepper->setSpeed( _currentSpeed);}
  154. else{stepper->moveTo(_targetStep);}
  155. position_timer.setFromNow(this, POSITION_SEND_TIMER);
  156. limits_timer.setFromNow(this, LIMIT_UPDATE_RATE);
  157. return;
  158. case LP_RUNNING:
  159. // if on limits and limits are hard, stop moving in one direction
  160. if(limitLow_State && _limitLow_Hard && (_currentSpeed<0.)) {
  161. trigger(EVT_EMERGENCY_STOP);
  162. break;
  163. }
  164. if( limitHigh_State && _limitHigh_Hard && (_currentSpeed>0.)) {
  165. trigger(EVT_EMERGENCY_STOP);
  166. break;
  167. }
  168. // if hard limits and homing is done, check current position is within limits
  169. if (_limitLow_Hard && homingLow_done) {
  170. if( (_currentStep<0) && (_currentSpeed<0.)) {trigger(EVT_EMERGENCY_STOP);break;}
  171. }
  172. if (_limitHigh_Hard && _maxStep) { //maxstep is 0 if not defined
  173. if( (_currentStep>_maxStep) && (_currentSpeed>0.)) {trigger(EVT_EMERGENCY_STOP);break;}
  174. }
  175. stepper_update();
  176. if(runMode && _currentSpeed == 0.) {trigger(EVT_EMERGENCY_STOP);break;}//trigger(EVT_ON_TARGET);
  177. if(!runMode && (_currentStep==_targetStep)){push( connectors, ON_ONTARGET, 0, _currentStep, 0 );trigger(EVT_EMERGENCY_STOP);break;}
  178. return;
  179. case ENT_STOP:
  180. push(connectors, ON_CHANGESTATE, 0, state(), 0);
  181. if (last_trigger == EVT_STOP) {
  182. runMode = 0 ;
  183. // stepper->setSpeed(stepper->speed());
  184. // stepper_update();
  185. stepper->stop();
  186. _targetStep = stepper->targetPosition();
  187. break;
  188. // push( connectors, ON_STOP, 0, 0, 0 );
  189. }
  190. if (last_trigger == EVT_EMERGENCY_STOP) {
  191. runMode=0 ;
  192. stepper->setSpeed(0);
  193. _currentStep = stepper->currentPosition();
  194. _targetStep = _currentStep ;
  195. stepper->setCurrentPosition(_currentStep);
  196. break;
  197. // stepper->moveTo(_targetStep);
  198. // push(connectors, ON_CHANGEPOSITION, 0, _currentStep, stepper->speed());
  199. // push( connectors, ON_STOP, 0, 1, 0 );
  200. }
  201. // stepper_update();
  202. // push(connectors, ON_CHANGEPOSITION, 0, _currentStep, stepper->speed());
  203. return;
  204. case LP_STOP:
  205. if(_currentSpeed == 0.) {trigger(EVT_ENABLE);break;}
  206. stepper_update();
  207. return;
  208. case ENT_HOMING_LOW:
  209. homingLow_done = 0;
  210. push(connectors, ON_CHANGESTATE, 0, state(), 0);
  211. push(connectors, ON_CHANGEPOSITION, 0, _currentStep, _currentSpeed);
  212. runMode = 1;
  213. _currentSpeed = -1*homing_speed;
  214. if (last_trigger!=EVT_ON_LIMIT_LOW && last_trigger!=EVT_ON_LIMIT_HIGH){compensatePlay(_currentSpeed);}
  215. stepper->setSpeed(-1*homing_speed);
  216. position_timer.setFromNow(this, POSITION_SEND_TIMER);
  217. limits_timer.setFromNow(this, LIMIT_UPDATE_RATE);
  218. return;
  219. case LP_HOMING_LOW:
  220. stepper_update();
  221. if(limitLow_State) {
  222. stepper->setCurrentPosition(0);
  223. _currentStep = 0;
  224. homingLow_done = 1 ;
  225. runMode = 0;
  226. trigger(EVT_EMERGENCY_STOP);
  227. push(connectors, ON_ONHOMINGLOW, 0, _currentStep, homingLow_done);
  228. }
  229. else if (changed && limitHigh_State && _limitHigh_Hard ){ //hit high limit and high is hard, stop
  230. homingLow_done = 0 ;
  231. runMode = 0;
  232. trigger(EVT_EMERGENCY_STOP);
  233. push(connectors, ON_ONHOMINGLOW, 0, _currentStep, homingLow_done);
  234. }
  235. return;
  236. case EXT_HOMING_LOW:
  237. return;
  238. case ENT_HOMING_HIGH:
  239. push(connectors, ON_CHANGESTATE, 0, state(), 0);
  240. push(connectors, ON_CHANGEPOSITION, 0, _currentStep, _currentSpeed);
  241. runMode = 1;
  242. _currentSpeed = homing_speed;
  243. if (last_trigger!=EVT_ON_LIMIT_LOW && last_trigger!=EVT_ON_LIMIT_HIGH){compensatePlay(_currentSpeed);}
  244. stepper->setSpeed(homing_speed);
  245. position_timer.setFromNow(this, POSITION_SEND_TIMER);
  246. limits_timer.setFromNow(this, LIMIT_UPDATE_RATE);
  247. return;
  248. case LP_HOMING_HIGH:
  249. stepper_update();
  250. if(limitHigh_State) {
  251. _maxStep = stepper->currentPosition();
  252. _currentStep = _maxStep;
  253. homingHigh_done = 1;
  254. runMode = 0 ;
  255. trigger(EVT_EMERGENCY_STOP);
  256. push(connectors, ON_ONHOMINGHIGH, 0, _currentStep, homingHigh_done);
  257. }
  258. else if (changed && limitLow_State &&_limitLow_Hard ){ //if hit low limit and low is hard, stop
  259. homingHigh_done = 0;
  260. runMode = 0 ;
  261. trigger(EVT_EMERGENCY_STOP);
  262. push(connectors, ON_ONHOMINGHIGH, 0, _currentStep, homingHigh_done);
  263. }
  264. return;
  265. case EXT_HOMING_HIGH:
  266. return;
  267. case ENT_LIMIT_LOW:
  268. /*triggered by a change in limit state
  269. if state is 0, we may leave this state for running
  270. if state is 1 we stay in limit state loop, where moves are allowed only in
  271. the free direction, until a trigger comes with state 0
  272. */
  273. push( connectors, ON_ONLIMITLOW, 0, limitLow_State, 0 );
  274. push(connectors, ON_CHANGEPOSITION, 0, _currentStep, _currentSpeed);
  275. if (!limitLow_State){trigger(EVT_MOVE);}
  276. return;
  277. case LP_LIMIT_LOW:
  278. //stop motor if going down, allow going up
  279. // if(_limitLow_Hard && (_targetStep < _currentStep)) {
  280. if(_limitLow_Hard && (stepper->speed()<0.)) {
  281. // Serial.println("youpi");
  282. // _currentStep = stepper->currentPosition();
  283. stepper->moveTo(_currentStep);
  284. _targetStep = _currentStep;
  285. stepper->setSpeed(0);
  286. }
  287. stepper_update();
  288. //else{} // _isHoming ? trigger(EVT_STOP):
  289. return;
  290. case ENT_LIMIT_HIGH:
  291. push( connectors, ON_ONLIMITHIGH, 0, limitHigh_State, 0 );
  292. push(connectors, ON_CHANGEPOSITION, 0, _currentStep, _currentSpeed);
  293. if (!limitHigh_State){trigger(EVT_MOVE);};
  294. return;
  295. case LP_LIMIT_HIGH:
  296. //stop motor if going down, allow going up
  297. if(_limitHigh_Hard && (_currentSpeed>0.)) {
  298. // Serial.println("youpi");
  299. // _currentStep = stepper->currentPosition();
  300. stepper->moveTo(_currentStep);
  301. _targetStep = _currentStep;
  302. stepper->setSpeed(0);
  303. }
  304. stepper_update();
  305. // else{}
  306. return;
  307. }
  308. }
  309. /* Optionally override the default trigger() method
  310. * Control how your machine processes triggers
  311. */
  312. Atm_AccelStepper& Atm_AccelStepper::trigger( int event ) {
  313. Machine::trigger( event );
  314. return *this;
  315. }
  316. /* Optionally override the default state() method
  317. * Control what the machine returns when another process requests its state
  318. */
  319. int Atm_AccelStepper::state( void ) {
  320. return Machine::state();
  321. }
  322. /* Nothing customizable below this line
  323. ************************************************************************************************
  324. */
  325. /* Still I'll customize a little just here
  326. */
  327. void Atm_AccelStepper::stepper_update(void) {
  328. switch (runMode) {
  329. case 0: //positional modae
  330. stepper->run();
  331. break;
  332. case 1: // speed mode
  333. stepper->runSpeed();
  334. break;
  335. }
  336. _currentSpeed = stepper->speed();
  337. if (_currentSpeed) {direction = _currentSpeed>0 ? 1 : 0;}
  338. long int tempStep = stepper->currentPosition();
  339. if (tempStep != _currentStep){
  340. _currentStep = tempStep;
  341. //Serial.println(stepper->currentPosition());
  342. if (position_timer.expired(this)){
  343. push(connectors, ON_CHANGEPOSITION, 0, _currentStep, _currentSpeed);
  344. position_timer.setFromNow(this, POSITION_SEND_TIMER);
  345. }
  346. }
  347. }
  348. Atm_AccelStepper& Atm_AccelStepper::setMaxStep( long int maxStep ) {
  349. _maxStep = maxStep;
  350. return *this ;
  351. }
  352. Atm_AccelStepper& Atm_AccelStepper::setMaxSpeed( long int maxSpeed){
  353. max_speed = maxSpeed ;
  354. stepper->setMaxSpeed(max_speed);
  355. return *this ;
  356. }
  357. Atm_AccelStepper& Atm_AccelStepper::setHomingSpeed(long int homingSpeed){
  358. homing_speed = homingSpeed ;
  359. return *this ;
  360. }
  361. Atm_AccelStepper& Atm_AccelStepper::setAcceleration(long int acc){
  362. acceleration = acc ;
  363. stepper->setAcceleration(acceleration);
  364. return *this ;
  365. }
  366. Atm_AccelStepper& Atm_AccelStepper::setPosition(long int position){
  367. stepper->setCurrentPosition(position);
  368. _currentStep = position ;
  369. return *this ;
  370. }
  371. Atm_AccelStepper& Atm_AccelStepper::setPlayCompensation(long int steps){
  372. playSteps = steps ;
  373. }
  374. bool Atm_AccelStepper::compensatePlay(int speed){ //check if there is a change in direction,
  375. //use just after _targetStep update and before moving
  376. bool newDirection ;
  377. switch (runMode) {
  378. case 0: //positional modae
  379. newDirection = _targetStep > _currentStep;
  380. break;
  381. case 1: // speed mode
  382. newDirection = speed>0;
  383. break;
  384. }
  385. if (direction != newDirection){
  386. long int compensation = newDirection ? -playSteps : playSteps ;
  387. setPosition(_currentStep + compensation);
  388. Serial.print("play compensation ");
  389. Serial.println(compensation);
  390. return 1;
  391. }
  392. else{return 0;}
  393. }
  394. long int Atm_AccelStepper::getPosition(){
  395. return stepper->currentPosition();;
  396. }
  397. long int Atm_AccelStepper::distanceToGo(){
  398. return stepper->distanceToGo();;
  399. }
  400. bool Atm_AccelStepper::isRunning(){
  401. return stepper->isRunning();
  402. }
  403. float Atm_AccelStepper::getSpeed(){
  404. return stepper->speed();
  405. }
  406. Atm_AccelStepper& Atm_AccelStepper::position_refresh(long int refresh_ms){
  407. POSITION_SEND_TIMER = refresh_ms ;
  408. return *this ;
  409. }
  410. Atm_AccelStepper& Atm_AccelStepper::move( long int stepRel) {
  411. _targetStep = _currentStep + stepRel;
  412. runMode = 0;
  413. stepper->moveTo(_targetStep);
  414. _currentSpeed = stepper->speed();
  415. enable();
  416. trigger( EVT_MOVE );
  417. return *this;
  418. }
  419. Atm_AccelStepper& Atm_AccelStepper::moveTo( long int stepAbs) {
  420. _targetStep = stepAbs;
  421. runMode = 0;
  422. stepper->moveTo(_targetStep);
  423. _currentSpeed = stepper->speed();
  424. enable();
  425. trigger( EVT_MOVE );
  426. return *this;
  427. }
  428. Atm_AccelStepper& Atm_AccelStepper::movePercent( float percent) {
  429. _targetStep = (float)_currentStep + percent/100.*float(_maxStep);
  430. runMode = 0;
  431. // Serial.println(_targetStep);
  432. stepper->moveTo(_targetStep);
  433. _currentSpeed = stepper->speed();
  434. enable();
  435. trigger( EVT_MOVE );
  436. return *this;
  437. }
  438. Atm_AccelStepper& Atm_AccelStepper::moveToPercent( float percent) {
  439. _targetStep = (float) percent/100*float(_maxStep) ;
  440. runMode = 0;
  441. stepper->moveTo(_targetStep);
  442. _currentSpeed = stepper->speed();
  443. enable();
  444. trigger( EVT_MOVE );
  445. return *this;
  446. }
  447. Atm_AccelStepper& Atm_AccelStepper::rotate( long int speed) {
  448. runMode = 1;
  449. stepper->setSpeed( speed);
  450. _currentSpeed = stepper->speed();
  451. stepper_update();
  452. enable();
  453. trigger( EVT_MOVE );
  454. return *this;
  455. }
  456. Atm_AccelStepper& Atm_AccelStepper::homing( bool homingDirection ){
  457. enable();
  458. homingDirection == 1 ? this->trigger(EVT_HOMING_HIGH) : this->trigger(EVT_HOMING_LOW);
  459. return *this;
  460. }
  461. int Atm_AccelStepper::limitLow_avg(bool limistate){
  462. limitLow_state_total = limitLow_state_total + limistate - limitLow_state_buf[limitLow_buf_head];
  463. limitLow_state_buf[limitLow_buf_head] = limistate;
  464. if ( limitLow_buf_head + 1 >= limit_buf_size ) {
  465. limitLow_buf_head = 0;
  466. } else {
  467. limitLow_buf_head++;
  468. }
  469. return limitLow_state_total > limit_buf_size / 2; //all values should agree
  470. }
  471. int Atm_AccelStepper::limitHigh_avg(bool limistate){
  472. limitHigh_state_total = limitHigh_state_total + limistate - limitHigh_state_buf[limitHigh_buf_head];
  473. limitHigh_state_buf[limitHigh_buf_head] = limistate;
  474. if ( limitHigh_buf_head + 1 >= limit_buf_size ) {
  475. limitHigh_buf_head = 0;
  476. } else {
  477. limitHigh_buf_head++;
  478. }
  479. return limitHigh_state_total > limit_buf_size / 2; //all values should agree
  480. }
  481. Atm_AccelStepper& Atm_AccelStepper::setEnablePin( int enablePin ){
  482. _enablePin = enablePin ;
  483. pinMode(_enablePin, OUTPUT);
  484. return *this;
  485. }
  486. Atm_AccelStepper& Atm_AccelStepper::pinReversed( bool directionInvert,
  487. bool stepInvert, bool enableInvert){
  488. stepper->setPinsInverted(directionInvert, stepInvert, enableInvert);
  489. return *this;
  490. }
  491. Atm_AccelStepper& Atm_AccelStepper::limitLow_set(int mode, int pin, int reversed){
  492. _limitLow_Mode = mode ;
  493. _limitLow_Pin = pin ;
  494. _limitLow_Reversed = reversed ;
  495. if (_limitLow_Mode==1) {pinMode(_limitLow_Pin, INPUT_PULLUP);}
  496. if (_limitLow_Mode==2) {pinMode(_limitLow_Pin, INPUT);}
  497. return *this;
  498. }
  499. Atm_AccelStepper& Atm_AccelStepper::limitLow_isHard(bool hardlimit){
  500. _limitLow_Hard = hardlimit;
  501. return *this;
  502. }
  503. Atm_AccelStepper& Atm_AccelStepper::limitLow_setThresholds (int threshold_low, int threshold_high){
  504. _limitLow_Thresholds[0] = threshold_low ;
  505. _limitLow_Thresholds[1] = threshold_high ;
  506. return *this;
  507. }
  508. Atm_AccelStepper& Atm_AccelStepper::limitHigh_set(int mode, int pin, int reversed){
  509. _limitHigh_Mode = mode ;
  510. _limitHigh_Pin = pin ;
  511. _limitHigh_Reversed = reversed ;
  512. if (_limitHigh_Mode==1) {pinMode(_limitHigh_Pin, INPUT_PULLUP);}
  513. if (_limitHigh_Mode==2) {pinMode(_limitHigh_Pin, INPUT);}
  514. return *this;
  515. }
  516. Atm_AccelStepper& Atm_AccelStepper::limitHigh_isHard(bool hardlimit){
  517. _limitHigh_Hard = hardlimit;
  518. return *this;
  519. }
  520. Atm_AccelStepper& Atm_AccelStepper::limitHigh_setThresholds (int threshold_low, int threshold_high){
  521. _limitHigh_Thresholds[0] = threshold_low ;
  522. _limitHigh_Thresholds[1] = threshold_high ;
  523. return *this;
  524. }
  525. /* Public event methods
  526. *
  527. */
  528. Atm_AccelStepper& Atm_AccelStepper::disable() {
  529. trigger( EVT_DISABLE );
  530. return *this;
  531. }
  532. Atm_AccelStepper& Atm_AccelStepper::enable() {
  533. trigger( EVT_ENABLE );
  534. return *this;
  535. }
  536. // Atm_AccelStepper& Atm_AccelStepper::move() {
  537. // trigger( EVT_MOVE );
  538. // return *this;
  539. // }
  540. Atm_AccelStepper& Atm_AccelStepper::stop() {
  541. trigger( EVT_STOP );
  542. return *this;
  543. }
  544. Atm_AccelStepper& Atm_AccelStepper::emergency_stop() {
  545. trigger( EVT_EMERGENCY_STOP );
  546. return *this;
  547. }
  548. Atm_AccelStepper& Atm_AccelStepper::on_limit_low() {
  549. trigger( EVT_ON_LIMIT_LOW );
  550. return *this;
  551. }
  552. Atm_AccelStepper& Atm_AccelStepper::on_limit_high() {
  553. trigger( EVT_ON_LIMIT_HIGH );
  554. return *this;
  555. }
  556. Atm_AccelStepper& Atm_AccelStepper::on_target() {
  557. trigger( EVT_ON_TARGET );
  558. return *this;
  559. }
  560. /*
  561. * onChangeposition() push connector variants ( slots 1, autostore 0, broadcast 0 )
  562. */
  563. Atm_AccelStepper& Atm_AccelStepper::onChangeposition( Machine& machine, int event ) {
  564. onPush( connectors, ON_CHANGEPOSITION, 0, 1, 1, machine, event );
  565. return *this;
  566. }
  567. Atm_AccelStepper& Atm_AccelStepper::onChangeposition( atm_cb_push_t callback, int idx ) {
  568. onPush( connectors, ON_CHANGEPOSITION, 0, 1, 1, callback, idx );
  569. return *this;
  570. }
  571. /*
  572. * onChangestate() push connector variants ( slots 1, autostore 0, broadcast 0 )
  573. */
  574. Atm_AccelStepper& Atm_AccelStepper::onChangestate( Machine& machine, int event ) {
  575. onPush( connectors, ON_CHANGESTATE, 0, 1, 1, machine, event );
  576. return *this;
  577. }
  578. Atm_AccelStepper& Atm_AccelStepper::onChangestate( atm_cb_push_t callback, int idx ) {
  579. onPush( connectors, ON_CHANGESTATE, 0, 1, 1, callback, idx );
  580. return *this;
  581. }
  582. /*
  583. * onOnlimithigh() push connector variants ( slots 1, autostore 0, broadcast 0 )
  584. */
  585. Atm_AccelStepper& Atm_AccelStepper::onOnlimithigh( Machine& machine, int event ) {
  586. onPush( connectors, ON_ONLIMITHIGH, 0, 1, 1, machine, event );
  587. return *this;
  588. }
  589. Atm_AccelStepper& Atm_AccelStepper::onOnlimithigh( atm_cb_push_t callback, int idx ) {
  590. onPush( connectors, ON_ONLIMITHIGH, 0, 1, 1, callback, idx );
  591. return *this;
  592. }
  593. /*
  594. * onOnlimitlow() push connector variants ( slots 1, autostore 0, broadcast 0 )
  595. */
  596. Atm_AccelStepper& Atm_AccelStepper::onOnlimitlow( Machine& machine, int event ) {
  597. onPush( connectors, ON_ONLIMITLOW, 0, 1, 1, machine, event );
  598. return *this;
  599. }
  600. Atm_AccelStepper& Atm_AccelStepper::onOnlimitlow( atm_cb_push_t callback, int idx ) {
  601. onPush( connectors, ON_ONLIMITLOW, 0, 1, 1, callback, idx );
  602. return *this;
  603. }
  604. /*
  605. * onOntarget() push connector variants ( slots 1, autostore 0, broadcast 0 )
  606. */
  607. Atm_AccelStepper& Atm_AccelStepper::onOntarget( Machine& machine, int event ) {
  608. onPush( connectors, ON_ONTARGET, 0, 1, 1, machine, event );
  609. return *this;
  610. }
  611. Atm_AccelStepper& Atm_AccelStepper::onOntarget( atm_cb_push_t callback, int idx ) {
  612. onPush( connectors, ON_ONTARGET, 0, 1, 1, callback, idx );
  613. return *this;
  614. }
  615. /*
  616. * onStop() push connector variants ( slots 1, autostore 0, broadcast 0 )
  617. */
  618. Atm_AccelStepper& Atm_AccelStepper::onStop( Machine& machine, int event ) {
  619. onPush( connectors, ON_STOP, 0, 1, 1, machine, event );
  620. return *this;
  621. }
  622. Atm_AccelStepper& Atm_AccelStepper::onStop( atm_cb_push_t callback, int idx ) {
  623. onPush( connectors, ON_STOP, 0, 1, 1, callback, idx );
  624. return *this;
  625. }
  626. Atm_AccelStepper& Atm_AccelStepper::onOnhominglow( Machine& machine, int event ) {
  627. onPush( connectors, ON_ONHOMINGLOW, 0, 1, 1, machine, event );
  628. return *this;
  629. }
  630. Atm_AccelStepper& Atm_AccelStepper::onOnhominglow( atm_cb_push_t callback, int idx ) {
  631. onPush( connectors, ON_ONHOMINGLOW, 0, 1, 1, callback, idx );
  632. return *this;
  633. }
  634. Atm_AccelStepper& Atm_AccelStepper::onOnhominghigh( Machine& machine, int event ) {
  635. onPush( connectors, ON_ONHOMINGHIGH, 0, 1, 1, machine, event );
  636. return *this;
  637. }
  638. Atm_AccelStepper& Atm_AccelStepper::onOnhominghigh( atm_cb_push_t callback, int idx ) {
  639. onPush( connectors, ON_ONHOMINGHIGH, 0, 1, 1, callback, idx );
  640. return *this;
  641. }
  642. /* State trace method
  643. * Sets the symbol table and the default logging method for serial monitoring
  644. */
  645. Atm_AccelStepper& Atm_AccelStepper::trace( Stream & stream ) {
  646. Machine::setTrace( &stream, atm_serial_debug::trace,
  647. "ACCELSTEPPER\0EVT_DISABLE\0EVT_ENABLE\0EVT_ENABLED_TIMEOUT\0EVT_MOVE\0EVT_STOP\0EVT_EMERGENCY_STOP\0EVT_ON_LIMIT_LOW\0EVT_ON_LIMIT_HIGH\0EVT_ON_TARGET\0EVT_HOMING_LOW\0EVT_HOMING_HIGH\0ELSE\0DISABLED\0ENABLED\0RUNNING\0STOP\0HOMING_LOW\0HOMING_HIGH\0LIMIT_LOW\0LIMIT_HIGH" );
  648. return *this;
  649. }
  650. // #endif