End switches an interrupts

Hi,

great :+1:
Is it ready for testing? Devel branch?

Greetings / Zennix

Hey, sorry about the delay. Please try this branch https://github.com/Wetmelon/ODrive/tree/Endstops

You’ll need to compile from scratch and upload with an STLink, unless there’s some way for you to use DFU to pull this pull request? https://github.com/madcowswe/ODrive/pull/218

Once you flash the controller, you can configure it normally, with the addition of the following endstop commands:

odrv#.axis#.config.max_endstop.gpio_num = <1, 2, 3, 4, 5>
odrv#.axis#.config.max_endstop.enabled = <True, False>
odrv#.axis#.config.max_endstop.offset = <int>
odrv#.axis#.config.max_endstop.is_active_high = <True, False>

odrv#.axis#.config.min_endstop.gpio_num = <1, 2, 3, 4, 5>
odrv#.axis#.config.min_endstop.enabled = <True, False>
odrv#.axis#.config.min_endstop.offset = <int>
odrv#.axis#.config.min_endstop.is_active_high = <True, False>

gpio_num and enabled should be self explanatory. Make sure to disable step/dir or UART communications as necessary.

offset can be set as a number of counts. It is used as the “home switch position”. In other words, if your min_endstop is 100 counts further than what you want 0 to be, set this value to -100. This is really only currently valid for min_endstop.

is_active_high sets the polarity of the endstop. If when the switch is pressed it pulls the pin LOW (this is very common for endstop switches), you want to set this to “False”.

1 Like

Hi Wetmelon,

thanks for the branch. It compiles and the ODrive is running as expected.
My configuration is:

odrv#.axis#.config.max_endstop.gpio_num = 6
odrv#.axis#.config.max_endstop.enabled = True
odrv#.axis#.config.max_endstop.offset = -100
odrv#.axis#.config.max_endstop.is_active_high = False
_
odrv#.axis#.config.min_endstop.gpio_num = 5
odrv#.axis#.config.min_endstop.enabled = True
odrv#.axis#.config.min_endstop.offset = -100
odrv#.axis#.config.min_endstop.is_active_high = False

my switches are active low, but I have no external pullup.

Is there a command for homing the axis?
I tried to press a switch during a running position command, but nothing happend. The motor was still running.

Greetings / Zennix

Looking at the code from the PR, I believe you want to set requested_state to AXIS_STATE_HOMING to begin the process.

Please pull the newest version of the firmware, there was a bug where it wouldn’t initialize any GPIO above #5. The internal pull up / down is set automatically depending on the polarity of the endstops.

I’ve added <axis>.config.startup_homing = <True, False> as an option. If both <axis>.config.startup_closed_loop_control and <axis>.config.startup_homing are True, then ODrive will home the axis after calibration. Otherwise, you can enter homing by setting <axis>.requested_state = AXIS_STATE_HOMING

After setting up your configuration, please remember to do <odrv>.save_configuration() then power cycle the controller.

1 Like

Hi Wetmelon,

Thank you.
I pulled the last version and here is my configuration

startup_motor_calibration = True (bool)
startup_encoder_index_search = True (bool)
startup_encoder_offset_calibration = True (bool)
startup_closed_loop_control = True (bool)
startup_sensorless_control = False (bool)
startup_homing = True (bool)
enable_step_dir = False (bool)
counts_per_step = 2.0 (float)
ramp_up_time = 0.4000000059604645 (float)
ramp_up_distance = 12.566370964050293 (float)
spin_up_current = 10.0 (float)
spin_up_acceleration = 400.0 (float)
spin_up_target_vel = 400.0 (float)
min_endstop:
gpio_num = 5 (int)
enabled = True (bool)
offset = -100 (int)
is_active_high = False (bool)
max_endstop:
gpio_num = 6 (int)
enabled = True (bool)
offset = -100 (int)
is_active_high = False (bool)

I set .config.startup_homing = True and .config.startup_closed_loop_control to True. Saved it and start. It does only the full calibration sequence. Nothing more.

The command .requested_state = AXIS_STATE_HOMING ends with:

In [11]: odrv0.axis0.requested_state = AXIS_STATE_HOMING
NameError Traceback (most recent call last)
d:\tools\Anaconda3\lib\site-packages\fibre\shell.py in ()
----> 1 odrv0.axis0.requested_state =
NameError: name ‘AXIS_STATE_HOMING’ is not defined

Is there a way to see if the switches are pressed?

Greetings / Zennix

Hi Wetmelon,

I tried the switches also at Pin 3 and 4. The same result. I pressed one of the switches and checked odrv.axis0.
I thought min_ or max_endstop_state should be true.

B [25]: odrv0.axis0
Out[25]:
error = 0x0000 (int)
enable_step_dir = False (bool)
current_state = 1 (int)
requested_state = 0 (int)
loop_counter = 318529 (int)
min_endstop_state = False (bool)
max_endstop_state = False (bool)

