Smoothieware / Smoothie2-old

(Deprecated attempt at) A Smoothie firmware port to the Smoothieboard v2 boards.
GNU General Public License v3.0
34 stars 22 forks source link

Endstops are not working #33

Open DouglasPearless opened 8 years ago

DouglasPearless commented 8 years ago

This is to document the issue and to cover off its resolution.

Issue: The endstops are not triggered during G28 Home.

Scenario: Using a FirePick Rotary Delta and the latest Smoothie2 code base, SilentStepStick at 256 microsteps and 400 step stepper motor.

Investigation: (1) Using GDB and Segger's JLink I have determined that the loop in 'wait_for_homed' method gets executed only once despite having a endless loop that only exits when 'running' becomes false. It never gets back to the 'while' statement to go repeatedly until it detects the endstop(s) are triggered. Sometimes it only gets as far as the 'THEKERNEL->call_event(ON_IDLE);' statement and never returns to the 'wait_for_homed' code at all. (2) I am wondering if Smoothie is not able to generate the step rate of some 102400 pulses per revolution for the configuration I have, and therefore does not have enough capacity to run all the other 'tasks' as the interrupt rate could be very rather high for the StepTicker. (3) Options: (a) Substantially reduce the resolution of the StepperMotor to (say) 16 microsteps to see if it now works; if this is the case the consider the following: (i) Migrate the endstops code to use interrupts on the endstop pins rather than polling them, this would include the debounce feature; I have done this for other real-time motor control systems as I have found polling to be too problematic at high work loads. I Note that the MBED interrupt feature for PIN may be too heavy and I may need to write my own ISR to keep it as fast as possible. (ii) Consider migrating the Step generation and enstops code to the M0 processor, but note that it does not appear to have a SysTick timer on that core. (iii) Consider moving the endstop code into the StepTicker code so that each time a stepper motor is sent a pulse, the endstop is checked (either the pin itself polled, or a flag set by an interrupt from the pin) (b) Implement Segger's SystemView code analyser to obtain actual metrics for time spent in interrupts and how often they are occurring (I am part of the way through this but I cannot get the SystemView application to connect to the Smoothie2 target, need too resolve this).

Thoughts?

Cheers Douglas

arthurwolf commented 8 years ago

You can just try homing much slower to see if it works.

On Thu, Oct 13, 2016 at 10:30 PM, Douglas Pearless <notifications@github.com

wrote:

This is to document the issue and to cover off its resolution.

Issue: The endstops are not triggered during G28 Home (Using a FirePick Rotary Delta).

Scenario: Latest Smoothie2 code base, SilentStepStick at 256 microsteps and 400 step stepper motor.

Investigation: (1) Using GDB and Segger's JLink I have determined that the loop in 'wait_for_homed' method gets executed only once despite having a endless loop that only exits when 'running' becomes false. It never gets back to the 'while' statement to go repeatedly until it detects the endstop(s) are triggered. Sometimes it only gets as far as the 'THEKERNEL->call_event(ON_IDLE);' statement and never returns to the 'wait_for_homed' code at all. (2) I am wondering if Smoothie is not able to generate the step rate of some 102400 pulses per revolution for the configuration I have, and therefore does not have enough capacity to run all the other 'tasks' as the interrupt rate could be very rather high for the StepTicker. (3) Options: (a) Substantially reduce the resolution of the StepperMotor to (say) 16 microsteps to see if it now works; if this is the case the consider the following: (i) Migrate the endstops code to use interrupts on the endstop pins rather than polling them, this would include the debounce feature; I have done this for other real-time motor control systems as I have found polling to be too problematic at high work loads. I Note that the MBED interrupt feature for PIN may be too heavy and I may need to write my own ISR to keep it as fast as possible. (ii) Consider migrating the Step generation and enstops code to the M0 processor, but note that it does not appear to have a SysTick timer on that core. (iii) Consider moving the endstop code into the StepTicker code so that each time a stepper motor is sent a pulse, the endstop is checked (either the pin itself polled, or a flag set by an interrupt from the pin) (b) Implement Segger's SystemView code analyser to obtain actual metrics for time spent in interrupts and how often they are occurring (I am part of the way through this but I cannot get the SystemView application to connect to the Smoothie2 target, need too resolve this).

Thoughts?

Cheers Douglas

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/Smoothieware/Smoothie2/issues/33, or mute the thread https://github.com/notifications/unsubscribe-auth/AAGpFXTN5Lv6EV8Wvh2UyMx-PYP-v1ITks5qzpTKgaJpZM4KWVTF .

Courage et bonne humeur.

wolfmanjm commented 8 years ago

Endstops have completely changed in Smoothie V1, and change here would diverge significantly from smoothie1... which may not be a bad thing. Smoothiev1 does not use interrupts as for some reason the endstops are not assigned to interrupt capable pins. Not sure about Smoothiev2. Ideally the endstops should be on interrupt pins, however debouncing interrupt pins is very hard.

DouglasPearless commented 8 years ago

Yep, tonight's task is slower homing :-)

On my Bambino210E I believe that the pins I am using are interrupt capable, pretty easy to move to other pins as required. I agree debouncing in interrupts can be tricky to get right!

