Hi,
I'm currently working on an implementation using one stepper motor and two limit switches (separate inputs) on an ESP-32-CAM-module. In the process I noticed that one of my limit switches wasn't working correctly. After checking my own implementation multiple times, I examined the processMovement() function and I think I found a small mistake in the following section (Line 1144):
|
this->limitSwitchCheckPeformed = true; |
|
|
|
//a limit switch is active, so movement is only allowed in one direction (away from the switch) |
|
if (this->activeLimitSwitch == this->LIMIT_SWITCH_BEGIN) |
|
{ |
|
this->disallowedDirection = this->directionTowardsHome; |
|
} |
|
else if (this->activeLimitSwitch == this->LIMIT_SWITCH_END) |
|
{ |
|
this->disallowedDirection = this->directionTowardsHome * -1; |
|
} |
|
else if (this->activeLimitSwitch == this->LIMIT_SWITCH_COMBINED_BEGIN_AND_END) |
|
{ |
|
//limit switches are paired together, so we need to try to figure out by checking which one it is, by using the last used step direction |
|
if (distanceToTarget_Signed > 0) |
|
{ |
|
this->lastStepDirectionBeforeLimitSwitchTrigger = 1; |
|
this->disallowedDirection = 1; |
|
} |
|
else if (distanceToTarget_Signed < 0) |
|
{ |
|
this->lastStepDirectionBeforeLimitSwitchTrigger = -1; |
|
this->disallowedDirection = -1; |
|
} |
|
} |
When the limit switch ist triggered, I'm calling: myStepper.setLimitSwitchActive(-1);
|
void ESP_FlexyStepper::setLimitSwitchActive(byte limitSwitchType) |
|
{ |
|
if (limitSwitchType == LIMIT_SWITCH_BEGIN || limitSwitchType == LIMIT_SWITCH_END || limitSwitchType == LIMIT_SWITCH_COMBINED_BEGIN_AND_END) |
|
{ |
|
this->activeLimitSwitch = limitSwitchType; |
|
this->limitSwitchCheckPeformed = false; //set flag for newly set limit switch trigger |
|
if (this->_limitTriggeredCallback) |
|
{ |
|
this->_limitTriggeredCallback(); //TODO: this function is called from within a ISR in ESPStepperMotorServer thus we should try to delay calling of the callback to the backound task / process Steps function |
|
} |
|
} |
|
} |
Corresponding to the definition:
|
static const byte LIMIT_SWITCH_BEGIN = -1; |
In line 217 the passed byte value is saved in the variable "this->activeLimitSwitch" of type signed char.
|
signed char activeLimitSwitch; |
I'm not sure, if the following explanation is right, so please correct me, if I'm wrong.
byte can hold numbers between 0 and 255 whereas signed char can hold numbers between -128 and 127.
The passed value of byte = -1 would ussually overflow to a value of 255, but signed char can save it as a value of -1 (see example).
` byte a = -1;
Serial.println(a); //result: 255
signed char b =a;
Serial.println(b); //result: -1
bool c = (a == b);
Serial.println(c); //result: 0
bool d = ((byte)a ==b);
Serial.println(d); //result: 1`
This leads me to the issue in Line 1144 :
|
if (this->activeLimitSwitch == this->LIMIT_SWITCH_BEGIN) |
In the comparison this->activeLimitSwitch has a value of -1 and this->LIMIT_SWITCH_BEGIN has a value of 255. Therefore the condition cannot become true, leading to the limit switch not preventing movement in a certain direction. This behaviour is not noticable in the examples, since the limit switches are connected in series and use the condition in line 1152.
if ((byte)this->activeLimitSwitch == this->LIMIT_SWITCH_BEGIN)
Casting this->activeLimitSwitch to byte in the comparison seems to fix the issues in my case.
Maybe someone could test this potential fix and see, if it works without causing any problems.