Atm_AccelStepper.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  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. _currentSpeed = stepper->speed();
  153. if (last_trigger!=EVT_ON_LIMIT_LOW && last_trigger!=EVT_ON_LIMIT_HIGH){compensatePlay(_currentSpeed);}
  154. if (runMode){stepper->setSpeed( _currentSpeed);}
  155. else{stepper->moveTo(_targetStep);}
  156. position_timer.setFromNow(this, POSITION_SEND_TIMER);
  157. limits_timer.setFromNow(this, LIMIT_UPDATE_RATE);
  158. return;
  159. case LP_RUNNING:
  160. // if on limits and limits are hard, stop moving in one direction
  161. if(limitLow_State && _limitLow_Hard && (_currentSpeed<0.)) {
  162. trigger(EVT_EMERGENCY_STOP);
  163. }
  164. if( limitHigh_State && _limitHigh_Hard && (_currentSpeed>0.)) {
  165. trigger(EVT_EMERGENCY_STOP);
  166. }
  167. // if hard limits and homing is done, check current position is within limits
  168. if (_limitLow_Hard && homingLow_done) {
  169. if( (_currentStep<0) && (_currentSpeed<0.)) {trigger(EVT_EMERGENCY_STOP);}
  170. }
  171. if (_limitHigh_Hard && _maxStep) { //maxstep is 0 if not defined
  172. if( (_currentStep>_maxStep) && (_currentSpeed>0.)) {trigger(EVT_EMERGENCY_STOP);}
  173. }
  174. stepper_update();
  175. if(runMode && _currentSpeed == 0.) {trigger(EVT_EMERGENCY_STOP);}//trigger(EVT_ON_TARGET);
  176. if(!runMode && (_currentStep==_targetStep)){push( connectors, ON_ONTARGET, 0, _currentStep, 0 );trigger(EVT_EMERGENCY_STOP);}
  177. return;
  178. case ENT_STOP:
  179. push(connectors, ON_CHANGESTATE, 0, state(), 0);
  180. if (last_trigger == EVT_STOP) {
  181. runMode = 0 ;
  182. // stepper->setSpeed(stepper->speed());
  183. // stepper_update();
  184. stepper->stop();
  185. _targetStep = stepper->targetPosition();
  186. // push( connectors, ON_STOP, 0, 0, 0 );
  187. }
  188. if (last_trigger == EVT_EMERGENCY_STOP) {
  189. runMode=0 ;
  190. stepper->setSpeed(0);
  191. _currentStep = stepper->currentPosition();
  192. _targetStep = _currentStep ;
  193. stepper->setCurrentPosition(_currentStep);
  194. // stepper->moveTo(_targetStep);
  195. // push(connectors, ON_CHANGEPOSITION, 0, _currentStep, stepper->speed());
  196. // push( connectors, ON_STOP, 0, 1, 0 );
  197. }
  198. stepper_update();
  199. // push(connectors, ON_CHANGEPOSITION, 0, _currentStep, stepper->speed());
  200. return;
  201. case LP_STOP:
  202. stepper_update();
  203. if(_currentSpeed == 0.) {trigger(EVT_ENABLE);}
  204. return;
  205. case ENT_HOMING_LOW:
  206. homingLow_done = 0;
  207. push(connectors, ON_CHANGESTATE, 0, state(), 0);
  208. push(connectors, ON_CHANGEPOSITION, 0, _currentStep, _currentSpeed);
  209. runMode = 1;
  210. _currentSpeed = -1*homing_speed;
  211. if (last_trigger!=EVT_ON_LIMIT_LOW && last_trigger!=EVT_ON_LIMIT_HIGH){compensatePlay(_currentSpeed);}
  212. stepper->setSpeed(-1*homing_speed);
  213. position_timer.setFromNow(this, POSITION_SEND_TIMER);
  214. limits_timer.setFromNow(this, LIMIT_UPDATE_RATE);
  215. return;
  216. case LP_HOMING_LOW:
  217. stepper_update();
  218. if(limitLow_State) {
  219. stepper->setCurrentPosition(0);
  220. _currentStep = 0;
  221. homingLow_done = 1 ;
  222. runMode = 0;
  223. trigger(EVT_EMERGENCY_STOP);
  224. push(connectors, ON_ONHOMINGLOW, 0, _currentStep, homingLow_done);
  225. }
  226. else if (changed && limitHigh_State && _limitHigh_Hard ){ //hit high limit and high is hard, stop
  227. homingLow_done = 0 ;
  228. runMode = 0;
  229. trigger(EVT_EMERGENCY_STOP);
  230. push(connectors, ON_ONHOMINGLOW, 0, _currentStep, homingLow_done);
  231. }
  232. return;
  233. case EXT_HOMING_LOW:
  234. return;
  235. case ENT_HOMING_HIGH:
  236. push(connectors, ON_CHANGESTATE, 0, state(), 0);
  237. push(connectors, ON_CHANGEPOSITION, 0, _currentStep, _currentSpeed);
  238. runMode = 1;
  239. _currentSpeed = homing_speed;
  240. if (last_trigger!=EVT_ON_LIMIT_LOW && last_trigger!=EVT_ON_LIMIT_HIGH){compensatePlay(_currentSpeed);}
  241. stepper->setSpeed(homing_speed);
  242. position_timer.setFromNow(this, POSITION_SEND_TIMER);
  243. limits_timer.setFromNow(this, LIMIT_UPDATE_RATE);
  244. return;
  245. case LP_HOMING_HIGH:
  246. stepper_update();
  247. if(limitHigh_State) {
  248. _maxStep = stepper->currentPosition();
  249. _currentStep = _maxStep;
  250. homingHigh_done = 1;
  251. runMode = 0 ;
  252. trigger(EVT_EMERGENCY_STOP);
  253. push(connectors, ON_ONHOMINGHIGH, 0, _currentStep, homingHigh_done);
  254. }
  255. else if (changed && limitLow_State &&_limitLow_Hard ){ //if hit low limit and low is hard, stop
  256. homingHigh_done = 0;
  257. runMode = 0 ;
  258. trigger(EVT_EMERGENCY_STOP);
  259. push(connectors, ON_ONHOMINGHIGH, 0, _currentStep, homingHigh_done);
  260. }
  261. return;
  262. case EXT_HOMING_HIGH:
  263. return;
  264. case ENT_LIMIT_LOW:
  265. /*triggered by a change in limit state
  266. if state is 0, we may leave this state for running
  267. if state is 1 we stay in limit state loop, where moves are allowed only in
  268. the free direction, until a trigger comes with state 0
  269. */
  270. push( connectors, ON_ONLIMITLOW, 0, limitLow_State, 0 );
  271. push(connectors, ON_CHANGEPOSITION, 0, _currentStep, _currentSpeed);
  272. if (!limitLow_State){trigger(EVT_MOVE);}
  273. return;
  274. case LP_LIMIT_LOW:
  275. //stop motor if going down, allow going up
  276. // if(_limitLow_Hard && (_targetStep < _currentStep)) {
  277. if(_limitLow_Hard && (stepper->speed()<0.)) {
  278. // Serial.println("youpi");
  279. // _currentStep = stepper->currentPosition();
  280. stepper->moveTo(_currentStep);
  281. _targetStep = _currentStep;
  282. stepper->setSpeed(0);
  283. }
  284. stepper_update();
  285. //else{} // _isHoming ? trigger(EVT_STOP):
  286. return;
  287. case ENT_LIMIT_HIGH:
  288. push( connectors, ON_ONLIMITHIGH, 0, limitHigh_State, 0 );
  289. push(connectors, ON_CHANGEPOSITION, 0, _currentStep, _currentSpeed);
  290. if (!limitHigh_State){trigger(EVT_MOVE);};
  291. return;
  292. case LP_LIMIT_HIGH:
  293. //stop motor if going down, allow going up
  294. if(_limitHigh_Hard && (_currentSpeed>0.)) {
  295. // Serial.println("youpi");
  296. // _currentStep = stepper->currentPosition();
  297. stepper->moveTo(_currentStep);
  298. _targetStep = _currentStep;
  299. stepper->setSpeed(0);
  300. }
  301. stepper_update();
  302. // else{}
  303. return;
  304. }
  305. }
  306. /* Optionally override the default trigger() method
  307. * Control how your machine processes triggers
  308. */
  309. Atm_AccelStepper& Atm_AccelStepper::trigger( int event ) {
  310. Machine::trigger( event );
  311. return *this;
  312. }
  313. /* Optionally override the default state() method
  314. * Control what the machine returns when another process requests its state
  315. */
  316. int Atm_AccelStepper::state( void ) {
  317. return Machine::state();
  318. }
  319. /* Nothing customizable below this line
  320. ************************************************************************************************
  321. */
  322. /* Still I'll customize a little just here
  323. */
  324. void Atm_AccelStepper::stepper_update(void) {
  325. switch (runMode) {
  326. case 0: //positional modae
  327. stepper->run();
  328. break;
  329. case 1: // speed mode
  330. stepper->runSpeed();
  331. break;
  332. }
  333. _currentSpeed = stepper->speed();
  334. if (_currentSpeed) {direction = _currentSpeed>0 ? 1 : 0;}
  335. long int tempStep = stepper->currentPosition();
  336. if (tempStep != _currentStep){
  337. _currentStep = tempStep;
  338. //Serial.println(stepper->currentPosition());
  339. if (position_timer.expired(this)){
  340. push(connectors, ON_CHANGEPOSITION, 0, _currentStep, _currentSpeed);
  341. position_timer.setFromNow(this, POSITION_SEND_TIMER);
  342. }
  343. }
  344. }
  345. Atm_AccelStepper& Atm_AccelStepper::setMaxStep( long int maxStep ) {
  346. _maxStep = maxStep;
  347. return *this ;
  348. }
  349. Atm_AccelStepper& Atm_AccelStepper::setMaxSpeed( long int maxSpeed){
  350. max_speed = maxSpeed ;
  351. stepper->setMaxSpeed(max_speed);
  352. return *this ;
  353. }
  354. Atm_AccelStepper& Atm_AccelStepper::setHomingSpeed(long int homingSpeed){
  355. homing_speed = homingSpeed ;
  356. return *this ;
  357. }
  358. Atm_AccelStepper& Atm_AccelStepper::setAcceleration(long int acc){
  359. acceleration = acc ;
  360. stepper->setAcceleration(acceleration);
  361. return *this ;
  362. }
  363. Atm_AccelStepper& Atm_AccelStepper::setPosition(long int position){
  364. stepper->setCurrentPosition(position);
  365. _currentStep = position ;
  366. return *this ;
  367. }
  368. Atm_AccelStepper& Atm_AccelStepper::setPlayCompensation(long int steps){
  369. playSteps = steps ;
  370. }
  371. bool Atm_AccelStepper::compensatePlay(int speed){ //check if there is a change in direction,
  372. //use just after _targetStep update and before moving
  373. bool newDirection ;
  374. switch (runMode) {
  375. case 0: //positional modae
  376. newDirection = _targetStep > _currentStep;
  377. break;
  378. case 1: // speed mode
  379. newDirection = speed>0;
  380. break;
  381. }
  382. if (direction != newDirection){
  383. long int compensation = newDirection ? -playSteps : playSteps ;
  384. setPosition(_currentStep + compensation);
  385. Serial.print("play compensation ");
  386. Serial.println(compensation);
  387. return 1;
  388. }
  389. else{return 0;}
  390. }
  391. long int Atm_AccelStepper::getPosition(){
  392. return stepper->currentPosition();;
  393. }
  394. long int Atm_AccelStepper::distanceToGo(){
  395. return stepper->distanceToGo();;
  396. }
  397. bool Atm_AccelStepper::isRunning(){
  398. return stepper->isRunning();
  399. }
  400. float Atm_AccelStepper::getSpeed(){
  401. return stepper->speed();
  402. }
  403. Atm_AccelStepper& Atm_AccelStepper::position_refresh(long int refresh_ms){
  404. POSITION_SEND_TIMER = refresh_ms ;
  405. return *this ;
  406. }
  407. Atm_AccelStepper& Atm_AccelStepper::move( long int stepRel) {
  408. _targetStep = _currentStep + stepRel;
  409. runMode = 0;
  410. stepper->moveTo(_targetStep);
  411. enable();
  412. trigger( EVT_MOVE );
  413. return *this;
  414. }
  415. Atm_AccelStepper& Atm_AccelStepper::moveTo( long int stepAbs) {
  416. _targetStep = stepAbs;
  417. runMode = 0;
  418. stepper->moveTo(_targetStep);
  419. enable();
  420. trigger( EVT_MOVE );
  421. return *this;
  422. }
  423. Atm_AccelStepper& Atm_AccelStepper::movePercent( float percent) {
  424. _targetStep = (float)_currentStep + percent/100.*float(_maxStep);
  425. runMode = 0;
  426. // Serial.println(_targetStep);
  427. stepper->moveTo(_targetStep);
  428. enable();
  429. trigger( EVT_MOVE );
  430. return *this;
  431. }
  432. Atm_AccelStepper& Atm_AccelStepper::moveToPercent( float percent) {
  433. _targetStep = (float) percent/100*float(_maxStep) ;
  434. runMode = 0;
  435. stepper->moveTo(_targetStep);
  436. enable();
  437. trigger( EVT_MOVE );
  438. return *this;
  439. }
  440. Atm_AccelStepper& Atm_AccelStepper::rotate( long int speed) {
  441. runMode = 1;
  442. stepper->setSpeed( speed);
  443. enable();
  444. trigger( EVT_MOVE );
  445. return *this;
  446. }
  447. Atm_AccelStepper& Atm_AccelStepper::homing( bool homingDirection ){
  448. enable();
  449. homingDirection == 1 ? this->trigger(EVT_HOMING_HIGH) : this->trigger(EVT_HOMING_LOW);
  450. return *this;
  451. }
  452. int Atm_AccelStepper::limitLow_avg(bool limistate){
  453. limitLow_state_total = limitLow_state_total + limistate - limitLow_state_buf[limitLow_buf_head];
  454. limitLow_state_buf[limitLow_buf_head] = limistate;
  455. if ( limitLow_buf_head + 1 >= limit_buf_size ) {
  456. limitLow_buf_head = 0;
  457. } else {
  458. limitLow_buf_head++;
  459. }
  460. return limitLow_state_total > limit_buf_size / 2; //all values should agree
  461. }
  462. int Atm_AccelStepper::limitHigh_avg(bool limistate){
  463. limitHigh_state_total = limitHigh_state_total + limistate - limitHigh_state_buf[limitHigh_buf_head];
  464. limitHigh_state_buf[limitHigh_buf_head] = limistate;
  465. if ( limitHigh_buf_head + 1 >= limit_buf_size ) {
  466. limitHigh_buf_head = 0;
  467. } else {
  468. limitHigh_buf_head++;
  469. }
  470. return limitHigh_state_total > limit_buf_size / 2; //all values should agree
  471. }
  472. Atm_AccelStepper& Atm_AccelStepper::setEnablePin( int enablePin ){
  473. _enablePin = enablePin ;
  474. pinMode(_enablePin, OUTPUT);
  475. return *this;
  476. }
  477. Atm_AccelStepper& Atm_AccelStepper::pinReversed( bool directionInvert,
  478. bool stepInvert, bool enableInvert){
  479. stepper->setPinsInverted(directionInvert, stepInvert, enableInvert);
  480. return *this;
  481. }
  482. Atm_AccelStepper& Atm_AccelStepper::limitLow_set(int mode, int pin, int reversed){
  483. _limitLow_Mode = mode ;
  484. _limitLow_Pin = pin ;
  485. _limitLow_Reversed = reversed ;
  486. if (_limitLow_Mode==1) {pinMode(_limitLow_Pin, INPUT_PULLUP);}
  487. if (_limitLow_Mode==2) {pinMode(_limitLow_Pin, INPUT);}
  488. return *this;
  489. }
  490. Atm_AccelStepper& Atm_AccelStepper::limitLow_isHard(bool hardlimit){
  491. _limitLow_Hard = hardlimit;
  492. return *this;
  493. }
  494. Atm_AccelStepper& Atm_AccelStepper::limitLow_setThresholds (int threshold_low, int threshold_high){
  495. _limitLow_Thresholds[0] = threshold_low ;
  496. _limitLow_Thresholds[1] = threshold_high ;
  497. return *this;
  498. }
  499. Atm_AccelStepper& Atm_AccelStepper::limitHigh_set(int mode, int pin, int reversed){
  500. _limitHigh_Mode = mode ;
  501. _limitHigh_Pin = pin ;
  502. _limitHigh_Reversed = reversed ;
  503. if (_limitHigh_Mode==1) {pinMode(_limitHigh_Pin, INPUT_PULLUP);}
  504. if (_limitHigh_Mode==2) {pinMode(_limitHigh_Pin, INPUT);}
  505. return *this;
  506. }
  507. Atm_AccelStepper& Atm_AccelStepper::limitHigh_isHard(bool hardlimit){
  508. _limitHigh_Hard = hardlimit;
  509. return *this;
  510. }
  511. Atm_AccelStepper& Atm_AccelStepper::limitHigh_setThresholds (int threshold_low, int threshold_high){
  512. _limitHigh_Thresholds[0] = threshold_low ;
  513. _limitHigh_Thresholds[1] = threshold_high ;
  514. return *this;
  515. }
  516. /* Public event methods
  517. *
  518. */
  519. Atm_AccelStepper& Atm_AccelStepper::disable() {
  520. trigger( EVT_DISABLE );
  521. return *this;
  522. }
  523. Atm_AccelStepper& Atm_AccelStepper::enable() {
  524. trigger( EVT_ENABLE );
  525. return *this;
  526. }
  527. // Atm_AccelStepper& Atm_AccelStepper::move() {
  528. // trigger( EVT_MOVE );
  529. // return *this;
  530. // }
  531. Atm_AccelStepper& Atm_AccelStepper::stop() {
  532. trigger( EVT_STOP );
  533. return *this;
  534. }
  535. Atm_AccelStepper& Atm_AccelStepper::emergency_stop() {
  536. trigger( EVT_EMERGENCY_STOP );
  537. return *this;
  538. }
  539. Atm_AccelStepper& Atm_AccelStepper::on_limit_low() {
  540. trigger( EVT_ON_LIMIT_LOW );
  541. return *this;
  542. }
  543. Atm_AccelStepper& Atm_AccelStepper::on_limit_high() {
  544. trigger( EVT_ON_LIMIT_HIGH );
  545. return *this;
  546. }
  547. Atm_AccelStepper& Atm_AccelStepper::on_target() {
  548. trigger( EVT_ON_TARGET );
  549. return *this;
  550. }
  551. /*
  552. * onChangeposition() push connector variants ( slots 1, autostore 0, broadcast 0 )
  553. */
  554. Atm_AccelStepper& Atm_AccelStepper::onChangeposition( Machine& machine, int event ) {
  555. onPush( connectors, ON_CHANGEPOSITION, 0, 1, 1, machine, event );
  556. return *this;
  557. }
  558. Atm_AccelStepper& Atm_AccelStepper::onChangeposition( atm_cb_push_t callback, int idx ) {
  559. onPush( connectors, ON_CHANGEPOSITION, 0, 1, 1, callback, idx );
  560. return *this;
  561. }
  562. /*
  563. * onChangestate() push connector variants ( slots 1, autostore 0, broadcast 0 )
  564. */
  565. Atm_AccelStepper& Atm_AccelStepper::onChangestate( Machine& machine, int event ) {
  566. onPush( connectors, ON_CHANGESTATE, 0, 1, 1, machine, event );
  567. return *this;
  568. }
  569. Atm_AccelStepper& Atm_AccelStepper::onChangestate( atm_cb_push_t callback, int idx ) {
  570. onPush( connectors, ON_CHANGESTATE, 0, 1, 1, callback, idx );
  571. return *this;
  572. }
  573. /*
  574. * onOnlimithigh() push connector variants ( slots 1, autostore 0, broadcast 0 )
  575. */
  576. Atm_AccelStepper& Atm_AccelStepper::onOnlimithigh( Machine& machine, int event ) {
  577. onPush( connectors, ON_ONLIMITHIGH, 0, 1, 1, machine, event );
  578. return *this;
  579. }
  580. Atm_AccelStepper& Atm_AccelStepper::onOnlimithigh( atm_cb_push_t callback, int idx ) {
  581. onPush( connectors, ON_ONLIMITHIGH, 0, 1, 1, callback, idx );
  582. return *this;
  583. }
  584. /*
  585. * onOnlimitlow() push connector variants ( slots 1, autostore 0, broadcast 0 )
  586. */
  587. Atm_AccelStepper& Atm_AccelStepper::onOnlimitlow( Machine& machine, int event ) {
  588. onPush( connectors, ON_ONLIMITLOW, 0, 1, 1, machine, event );
  589. return *this;
  590. }
  591. Atm_AccelStepper& Atm_AccelStepper::onOnlimitlow( atm_cb_push_t callback, int idx ) {
  592. onPush( connectors, ON_ONLIMITLOW, 0, 1, 1, callback, idx );
  593. return *this;
  594. }
  595. /*
  596. * onOntarget() push connector variants ( slots 1, autostore 0, broadcast 0 )
  597. */
  598. Atm_AccelStepper& Atm_AccelStepper::onOntarget( Machine& machine, int event ) {
  599. onPush( connectors, ON_ONTARGET, 0, 1, 1, machine, event );
  600. return *this;
  601. }
  602. Atm_AccelStepper& Atm_AccelStepper::onOntarget( atm_cb_push_t callback, int idx ) {
  603. onPush( connectors, ON_ONTARGET, 0, 1, 1, callback, idx );
  604. return *this;
  605. }
  606. /*
  607. * onStop() push connector variants ( slots 1, autostore 0, broadcast 0 )
  608. */
  609. Atm_AccelStepper& Atm_AccelStepper::onStop( Machine& machine, int event ) {
  610. onPush( connectors, ON_STOP, 0, 1, 1, machine, event );
  611. return *this;
  612. }
  613. Atm_AccelStepper& Atm_AccelStepper::onStop( atm_cb_push_t callback, int idx ) {
  614. onPush( connectors, ON_STOP, 0, 1, 1, callback, idx );
  615. return *this;
  616. }
  617. Atm_AccelStepper& Atm_AccelStepper::onOnhominglow( Machine& machine, int event ) {
  618. onPush( connectors, ON_ONHOMINGLOW, 0, 1, 1, machine, event );
  619. return *this;
  620. }
  621. Atm_AccelStepper& Atm_AccelStepper::onOnhominglow( atm_cb_push_t callback, int idx ) {
  622. onPush( connectors, ON_ONHOMINGLOW, 0, 1, 1, callback, idx );
  623. return *this;
  624. }
  625. Atm_AccelStepper& Atm_AccelStepper::onOnhominghigh( Machine& machine, int event ) {
  626. onPush( connectors, ON_ONHOMINGHIGH, 0, 1, 1, machine, event );
  627. return *this;
  628. }
  629. Atm_AccelStepper& Atm_AccelStepper::onOnhominghigh( atm_cb_push_t callback, int idx ) {
  630. onPush( connectors, ON_ONHOMINGHIGH, 0, 1, 1, callback, idx );
  631. return *this;
  632. }
  633. /* State trace method
  634. * Sets the symbol table and the default logging method for serial monitoring
  635. */
  636. Atm_AccelStepper& Atm_AccelStepper::trace( Stream & stream ) {
  637. Machine::setTrace( &stream, atm_serial_debug::trace,
  638. "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" );
  639. return *this;
  640. }
  641. // #endif