I cannot comment on the Smoothie2 hardware as I have not seen a circuit diagram :-)

DouglasPearless commented 8 years ago

I have slowed it right down and it still does not stop on the endstop trigger.

I have however started integrating Seggers SystemView into my fork :-) First image shows Smoothie2 booted and awaiting a command: screenshot from 2016-10-14 17-08-25 The second image shows Smoothie2 executing a G28 command (note I have reduced the steps to 338 in the config file): screenshot from 2016-10-14 17-10-10 Notes: The step_tick() runs for 23.5 Us (4 808 cycles) The unstep_tick() runs for 16.3 Us (3 333 cycles) The acceleration_tick() runs for 48.2 Us (9 8423 cycles) I need to further integrate SystemView into Smoothie, particularly the endstop module to see what is happening and what the timings are looking like.

arthurwolf commented 8 years ago

Wow that is a nice view of what is going on, I expect this sort of stuff will help a lot with future development.

On Fri, Oct 14, 2016 at 6:16 AM, Douglas Pearless notifications@github.com wrote:

I have slowed it right down and it still does not stop on tend stop trigger.

I have however started integrating Seggers SystemView into my fork :-) First image shows Smoothie2 booted and awaiting a command: [image: screenshot from 2016-10-14 17-08-25] https://cloud.githubusercontent.com/assets/3744251/19375521/84527512-9231-11e6-9b64-9019cbe8cf5d.png The second image shows Smoothie2 executing a G28 command (note I have reduced the steps to 338 in the config file): [image: screenshot from 2016-10-14 17-10-10] https://cloud.githubusercontent.com/assets/3744251/19375525/88c08d96-9231-11e6-9db8-94d4f7fa2b54.png I need to further integrate SystemView into Smoothie, particularly the endstop module to see what is happening and what the timings are looking like.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/Smoothieware/Smoothie2/issues/33#issuecomment-253705752, or mute the thread https://github.com/notifications/unsubscribe-auth/AAGpFVlQ5Ab_21keMn6mCPibDsOEWGDXks5qzwIagaJpZM4KWVTF .

Courage et bonne humeur.

DouglasPearless commented 8 years ago

The tool will enable some empirical measurement of performance and when I have more of the Segger SystemView implemented, then we can really get quality trace data and see what .

Then there is also extending this with Impulse from http://toem.de per this post [https://mcuoneclipse.com/2016/07/31/impulse-segger-systemview-in-eclipse/#more-18459] .

We will then have a (hopefully) robust platform that we can get plenty of metric to improve and expand Smoothie2, and I can hopefully figure out why endstops are not being triggered!

DouglasPearless commented 8 years ago

Update: It appears to be a timing issue.

Findings:

The RITIMER_IRQHandler works just fine with these added.

Below are some of the changes to change the code to reflect the new Stepper motor code. Note the change: //STEPPER[c]->move(0, 0); //REMOVED STEPPER[c]->force_finish_move(); //ADDED TODO test

Is this is the correct way to now stop a stepper motor?

bool Endstops::wait_for_homed(char axes_to_move)
{
    bool running = true;
    unsigned int debounce[3] = {0, 0, 0};
    while (running) {
        SEGGER_SYSVIEW_Print("Endstop::wait_for_homed\n");
        running = false;
        THEKERNEL->call_event(ON_IDLE);

        // check if on_halt (e.g. kil
        if(THEKERNEL->is_halted()) return false;

        for ( int c = X_AXIS; c <= Z_AXIS; c++ ) {
            if ( ( axes_to_move >> c ) & 1 ) {
                //SEGGER_SYSVIEW_PrintfHost("  debounce[%u] = %u\n",c,debounce[c]);
                if ( this->pins[c + (this->home_direction[c] ? 0 : 3)].get() ) {
                    //SEGGER_SYSVIEW_PrintfHost("A debounce[%u] = %u\n",c,debounce[c]);
                    if ( debounce[c] < debounce_count ) {
                        debounce[c]++;
                        running = true;
                    } else if ( STEPPER[c]->is_moving() ) {
                        SEGGER_SYSVIEW_PrintfHost("Reached endstop for %u\n",c);
                        //STEPPER[c]->move(0, 0); //REMOVED
                        STEPPER[c]->force_finish_move(); //ADDED TODO test
                        SEGGER_SYSVIEW_PrintfHost("Axis to move a %u\n",axes_to_move);
                        axes_to_move &= ~(1 << c); // no need to check it again
                        SEGGER_SYSVIEW_PrintfHost("Axis to move %u\n",axes_to_move);
                    }
                } else {
                    // The endstop was not hit yet
                    //SEGGER_SYSVIEW_PrintfHost("C debounce[%u] = %u\n",c,debounce[c]);
                    running = true;
                    debounce[c] = 0;
                }
            }
        }
        SEGGER_SYSVIEW_PrintfHost("%u,%u,%u\n",debounce[0],debounce[1],debounce[2]);
    }
    SEGGER_SYSVIEW_Print("Endstop::wait_for_homed EXIT\n");
    return true;
}

Thoughts?

DouglasPearless commented 8 years ago

Pull request #34 did not solve my issue; this weekend I am focussing on solving this so I can test my Z-Probe (and others) port.