Greetings / Zennix

Make sure you’re using the odrivetool that comes with the repository (v0.4.2.dev) rather than the one that comes from pip. That should fix the AXIS_STATE_HOMING issue. If you don’t want to do that, you can use .requested_state = 9

As for it not seeing the endstops… will investigate.

EDIT: I found a few issues… It will take me another day to clean up, but it’s definitely working (at least on GPIO 5). There’s still a bug where it immediately faults out because it goes into AXIS_STATE_CLOSED_LOOP_CONTROL while the homing switch is still pressed

Ok, the absolute newest build should work. I tested it on my bench and it seems to work correctly.

I recommend using a GPIO pin above #4 (so 5, 6, 7, or 8 on v3.5)

Hi Wetmelon,

looks good, thank you.

I tested GPIO 3, 4, 5 and 6, there are recognised.
Automatic homing is working too.
Reaching an endstop during a run is also working. It stops the motor.
manual homing is also working.

one finding:
I saw, that about every second try the homing function will not work. The motor initializes, searches home. If the min button is pressed the motor stops and will not go to it’s offset.
In [2]: odrv0.axis0.error
Out[2]: 2049

BTW: how to start the new ODrivetool in a Windows environment without installing it through pip?

Great work!!!

Greetings / Zennix

Hi,

another finding:
endstop_max gpio 8 and endstop_min gpio 7 are not working correct. Config is showing correct, pressing the max switch, the axis will show the min switch is pressed. The min switch at 7 will not be recognised.

Greetings / Zennix

Error 2049 is 0x801, which is what happens when the min endstop is pressed while in “run” state. I suspect what’s happening is that it has insufficient debouncing so it moves through the entire set of states all in one press. I may be able to fix this in software, but one quick and easy way to fix it is to put a decoupling capacitor or little RC filter on the GPIO.

You can start the new ODrivetool by manually navigating to the ODrive/tools folder and calling ipython -i ./odrivetool

What happens if you set max_endstop.enabled = False?

Hi,

OK, thank you. I will try to use a RC filter later on.

Here is the test with disabled max_endstop.

min_endstop:
gpio_num = 7 (int)
enabled = True (bool)
offset = -10000 (int)
is_active_high = False (bool)
max_endstop:
gpio_num = 8 (int)
enabled = False (bool)
offset = -100 (int)
is_active_high = False (bool)

Max_endstop switch is pressed:

In [9]: odrv0.axis0
Out[9]:
error = 0x0801 (int)
enable_step_dir = False (bool)
current_state = 1 (int)
requested_state = 0 (int)
loop_counter = 175924 (int)
min_endstop_state = True (bool)
max_endstop_state = False (bool)

Greetings / Zennix

Hello and thanks for your sharing your own experiences. Would you mind sharing the technical information below?

Switch limit type
Is your limit switch wired to an arduino board and then the arduino is connected to the odrive?If so, can you share the wiring From -To pinouts?
Would you be able to show a video how switch works?
If you are using arduino, would you mind sharing the sketch?

Thanks

Hi

@Wetmelon
I had a look to your code, but couldn’t find why the GPIO 7 and 8 isn’t working as expected.

But one idea to void Axis::set_min_endstop_enabled(bool enable) in axis.cpp
you set interrupt_mode = GPIO_MODE_IT_RISING_FALLING. For debouncing isn’t it better to set it like:

uint32_t interrupt_mode = config_.min_endstop.is_active_high ? GPIO_MODE_IT_RISING : GPIO_MODE_IT_FALLING;

@hbtousa
You can use every micro switch that fits to your application. I used: https://www.ebay.de/itm/10-Stueck-AC-125V-5A-SPDT-1NO-1NC-Glatt-Hinge-Lever-Mini-Micro-Schalter-DE/282522069641?hash=item41c7a0aa89:g:kxcAAOSwCkZZPuy7

The connetion is very easy. It’s directly connected to a GPIO on the ODrive. The other contact is connected to Ground GND.

Greetings / Zennix

Hi,

Findings:

  1. debouncing
  2. GPIO7 and 8 not recognised correct
  3. new-> axis1 didn’t find the encoder anymore.

Greetings / Zennix

I’ve updated the endstop branch again. To make the code cleaner, I’ve made each endstop an object. This means they now exist as objects within the axis context:

<odrv>.<axis>.min_endstop
<odrv>.<axis>.max_endstop

I’ve also added software debouncing, with a default value of 100ms.

<odrv>.<axis>.min_endstop.config.debounce_ms = <Float>
<odrv>.<axis>.max_endstop.config.debounce_ms = <Float>

Please try this out. I don’t think it will have fixed the GPIO issues though.

Hi,

Couldn’t test it, because I could not save the configuration.
After a save_configuration() and reboot(), the values are gone.

Greetings / Zennix

2 posts were split to a new topic: How to use github?

Yes, I am having the same result. All parameter configuration settings gone.

Thanks