Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

troggle stepper enable on reset #150

Closed
Tsillen opened this issue Jun 16, 2022 · 17 comments
Closed

troggle stepper enable on reset #150

Tsillen opened this issue Jun 16, 2022 · 17 comments

Comments

@Tsillen
Copy link

Tsillen commented Jun 16, 2022

My use case: alarm of IHSV57 servo's are hooked up to my e-stop circuit.
In the case of a alarm, e-stop input pulls low.
In order to reset this either power cycle servo's (not ideal) or troggle drive enable .

To my suprise this drive enable/disable does not occur when you reset the board. It only occurs if you change a setting (in IO SENDER).

Ideally you would see an option somewhere to troggle enable/disable of stepper/servo's on init/reset.

@terjeio
Copy link
Contributor

terjeio commented Jun 17, 2022

A plugin can do that by hooking code into hal.driver_reset and registering a function to be called on startup in the plugins init function. Here is an example of the use of those methods.

Toggling the enable signal can be done by calling hal.stepper.enable().

@Tsillen
Copy link
Author

Tsillen commented Jun 17, 2022

So if i understand correctly
`static void on_driver_reset (void)
{

hal.stepper.enable(0xFF);
1 sec delay
hal.stepper.enable(0x00);
driver_reset();

if(power_state != Power_On)
    check_power_restored();

}
`

@terjeio
Copy link
Contributor

terjeio commented Jun 17, 2022

You have to cast the argument to hal.stepper.enable like this:
hal.stepper.enable((axes_signals_t){AXES_BITMASK});
and
hal.stepper.enable(s(axes_signals_t){0});

1 sec delay is hal.delay_ms(1000, NULL);

@Tsillen
Copy link
Author

Tsillen commented Jun 17, 2022

awesome, i'll have a try.

@Tsillen
Copy link
Author

Tsillen commented Jun 17, 2022

