Closed SamuelCyr closed 3 years ago
Hi @SamuelCyr,
Thanks for reporting, it was clearly a bug :-$ Your solution whas working, but I found a more effective one: 1) Calculate the missing/unused bits according to N_AXIS:
uint8_t not used_bits = 0xff - (1 << N_AXIS) + 1;
2) Return the correct value if $5 = 1:
if (bit_istrue(settings.flags,BITFLAG_INVERT_LIMIT_PINS)) {
return(~((limit_state_max & limit_state_min) | unused_bits));
} else {
return(limit_state_max | limit_state_min);
}
I pushed the patch awhile ago with version number v1.1r.
Since I don't use the hardware limits in my real CNC milling machine (I prefer to trust software limits), thank to tell me if this patch fully solve this bug.
@++; Gauthier.
Hello @fra589 ,
I've tested the changes and everything seems to work fine for me !
thanks,
You're welcome,
I've been having some frustrating problems with NC limit switch using grbl-5x and an ArduinoMega + Ramp1.4 recently and I believe there might be a small problem with the the function "limits_get_setate()" found in "limits.c". The post is long, but was made to explain in depth my process and to make it as clear as possible.
Context Grbl parameters: $5=1 $20=0 $21=1 $22=1 $23=0
I used parameters $5=1 to make all contact NC. I've hooked up everything and I did the homing cycle succesfuly. If I use the realtime command "?", there is no limit switch triggered. However, As soon as I send a command to move a stepper, ALARM 1 is thrown and I need to reset the Arduino.
At first, I've look in various forums for similar problems and I've done all the answers mentionned:
But still, impossible to send a motor command successfully...
Problem When looking in the source code, I've noticed the following in "limits_get_state()" The problem is actually only seen if you are using "$5=1".
"limit_state_max" and "limit_state_min" are both 8 bits (uint8_t) and they are both intialized to "0" [Line 194 -195]. Also, since there is a bitwise NOT (\~) applied to "limit_state_max & limit_state_min" before returning the result [Line 220], it means that some of the most significant bits will necessarily be "0" depending on the number of axis defined (N_AXIS). For example, with 5 axis, bits 7,6 and 5 will be "0" (0b000XXXXX) and the last 5 less significant bits (X) will represent the state of the limit switch. However, since a bitwise NOT (\~) is applied before the return, these 3 bits will necessarily become "1". The real problem however appears when grbl check to see if any limit switch has been triggered which happens in "ramp_hard_limit" also in "limit.c":
As you can see in the line 258, as soon as the variable returned by "limit_get_state" is different then "0", the ALARM 1 will be thrown. However, As I mentionned earlier, the 3 most significant bits will always be "1" and therefore, the if [line 258] will always evaluate to "true". Note: the problem only arises when "$5=1" since in "$5=0" logic, the variable is initialized to "0" and only triggered limit switch will change some bits to 1. The 3 most significant bit will therefore always stay "0".
Proposed solution To solve the issue, I think we should add something like the following "for" loop before returning the value when "$5=1". This would ensure that all the most significant bits are put to "1" before applying the bitwise NOT (which would make sure that they are actually "0" when the value is returned). This is only a proposition, and there is certainly a more efficient/clean way to do this. The whole point of this thread was only to shed some light on the issue to make sure no else has to deal with the problem !