#include "Atm_AccelStepper.h" /* Add optional parameters for the state machine to begin() * Add extra initialization code */ Atm_AccelStepper& Atm_AccelStepper::begin(int step_pin, int dir_pin) { // clang-format off const static state_t state_table[] PROGMEM = { /* 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 */ /* DISABLE */ ENT_DISABLED, -1, -1, -1, ENABLED, -1, RUNNING, -1, -1, -1, -1, -1, HOMING_LOW, HOMING_HIGH, -1, /* ENABLED */ ENT_ENABLED, -1, -1, DISABLE, -1, DISABLE, RUNNING, STOP, STOP, -1, -1, -1, HOMING_LOW, HOMING_HIGH, -1, /* RUNNING */ ENT_RUNNING, LP_RUNNING, -1, DISABLE, -1, -1, RUNNING, STOP, STOP, LIMIT_LOW, LIMIT_HIGH, ENABLED, -1, -1, -1, /* STOP */ ENT_STOP, LP_STOP, -1, DISABLE, -1, -1, RUNNING, -1, -1, -1, -1, ENABLED, -1, -1, -1, /* HOMING_LOW */ ENT_HOMING_LOW, LP_HOMING_LOW, EXT_HOMING_LOW, DISABLE, -1, -1, -1, STOP, STOP, LIMIT_LOW, LIMIT_HIGH, -1, -1, -1, -1, /* HOMING_HIGH */ ENT_HOMING_HIGH, LP_HOMING_HIGH, EXT_HOMING_HIGH, DISABLE, -1, -1, -1, STOP, STOP, LIMIT_LOW, LIMIT_HIGH, -1, -1, -1, -1, /* LIMIT_LOW */ ENT_LIMIT_LOW, -1, -1, -1, -1, -1, RUNNING, STOP, STOP, LIMIT_LOW, -1, -1, -1, -1, -1, /* LIMIT_HIGH */ ENT_LIMIT_HIGH, -1, -1, -1, -1, -1, RUNNING, STOP, STOP, -1, LIMIT_HIGH, -1, -1, -1, -1 }; // clang-format on Machine::begin( state_table, ELSE ); stepper = new AccelStepper(1, step_pin, dir_pin); stepper->setMaxSpeed(max_speed); stepper->setAcceleration(acceleration); idle_timer.set(ATM_TIMER_OFF); return *this; } /* Add C++ code for each internally handled event (input) * The code must return 1 to trigger the event */ int Atm_AccelStepper::event( int id ) { //updateLimitSwitch(); switch ( id ) { case EVT_DISABLE: return 0; case EVT_ENABLE: return 0; case EVT_ENABLED_TIMEOUT: return 0; case EVT_MOVE: return 0; case EVT_STOP: return 0; case EVT_EMERGENCY_STOP: return 0; case EVT_ON_LIMIT_LOW: switch(_limitLow_Mode) { case 0: // Serial.println("no limit"); return 0; case 1: //digital INPUT // Serial.println("digital"); limitLow_State = digitalRead(_limitLow_Pin); limitLow_State = _limitLow_Reversed ? !limitLow_State : limitLow_State; return limitLow_State; case 2: int analogTemp = analogRead(_limitLow_Pin); limitLow_State = (_limitLow_Thresholds[0] < analogTemp) && (analogTemp < _limitLow_Thresholds[1]); limitLow_State = _limitLow_Reversed ? !limitLow_State : limitLow_State; return limitLow_State; } case EVT_ON_LIMIT_HIGH: switch(_limitHigh_Mode) { case 0: return 0; case 1: //digital INPUT limitHigh_State = digitalRead(_limitHigh_Pin); limitHigh_State = _limitHigh_Reversed ? !limitHigh_State : limitHigh_State; return limitHigh_State; case 2: //Serial.println("analog"); int analogTemp = analogRead(_limitHigh_Pin); limitHigh_State = (_limitHigh_Thresholds[0] < analogTemp) && (analogTemp < _limitHigh_Thresholds[1]); limitHigh_State = _limitHigh_Reversed ? !limitHigh_State : limitHigh_State; return limitHigh_State; } case EVT_ON_TARGET: return _currentStep == _targetStep; case EVT_HOMING_LOW: return 0; case EVT_HOMING_HIGH: return 0; } return 0; } /* Add C++ code for each action * This generates the 'output' for the state machine * * Available connectors: * push( connectors, ON_CHANGEPOSITION, 0, , ); * push( connectors, ON_CHANGESTATE, 0, , ); * push( connectors, ON_ONLIMITHIGH, 0, , ); * push( connectors, ON_ONLIMITLOW, 0, , ); * push( connectors, ON_ONTARGET, 0, , ); * push( connectors, ON_STOP, 0, , ); */ void Atm_AccelStepper::action( int id ) { switch ( id ) { case ENT_DISABLED: push(connectors, ON_CHANGESTATE, 0, state(), 0); enabled = _enableReversed ? HIGH : LOW; digitalWrite(_enablePin, enabled); return; case ENT_ENABLED: push(connectors, ON_CHANGESTATE, 0, state(), 0); enabled = _enableReversed ? LOW : HIGH ; digitalWrite(_enablePin, enabled); return; case ENT_RUNNING: push(connectors, ON_CHANGESTATE, 0, state(), 0); return; case LP_RUNNING: stepper_update(); return; case ENT_STOP: push(connectors, ON_CHANGESTATE, 0, state(), 0); if (last_trigger == EVT_STOP) { stepper->stop(); _targetStep = stepper->targetPosition(); push( connectors, ON_STOP, 0, 0, 0 ); } if (last_trigger == EVT_EMERGENCY_STOP) { _currentStep = stepper->currentPosition(); _targetStep = _currentStep ; stepper->moveTo(_targetStep); stepper->setSpeed(0); push( connectors, ON_STOP, 0, 1, 0 ); } return; case LP_STOP: stepper_update(); _currentStep = stepper->currentPosition(); return; case ENT_HOMING_LOW: runMode = 1; stepper->setSpeed(-1*homing_speed); return; case LP_HOMING_LOW: stepper_update(); return; case EXT_HOMING_LOW: if(last_trigger == EVT_ON_LIMIT_LOW) { stepper->setCurrentPosition(0); _currentStep = 0; Serial.println("homing low done"); } else{Serial.println("homing low failed");} return; case ENT_HOMING_HIGH: runMode = 1; stepper->setSpeed(homing_speed); return; case LP_HOMING_HIGH: stepper_update(); return; case EXT_HOMING_HIGH: if(last_trigger == EVT_ON_LIMIT_HIGH) { _maxStep = stepper->currentPosition(); _currentStep = _maxStep; Serial.println("homing high done"); } else{Serial.println("homing high failed");} return; case ENT_LIMIT_LOW: push( connectors, ON_ONLIMITLOW, 0, 0, 0 ); //stop motor if going down, allow going up if(_limitLow_Hard && (stepper->speed() < 0)) {trigger(EVT_EMERGENCY_STOP);} else{stepper_update(); trigger(EVT_MOVE);} return; case ENT_LIMIT_HIGH: push( connectors, ON_ONLIMITHIGH, 0, 1, 0 ); if(_limitHigh_Hard && (stepper->speed() > 0)) {trigger(EVT_EMERGENCY_STOP);} else{stepper_update() ; trigger(EVT_MOVE);} return; } } /* Optionally override the default trigger() method * Control how your machine processes triggers */ Atm_AccelStepper& Atm_AccelStepper::trigger( int event ) { Machine::trigger( event ); return *this; } /* Optionally override the default state() method * Control what the machine returns when another process requests its state */ int Atm_AccelStepper::state( void ) { return Machine::state(); } /* Nothing customizable below this line ************************************************************************************************ */ /* Still I'll customize a little just here */ void Atm_AccelStepper::stepper_update(void) { switch (runMode) { case 0: //positional modae stepper->run(); break; case 1: // speed mode stepper->runSpeed(); break; } long int tempStep = stepper->currentPosition(); if (tempStep != _currentStep){ _currentStep = tempStep; push(connectors, ON_CHANGEPOSITION, 0, _currentStep, stepper->speed()); } } Atm_AccelStepper& Atm_AccelStepper::move( long int stepRel) { _targetStep = _currentStep + stepRel; runMode = 0; //Serial.println(_targetStep); stepper->move(_targetStep); enable(); trigger( EVT_MOVE ); return *this; } Atm_AccelStepper& Atm_AccelStepper::moveTo( long int stepAbs) { _targetStep = stepAbs; runMode = 0; stepper->moveTo(_targetStep); enable(); trigger( EVT_MOVE ); return *this; } Atm_AccelStepper& Atm_AccelStepper::rotate( long int speed) { runMode = 1; stepper->setSpeed(speed); enable(); trigger( EVT_MOVE ); return *this; } Atm_AccelStepper& Atm_AccelStepper::setEnablePin( int enablePin ){ _enablePin = enablePin ; pinMode(_enablePin, OUTPUT); return *this; } Atm_AccelStepper& Atm_AccelStepper::enableReversed( bool reverse ){ _enableReversed = reverse ; return *this; } Atm_AccelStepper& Atm_AccelStepper::limitLow_set(int mode, int pin, int reversed){ _limitLow_Mode = mode ; _limitLow_Pin = pin ; _limitLow_Reversed = reversed ; if (_limitLow_Mode==1) {pinMode(_limitLow_Pin, INPUT_PULLUP);} if (_limitLow_Mode==2) {pinMode(_limitLow_Pin, INPUT);} return *this; } Atm_AccelStepper& Atm_AccelStepper::limitLow_isHard(bool hardlimit){ _limitLow_Hard = hardlimit; } Atm_AccelStepper& Atm_AccelStepper::limitLow_setThresholds (int threshold_low, int threshold_high){ _limitLow_Thresholds[0] = threshold_low ; _limitLow_Thresholds[1] = threshold_high ; return *this; } Atm_AccelStepper& Atm_AccelStepper::limitHigh_set(int mode, int pin, int reversed){ _limitHigh_Mode = mode ; _limitHigh_Pin = pin ; _limitHigh_Reversed = reversed ; if (_limitHigh_Mode==1) {pinMode(_limitHigh_Pin, INPUT_PULLUP);} if (_limitHigh_Mode==2) {pinMode(_limitHigh_Pin, INPUT);} return *this; } Atm_AccelStepper& Atm_AccelStepper::limitHigh_isHard(bool hardlimit){ _limitHigh_Hard = hardlimit; } Atm_AccelStepper& Atm_AccelStepper::limitHigh_setThresholds (int threshold_low, int threshold_high){ _limitHigh_Thresholds[0] = threshold_low ; _limitHigh_Thresholds[1] = threshold_high ; return *this; } /* Public event methods * */ Atm_AccelStepper& Atm_AccelStepper::disable() { trigger( EVT_DISABLE ); return *this; } Atm_AccelStepper& Atm_AccelStepper::enable() { trigger( EVT_ENABLE ); return *this; } // Atm_AccelStepper& Atm_AccelStepper::move() { // trigger( EVT_MOVE ); // return *this; // } Atm_AccelStepper& Atm_AccelStepper::stop() { trigger( EVT_STOP ); return *this; } Atm_AccelStepper& Atm_AccelStepper::emergency_stop() { trigger( EVT_EMERGENCY_STOP ); return *this; } Atm_AccelStepper& Atm_AccelStepper::on_limit_low() { trigger( EVT_ON_LIMIT_LOW ); return *this; } Atm_AccelStepper& Atm_AccelStepper::on_limit_high() { trigger( EVT_ON_LIMIT_HIGH ); return *this; } Atm_AccelStepper& Atm_AccelStepper::on_target() { trigger( EVT_ON_TARGET ); return *this; } /* * onChangeposition() push connector variants ( slots 1, autostore 0, broadcast 0 ) */ Atm_AccelStepper& Atm_AccelStepper::onChangeposition( Machine& machine, int event ) { onPush( connectors, ON_CHANGEPOSITION, 0, 1, 1, machine, event ); return *this; } Atm_AccelStepper& Atm_AccelStepper::onChangeposition( atm_cb_push_t callback, int idx ) { onPush( connectors, ON_CHANGEPOSITION, 0, 1, 1, callback, idx ); return *this; } /* * onChangestate() push connector variants ( slots 1, autostore 0, broadcast 0 ) */ Atm_AccelStepper& Atm_AccelStepper::onChangestate( Machine& machine, int event ) { onPush( connectors, ON_CHANGESTATE, 0, 1, 1, machine, event ); return *this; } Atm_AccelStepper& Atm_AccelStepper::onChangestate( atm_cb_push_t callback, int idx ) { onPush( connectors, ON_CHANGESTATE, 0, 1, 1, callback, idx ); return *this; } /* * onOnlimithigh() push connector variants ( slots 1, autostore 0, broadcast 0 ) */ Atm_AccelStepper& Atm_AccelStepper::onOnlimithigh( Machine& machine, int event ) { onPush( connectors, ON_ONLIMITHIGH, 0, 1, 1, machine, event ); return *this; } Atm_AccelStepper& Atm_AccelStepper::onOnlimithigh( atm_cb_push_t callback, int idx ) { onPush( connectors, ON_ONLIMITHIGH, 0, 1, 1, callback, idx ); return *this; } /* * onOnlimitlow() push connector variants ( slots 1, autostore 0, broadcast 0 ) */ Atm_AccelStepper& Atm_AccelStepper::onOnlimitlow( Machine& machine, int event ) { onPush( connectors, ON_ONLIMITLOW, 0, 1, 1, machine, event ); return *this; } Atm_AccelStepper& Atm_AccelStepper::onOnlimitlow( atm_cb_push_t callback, int idx ) { onPush( connectors, ON_ONLIMITLOW, 0, 1, 1, callback, idx ); return *this; } /* * onOntarget() push connector variants ( slots 1, autostore 0, broadcast 0 ) */ Atm_AccelStepper& Atm_AccelStepper::onOntarget( Machine& machine, int event ) { onPush( connectors, ON_ONTARGET, 0, 1, 1, machine, event ); return *this; } Atm_AccelStepper& Atm_AccelStepper::onOntarget( atm_cb_push_t callback, int idx ) { onPush( connectors, ON_ONTARGET, 0, 1, 1, callback, idx ); return *this; } /* * onStop() push connector variants ( slots 1, autostore 0, broadcast 0 ) */ Atm_AccelStepper& Atm_AccelStepper::onStop( Machine& machine, int event ) { onPush( connectors, ON_STOP, 0, 1, 1, machine, event ); return *this; } Atm_AccelStepper& Atm_AccelStepper::onStop( atm_cb_push_t callback, int idx ) { onPush( connectors, ON_STOP, 0, 1, 1, callback, idx ); return *this; } Atm_AccelStepper& Atm_AccelStepper::onOnhominglow( Machine& machine, int event ) { onPush( connectors, ON_ONTARGET, 0, 1, 1, machine, event ); return *this; } Atm_AccelStepper& Atm_AccelStepper::onOnhominglow( atm_cb_push_t callback, int idx ) { onPush( connectors, ON_ONTARGET, 0, 1, 1, callback, idx ); return *this; } Atm_AccelStepper& Atm_AccelStepper::onOnhominghigh( Machine& machine, int event ) { onPush( connectors, ON_ONTARGET, 0, 1, 1, machine, event ); return *this; } Atm_AccelStepper& Atm_AccelStepper::onOnhominghigh( atm_cb_push_t callback, int idx ) { onPush( connectors, ON_ONTARGET, 0, 1, 1, callback, idx ); return *this; } /* State trace method * Sets the symbol table and the default logging method for serial monitoring */ Atm_AccelStepper& Atm_AccelStepper::trace( Stream & stream ) { Machine::setTrace( &stream, atm_serial_debug::trace, "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" ); return *this; }