grblHAL / iMXRT1062

grblHAL driver for NXP iMXRT1062 (Teensy 4.x)
Other
51 stars 39 forks source link

How to add new pins and use them. #66

Open ToRoCu opened 1 year ago

ToRoCu commented 1 year ago

Hello, I would like to use pins 48-50 (Teensy 4.1 from PSRAM) in the programme, how do I set this up?

terjeio commented 1 year ago

For digital I/O add them as aux ports in your map and use them via M62-M66.

ToRoCu commented 1 year ago

Sry, I should have described better what I want to do. I would like to use the pins in a plugin. I have already spent a few hours with the code and am still unclear about the correct use of the functions/classes such as "claiming an auxiliary pin for exclusive use". Is "Y2_LIMIT_PIN" already used somewhere in the program or is it a placeholder?... If so, for what?

There are still some comments missing, I will add some when I am done and make a pull request for it.

terjeio commented 1 year ago

I would like to use the pins in a plugin.

You will have to define them as aux in and/or aux out. By default such pins are made available for the M62-M66 commands but can be claimed by plugins for exclusive use meaning the can no longer be set or read by those M commands. Use the $pins command to get a list of pins and the function they are assigned to.

Is "Y2_LIMIT_PIN" already used somewhere in the program or is it a placeholder?... If so, for what?

It is and is the limit (home switch) pin for the second Y2 motor (for auto-squared Y axis).

ToRoCu commented 1 year ago

Hello terjeio, I am amazed at how quickly your answers come. First of all, thank you for your valuable work on this project.

After many hours of trying to understand the code and get what i want to do...I need help or a thought to move forward. what i want to do is "actually" simple...i need two outputs (HIGH) on two AUX ports when one of the two Y axes (double motor) is on limit switch, as long as a step signal is generated.

Y_LIMIT_PIN= AUXOUTPUT6_PIN<-- HIGH when Y_LIMIT_PIN is triggered and a step signal is generated. Y2_LIMIT_PIN = AUXOUTPUT7_PIN<-- HIGH when Y2_LIMIT_PIN is triggered and a step signal is generated.

I have added "#elif Y_DOUBLED == 6" to motor.pins.h to make Y2_LIMIT_PIN not dependent on the other axes.

I hope you can help me, even though I know it's a big ask.

Thank you

terjeio commented 1 year ago

I am not sure I understand what you want to achieve but I am pretty sure you are complicating it by modifying _motorpins.h. Plugins can do a lot of fancy stuff by intercepting HAL calls and/or subscribing to core events - and I wonder if this is the way forward for you. First, when do you need the aux ports to be set high? At all times or just when homing? If during homing you can intercept the HAL call that reads the limit switches since they are continuously polled. If at all times the there are other options. A more detailed description of what you want will help me provide better guidance.

ToRoCu commented 1 year ago

The AUX ports must be switched during the home cycle (HIGH), otherwise it is not necessary. However, I wonder how I can manage this without manipulating motor_pins.h so that I can use the second Y2_limit input without having to sacrifice the A-axis. If the limit switch (Y_LIMIT_PIN) is triggered, then (AUXOUTPUT6_PIN) should be switched to (HIGH). The AUX port (AUXOUTPUT6_PIN) should only output a (HIGH) signal as long as a step signal is generated on the Y_axis. The same then applies to "Y2_LIMIT_PIN, AUXOUTPUT7_PIN".

terjeio commented 1 year ago

Check this piece of code, it intercepts the HAL get limit switch status and modifies it when homing. Step signals are generated as long as the homing sequence is active, in onHomingRateSet() the axes parameter holds which axis/axes. It is also possible to intercept the HAL call that ouput pulses if you want to check at such a low level.

If you rename the init function to my_plugin_init() the it will be automatically be called on startup (since it is defined as a "weak" function in the core),

ToRoCu commented 1 year ago

How do I get access to the Y2_LIMIT_PIN?

terjeio commented 1 year ago

The status is available in the limit_signals_t struct, min2.y - available either by calling hal.limits.get_state directly or by intercepting the call as done in the code linked above. During homing the limitsGetState() call in the linked code will be called at a high frequency so you do not have to add it to the real time loop callback. Interrupts are disabled for limit pins involved in the homing sequence so it is not possible to get hold of the status via intercepting the limits interrupt callback. You can of course use MCU specific calls or register access to get hold of the status but that is not needed nor portable.

ToRoCu commented 1 year ago

some things are working now, i'm starting to see the big picture behind the code. There are still 2 things:

  1. how can I stop the homing "success/OK" until both Y endstops are activated?
  2. it takes too long from Y_LIMIT_PIN is pressed until a "HIGH" is output at the output port.
terjeio commented 1 year ago

I still do not understand clearly what you want to achieve...

  1. By writing your own homing routine? If a switch fails to activate the controller will raise an alarm when the distance traveled is more than the configured distance. Or for an auto squared axis when the second motor drives the the axis too far out of square. Is this what you want to block?
  2. What is too long? a few microseconds? milliseconds? ... Post your code, either in a repo or in a comment so I can take a look.