ssr.c (probably don't need half of these includes)

#include "driver.h"

#if SERVO_RESET_ENABLE // Declared in my_machine.h - you must add in the section with the included plugins
#include "grbl/protocol.h"
#include "grbl/hal.h"
#include "grbl/state_machine.h"
#include "grbl/system.h"
#include "grbl/alarms.h"
#include "grbl/nuts_bolts.h"         // For delay_sec non-blocking timer function


// Declarations
static driver_reset_ptr driver_reset;
// DRIVER RESET
static void driverReset (void)
{
    hal.stepper.enable((axes_signals_t){0}); //disable drives
    hal.delay_ms(1000, NULL); // wait a second
    hal.stepper.enable((axes_signals_t){1}); //enable drives
    driver_reset();
}

// INIT FUNCTION - CALLED FROM plugins_init.h()
// void my_plugin_init() {
void ssr_init() 
{

    driver_reset = hal.driver_reset;                    // Subscribe to driver reset event
    hal.driver_reset = driverReset;

    
 }
#endif

plugins_init.h add:

#if SERVO_RESET_ENABLE
    extern void ssr_init (void);
    ssr_init();
#endif

my_machine.h add:
#define SERVO_RESET_ENABLE 1

I was kinda suprised that it found my ssr.c as nowhere i let it know it is in the /ssr/ folder but it seems to compile.
Now lets see if it works.

@Tsillen
Copy link
Author

Tsillen commented Jun 17, 2022

yup this works.

When my servo goes in alarm -> pulls e-stop -> pressing reset in iosender now pulls drive enable and clears servo alarm.

@Tsillen
Copy link
Author

Tsillen commented Jun 17, 2022

Well does something weird. if servo alarm goes off -> pulls e-stop -> i see that there is no alarm light on my servo. When i check the status (over RS232 directly into servo) it shows that drive_enable is low. It seems that it auto triggers and reset which is not the intended goal.

Goal is to reset it when i press the big reset button:
image

Seems like hal.driver_reset is auto called when e-stop is active.

@terjeio
Copy link
Contributor

terjeio commented Jun 17, 2022

Seems like hal.driver_reset is auto called when e-stop is active.

Correct, you'll have to check if e-stop is active and delay action until it is cleared?

if (!hal.control.get_state().e_stop)
    toggle enable

@Tsillen
Copy link
Author

Tsillen commented Jun 17, 2022

during e-stop drivers can stay enabled. I should toggle enable after this code is cleared.

@Tsillen
Copy link
Author

Tsillen commented Jun 17, 2022

#include "driver.h"

#if SERVO_RESET_ENABLE // Declared in my_machine.h - you must add in the section with the included plugins
#include "grbl/protocol.h"
#include "grbl/hal.h"
#include "grbl/state_machine.h"
#include "grbl/system.h"
#include "grbl/alarms.h"
#include "grbl/nuts_bolts.h"         // For delay_sec non-blocking timer function


// Declarations
static driver_reset_ptr driver_reset;
uint8_t holdbit = 0; //holdbit for servo enable toggle
// DRIVER RESET
static void driverReset (void)
{
    if (holdbit == 1)
    {
        hal.stepper.enable((axes_signals_t){0}); //disable drives
        hal.delay_ms(1000, NULL); // wait a second 
        hal.stepper.enable((axes_signals_t){1}); //enable drives
        holdbit = 0; //reset holdbit
    }
    driver_reset();
}

// INIT FUNCTION - CALLED FROM plugins_init.h()
// void my_plugin_init() {
void ssr_init() 
{

    driver_reset = hal.driver_reset;                    // Subscribe to driver reset event
    hal.driver_reset = driverReset;
 }
#endif


if (hal.control.get_state().e_stop) //estop event
{
    holdbit = 1; //set holdbit
}

@Tsillen
Copy link
Author

Tsillen commented Jun 17, 2022

i think something like this should work. need to check where i can put the estop event code

@terjeio
Copy link
Contributor

terjeio commented Jun 17, 2022

need to check where i can put the estop event code

It is not an event callback, the hal.control.get_state().e_stop call reads the status directly from the input.

@Tsillen
Copy link
Author

Tsillen commented Jun 17, 2022

image
Iosender does not allow me to reset while e-stop is active (alarm from servos)

I tried this:
but i can't send reset in current state so it is kinda stuck. Not sure how do to this behavoir other than adding extra buttons etc.

#include "driver.h"

#if SERVO_RESET_ENABLE // Declared in my_machine.h - you must add in the section with the included plugins
#include "grbl/protocol.h"
#include "grbl/hal.h"
#include "grbl/state_machine.h"
#include "grbl/system.h"
#include "grbl/alarms.h"
#include "grbl/nuts_bolts.h"         // For delay_sec non-blocking timer function


// Declarations
static driver_reset_ptr driver_reset;
uint8_t holdbit = 0; //holdbit for servo enable toggle

// DRIVER RESET
static void driverReset (void)
{
    if (holdbit == 1) //should i check if e-stop is still high?
    {
        hal.stepper.enable((axes_signals_t){0}); //disable drives
        hal.delay_ms(1000, NULL); // wait a second 
        hal.stepper.enable((axes_signals_t){1}); //enable drives
        holdbit = 0; //reset holdbit
    } 
    else if (hal.control.get_state().e_stop) //if e-stop pin is high
    {
        holdbit = 1; //set holdbit
    }
    
    driver_reset();
}

// INIT FUNCTION - CALLED FROM plugins_init.h()
// void my_plugin_init() {
void ssr_init() 
{

    driver_reset = hal.driver_reset;                    // Subscribe to driver reset event
    hal.driver_reset = driverReset;
}
#endif

@terjeio
Copy link
Contributor

terjeio commented Jun 17, 2022

If you want to trap the e-stop event you can attach your code to hal.control.interrupt_callback in the same manner as you do for hal.driver_reset. Here is the core handler for the callback:

core/system.c

Lines 92 to 139 in 45b0e10

// Pin change interrupt for pin-out commands, i.e. cycle start, feed hold, and reset. Sets
// only the realtime command execute variable to have the main program execute these when
// its ready. This works exactly like the character-based realtime commands when picked off
// directly from the incoming data stream.
ISR_CODE void ISR_FUNC(control_interrupt_handler)(control_signals_t signals)
{
if(signals.deasserted)
return; // for now...
if (signals.value) {
sys.last_event.control.value = signals.value;
if ((signals.reset || signals.e_stop || signals.motor_fault) && state_get() != STATE_ESTOP)
mc_reset();
else {
#ifndef NO_SAFETY_DOOR_SUPPORT
if (signals.safety_door_ajar && hal.signals_cap.safety_door_ajar) {
if(settings.safety_door.flags.ignore_when_idle) {
// Only stop the spindle (laser off) when idle or jogging,
// this to allow positioning the controlled point (spindle) when door is open.
// NOTE: at least for lasers there should be an external interlock blocking laser power.
if(state_get() != STATE_IDLE && state_get() != STATE_JOG)
system_set_exec_state_flag(EXEC_SAFETY_DOOR);
if(sys.mode == Mode_Laser) // Turn off spindle immediately (laser) when in laser mode
hal.spindle.set_state((spindle_state_t){0}, 0.0f);
} else
system_set_exec_state_flag(EXEC_SAFETY_DOOR);
}
#endif
if (signals.probe_triggered) {
if(sys.probing_state == Probing_Off && (state_get() & (STATE_CYCLE|STATE_JOG))) {
system_set_exec_state_flag(EXEC_STOP);
sys.alarm_pending = Alarm_ProbeProtect;
} else
hal.probe.configure(false, false);
} else if (signals.probe_disconnected) {
if(sys.probing_state == Probing_Active && state_get() == STATE_CYCLE) {
system_set_exec_state_flag(EXEC_FEED_HOLD);
sys.alarm_pending = Alarm_ProbeProtect;
}
} else if (signals.feed_hold)
system_set_exec_state_flag(EXEC_FEED_HOLD);
else if (signals.cycle_start)
system_set_exec_state_flag(EXEC_CYCLE_START);
}
}
}

@terjeio
Copy link
Contributor

terjeio commented Jun 17, 2022

Iosender does not allow me to reset while e-stop is active (alarm from servos)

grblHAL blocks this - the servo alarm should trigger the motor fault signal instead? If the driver you are using has aux inputs you could claim one and use that to trigger the signal.

@Tsillen
Copy link
Author

Tsillen commented Jun 17, 2022

Hi i'm using the grblhal2k:
https://github.com/Expatria-Technologies/grblhal_2000_PrintNC

I believe it has aux inputs. Will investigate further

@Tsillen
Copy link
Author

Tsillen commented Jun 22, 2022

Using this code for now, works well enough.
#150 (comment)

At some point i might use the motor fault input.

@terjeio terjeio closed this as completed Apr 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants