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. if (last_trigger!=EVT_ON_LIMIT_LOW && last_trigger!=EVT_ON_LIMIT_HIGH){compensatePlay(_currentSpeed);}
  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. }
  163. if( limitHigh_State && _limitHigh_Hard && (_currentSpeed>0.)) {
  164. trigger(EVT_EMERGENCY_STOP);
  165. }
  166. // if hard limits and homing is done, check current position is within limits
  167. if (_limitLow_Hard && homingLow_done) {
  168. if( (_currentStep<0) && (_currentSpeed<0.)) {trigger(EVT_EMERGENCY_STOP);}
  169. }
  170. if (_limitHigh_Hard && _maxStep) { //maxstep is 0 if not defined
  171. if( (_currentStep>_maxStep) && (_currentSpeed>0.)) {trigger(EVT_EMERGENCY_STOP);}
  172. }
  173. stepper_update();
  174. if(runMode && _currentSpeed == 0.) {trigger(EVT_EMERGENCY_STOP);}//trigger(EVT_ON_TARGET);
  175. if(!runMode && (_currentStep==_targetStep)){push( connectors, ON_ONTARGET, 0, _currentStep, 0 );trigger(EVT_EMERGENCY_STOP);}
  176. return;
  177. case ENT_STOP:
  178. push(connectors, ON_CHANGESTATE, 0, state(), 0);
  179. if (last_trigger == EVT_STOP) {
  180. runMode = 0 ;
  181. // stepper->setSpeed(stepper->speed());
  182. // stepper_update();
  183. stepper->stop();
  184. _targetStep = stepper->targetPosition();
  185. // push( connectors, ON_STOP, 0, 0, 0 );
  186. }
  187. if (last_trigger == EVT_EMERGENCY_STOP) {
  188. runMode=0 ;
  189. stepper->setSpeed(0);
  190. _currentStep = stepper->currentPosition();
  191. _targetStep = _currentStep ;
  192. stepper->setCurrentPosition(_currentStep);
  193. // stepper->moveTo(_targetStep);
  194. // push(connectors, ON_CHANGEPOSITION, 0, _currentStep, stepper->speed());
  195. // push( connectors, ON_STOP, 0, 1, 0 );
  196. }
  197. stepper_update();
  198. // push(connectors, ON_CHANGEPOSITION, 0, _currentStep, stepper->speed());
  199. return;
  200. case LP_STOP:
  201. stepper_update();
  202. if(_currentSpeed == 0.) {trigger(EVT_ENABLE);}
  203. return;
  204. case ENT_HOMING_LOW:
  205. homingLow_done = 0;
  206. push(connectors, ON_CHANGESTATE, 0, state(), 0);
  207. push(connectors, ON_CHANGEPOSITION, 0, _currentStep, _currentSpeed);
  208. runMode = 1;
  209. _currentSpeed = -1*homing_speed;
  210. if (last_trigger!=EVT_ON_LIMIT_LOW && last_trigger!=EVT_ON_LIMIT_HIGH){compensatePlay(_currentSpeed);}
  211. stepper->setSpeed(-1*homing_speed);
  212. position_timer.setFromNow(this, POSITION_SEND_TIMER);
  213. limits_timer.setFromNow(this, LIMIT_UPDATE_RATE);
  214. return;
  215. case LP_HOMING_LOW:
  216. stepper_update();
  217. if(limitLow_State) {
  218. stepper->setCurrentPosition(0);
  219. _currentStep = 0;
  220. homingLow_done = 1 ;
  221. runMode = 0;
  222. trigger(EVT_EMERGENCY_STOP);
  223. push(connectors, ON_ONHOMINGLOW, 0, _currentStep, homingLow_done);
  224. }
  225. else if (changed && limitHigh_State && _limitHigh_Hard ){ //hit high limit and high is hard, stop
  226. homingLow_done = 0 ;
  227. runMode = 0;
  228. trigger(EVT_EMERGENCY_STOP);
  229. push(connectors, ON_ONHOMINGLOW, 0, _currentStep, homingLow_done);
  230. }
  231. return;
  232. case EXT_HOMING_LOW:
  233. return;
  234. case ENT_HOMING_HIGH:
  235. push(connectors, ON_CHANGESTATE, 0, state(), 0);
  236. push(connectors, ON_CHANGEPOSITION, 0, _currentStep, _currentSpeed);
  237. runMode = 1;
  238. _currentSpeed = homing_speed;
  239. if (last_trigger!=EVT_ON_LIMIT_LOW && last_trigger!=EVT_ON_LIMIT_HIGH){compensatePlay(_currentSpeed);}
  240. stepper->setSpeed(homing_speed);
  241. position_timer.setFromNow(this, POSITION_SEND_TIMER);
  242. limits_timer.setFromNow(this, LIMIT_UPDATE_RATE);
  243. return;
  244. case LP_HOMING_HIGH:
  245. stepper_update();
  246. if(limitHigh_State) {
  247. _maxStep = stepper->currentPosition();
  248. _currentStep = _maxStep;
  249. homingHigh_done = 1;
  250. runMode = 0 ;
  251. trigger(EVT_EMERGENCY_STOP);
  252. push(connectors, ON_ONHOMINGHIGH, 0, _currentStep, homingHigh_done);
  253. }
  254. else if (changed && limitLow_State &&_limitLow_Hard ){ //if hit low limit and low is hard, stop
  255. homingHigh_done = 0;
  256. runMode = 0 ;
  257. trigger(EVT_EMERGENCY_STOP);
  258. push(connectors, ON_ONHOMINGHIGH, 0, _currentStep, homingHigh_done);
  259. }
  260. return;
  261. case EXT_HOMING_HIGH:
  262. return;
  263. case ENT_LIMIT_LOW:
  264. /*triggered by a change in limit state
  265. if state is 0, we may leave this state for running
  266. if state is 1 we stay in limit state loop, where moves are allowed only in
  267. the free direction, until a trigger comes with state 0
  268. */
  269. push( connectors, ON_ONLIMITLOW, 0, limitLow_State, 0 );
  270. push(connectors, ON_CHANGEPOSITION, 0, _currentStep, _currentSpeed);
  271. if (!limitLow_State){trigger(EVT_MOVE);}
  272. return;
  273. case LP_LIMIT_LOW:
  274. //stop motor if going down, allow going up
  275. // if(_limitLow_Hard && (_targetStep < _currentStep)) {
  276. if(_limitLow_Hard && (stepper->speed()<0.)) {
  277. // Serial.println("youpi");
  278. // _currentStep = stepper->currentPosition();
  279. stepper->moveTo(_currentStep);
  280. _targetStep = _currentStep;
  281. stepper->setSpeed(0);
  282. }
  283. stepper_update();
  284. //else{} // _isHoming ? trigger(EVT_STOP):
  285. return;
  286. case ENT_LIMIT_HIGH:
  287. push( connectors, ON_ONLIMITHIGH, 0, limitHigh_State, 0 );
  288. push(connectors, ON_CHANGEPOSITION, 0, _currentStep, _currentSpeed);
  289. if (!limitHigh_State){trigger(EVT_MOVE);};
  290. return;
  291. case LP_LIMIT_HIGH:
  292. //stop motor if going down, allow going up
  293. if(_limitHigh_Hard && (_currentSpeed>0.)) {
  294. // Serial.println("youpi");
  295. // _currentStep = stepper->currentPosition();
  296. stepper->moveTo(_currentStep);
  297. _targetStep = _currentStep;
  298. stepper->setSpeed(0);
  299. }
  300. stepper_update();
  301. // else{}
  302. return;
  303. }
  304. }
  305. /* Optionally override the default trigger() method
  306. * Control how your machine processes triggers
  307. */
  308. Atm_AccelStepper& Atm_AccelStepper::trigger( int event ) {
  309. Machine::trigger( event );
  310. return *this;
  311. }
  312. /* Optionally override the default state() method
  313. * Control what the machine returns when another process requests its state
  314. */
  315. int Atm_AccelStepper::state( void ) {
  316. return Machine::state();
  317. }
  318. /* Nothing customizable below this line
  319. ************************************************************************************************
  320. */
  321. /* Still I'll customize a little just here
  322. */
  323. void Atm_AccelStepper::stepper_update(void) {
  324. switch (runMode) {
  325. case 0: //positional modae
  326. stepper->run();
  327. break;
  328. case 1: // speed mode
  329. stepper->runSpeed();
  330. break;
  331. }
  332. _currentSpeed = stepper->speed();
  333. if (_currentSpeed) {direction = _currentSpeed>0 ? 1 : 0;}
  334. long int tempStep = stepper->currentPosition();
  335. if (tempStep != _currentStep){
  336. _currentStep = tempStep;
  337. //Serial.println(stepper->currentPosition());
  338. if (position_timer.expired(this)){
  339. push(connectors, ON_CHANGEPOSITION, 0, _currentStep, _currentSpeed);
  340. position_timer.setFromNow(this, POSITION_SEND_TIMER);
  341. }
  342. }
  343. }
  344. Atm_AccelStepper& Atm_AccelStepper::setMaxStep( long int maxStep ) {
  345. _maxStep = maxStep;
  346. return *this ;
  347. }
  348. Atm_AccelStepper& Atm_AccelStepper::setMaxSpeed( long int maxSpeed){
  349. max_speed = maxSpeed ;
  350. stepper->setMaxSpeed(max_speed);
  351. return *this ;
  352. }
  353. Atm_AccelStepper& Atm_AccelStepper::setHomingSpeed(long int homingSpeed){
  354. homing_speed = homingSpeed ;
  355. return *this ;
  356. }
  357. Atm_AccelStepper& Atm_AccelStepper::setAcceleration(long int acc){
  358. acceleration = acc ;
  359. stepper->setAcceleration(acceleration);
  360. return *this ;
  361. }
  362. Atm_AccelStepper& Atm_AccelStepper::setPosition(long int position){
  363. stepper->setCurrentPosition(position);
  364. _currentStep = position ;
  365. return *this ;
  366. }
  367. Atm_AccelStepper& Atm_AccelStepper::setPlayCompensation(long int steps){
  368. playSteps = steps ;
  369. }
  370. bool Atm_AccelStepper::compensatePlay(int speed){ //check if there is a change in direction,
  371. //use just after _targetStep update and before moving
  372. bool newDirection ;
  373. switch (runMode) {
  374. case 0: //positional modae
  375. newDirection = _targetStep > _currentStep;
  376. break;
  377. case 1: // speed mode
  378. newDirection = speed>0;
  379. break;
  380. }
  381. if (direction != newDirection){
  382. long int compensation = newDirection ? -playSteps : playSteps ;
  383. setPosition(_currentStep + compensation);
  384. Serial.print("play compensation ");
  385. Serial.println(compensation);
  386. return 1;
  387. }
  388. else{return 0;}
  389. }
  390. long int Atm_AccelStepper::getPosition(){
  391. return stepper->currentPosition();;
  392. }
  393. long int Atm_AccelStepper::distanceToGo(){
  394. return stepper->distanceToGo();;
  395. }
  396. bool Atm_AccelStepper::isRunning(){
  397. return stepper->isRunning();
  398. }
  399. float Atm_AccelStepper::getSpeed(){
  400. return stepper->speed();
  401. }
  402. Atm_AccelStepper& Atm_AccelStepper::position_refresh(long int refresh_ms){
  403. POSITION_SEND_TIMER = refresh_ms ;
  404. return *this ;
  405. }
  406. Atm_AccelStepper& Atm_AccelStepper::move( long int stepRel) {
  407. _targetStep = _currentStep + stepRel;
  408. runMode = 0;
  409. stepper->moveTo(_targetStep);
  410. enable();
  411. trigger( EVT_MOVE );
  412. return *this;
  413. }
  414. Atm_AccelStepper& Atm_AccelStepper::moveTo( long int stepAbs) {
  415. _targetStep = stepAbs;
  416. runMode = 0;
  417. stepper->moveTo(_targetStep);
  418. enable();
  419. trigger( EVT_MOVE );
  420. return *this;
  421. }
  422. Atm_AccelStepper& Atm_AccelStepper::movePercent( float percent) {
  423. _targetStep = (float)_currentStep + percent/100.*float(_maxStep);
  424. runMode = 0;
  425. // Serial.println(_targetStep);
  426. stepper->moveTo(_targetStep);
  427. enable();
  428. trigger( EVT_MOVE );
  429. return *this;
  430. }
  431. Atm_AccelStepper& Atm_AccelStepper::moveToPercent( float percent) {
  432. _targetStep = (float) percent/100*float(_maxStep) ;
  433. runMode = 0;
  434. stepper->moveTo(_targetStep);
  435. enable();
  436. trigger( EVT_MOVE );
  437. return *this;
  438. }
  439. Atm_AccelStepper& Atm_AccelStepper::rotate( long int speed) {
  440. runMode = 1;
  441. stepper->setSpeed( speed);
  442. _currentSpeed = stepper->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