hal.stepper.disable_motors could be another call you need to intercept?

ToRoCu commented 1 year ago

I would like to expand the Autosquaring so that I don't have to waste an extra axle like A. Currently, no matter which sensor triggers (Limit_Y or Limit_Y2) the homing cycle is completed with Success. I want to prevent this and want the axis to continue driving until the second sensor has also triggered. When both sensors have triggered, Homing is DONE for Y axis.

Too long is over 500 milliseconds, when a sensor triggers, the output must go HIGH as quickly as possible.

static limit_signals_t limitsGetState (void)
{
    limit_signals_t state;
    axes_signals_t dir_outbits;

    state = limits_get_state();
    dir_outbits.y;

    bool M_lockY1 = state.min.y;
    bool M_lockY2 = state.min2.y;

  if(homing.y) {
    hal.port.digital_out(port_lockY1, M_lockY1);
    hal.port.digital_out(port_lockY2, M_lockY2);
  }else{
    hal.port.digital_out(port_lockY1, false);
    hal.port.digital_out(port_lockY2, false);    
  }
  return state;
}

This function is running in My_Plugin.

terjeio commented 1 year ago

Too long is over 500 milliseconds, when a sensor triggers, the output must go HIGH as quickly as possible.

If outside of homing the delay will be up to the real-time request interval (from the sender). Please post the complete plugin code, the snippet above does not provide any context.

terjeio commented 1 year ago

You want to do auto squaring with two motors connected to a single stepper driver? Or two stepper drivers/motors connected to the same step/dir output from the controller? The output signals are for switching motors (or rather drivers) in/out? I guess this doable by defining the step/dir pins for M3 equal to the Y axis, trapping hal.stepper.disable_motors is then the correct way to control the outputs as this called when switching between motors during homing for an auto-squared axis.

ToRoCu commented 1 year ago

I guess this doable by defining the step/dir pins for M3 equal to the Y axis, trapping hal.stepper.disable_motors is then the correct way to control the outputs as this called when switching between motors during homing for an auto-squared axis.

I think you are making what I am trying to achieve more complicated than it is :D. 2 drivers on one STEP/DIR output. If I do the AutoSquaring by defining M3, I have to waste a whole Axis just to align the portal once. would mean I can only build a 4 axis CNC with the IMXRT1062. Currently I only have the problem that I want to wait until both Y sensors have triggered to finish the homing process.

if(Y_LIMIT_PIN && Y2_LIMIT_PIN) 
    Homing = success;
terjeio commented 1 year ago

If I do the AutoSquaring by defining M3, I have to waste a whole Axis just to align the portal once. would mean I can only build a 4 axis CNC with the IMXRT1062.

driver.c supports up to 6 axes, 2 of which can be auto-squared (1 in an 5 axes configuration), you will need a new board map to take avantage of that though. E.g. if you add M5 definitions to the board map you can have either 6 axes or 5 axes with one auto-squared. Duplicating Y-axis definitions to the highest numbered motor in use (except the limit pin) and configure the Y-axis as auto-squared might work as suggested above. E.g. for a 5 axis configuration Y2 will be M5, in a 4 axis it will be M4. ABC-axis motors are assigned from M3 upwards and second motors for auto squared axes downwards from the highest numbered needed.

Currently I only have the problem that I want to wait until both Y sensors have triggered to finish the homing process.

This is with the Y-axis not configured as auto squared then? If so you may have to write your own homing routine as homing is not just waiting for both switches to be triggered - possible since homing just got its own function pointer: grbl.home_machine. It is not possible to preempt the core homing implementation by returning early when both switches are triggered: pulloff, locate phase, pulloff, possibly square adjustment and then work envelope configuration has to be completed first. Since the core queries the driver for auto squared axes prior to calling the homing routine you could perhaps fake that a single single motor output can be used for auto squaring and still use the core homing routine by redirecting hal.stepper.get_ganged to your plugin. You would then have to route the step signal to the correct drivers via trapping hal.stepper_disable_motors.

ToRoCu commented 1 year ago

driver.c supports up to 6 axes, 2 of which can be auto-squared (1 in an 5 axes configuration), you will need a new board map to take avantage of that though. E.g. if you add M5 definitions to the board map you can have either 6 axes or 5 axes with one auto-squared. Duplicating Y-axis definitions to the highest numbered motor in use (except the limit pin) and configure the Y-axis as auto-squared might work as suggested above. E.g. for a 5 axis configuration Y2 will be M5, in a 4 axis it will be M4. ABC-axis motors are assigned from M3 upwards and second motors for auto squared axes downwards from the highest numbered needed.

I know, that is in the _motorpins.h.

The problem is that the IMXRT1062 does not have unlimited free GPIO's available, so i cannot use the common way. In my case all GPIO's are already fully defined + the GPIO's on the underside(PSRAM), which is why this option is unfortunately not possible for me.

Currently, auto squared is not configured because it then immediately uses the A axis as M3. "which is why I initially wanted to add another option to _motorpins.h".

I will test a few ways.

Thanks :)