grblHAL / Plugin_fans

grblHAL plugin for fan control
Other
2 stars 0 forks source link

Using Fans with other I/O ports #2

Closed MisterDiz closed 1 year ago

MisterDiz commented 2 years ago

I'm using grblHAL with the RGB LED Datron style plugin and now wish to add a wine rack style ATC. My plan is to use the fans control plugin to operate pneumatic solenoids to shove the tool rack around.

As both use the standard 4 analogue outs, I was wondering if there was a simple way to use both plugins at once? I have a Teensy 4.1 with lots of spare pins and practically nil programming skills. The plugin examples show that extra I/O and M codes would be easily achievable but I fear that its above my pay grade.

terjeio commented 2 years ago

Depending on the number of I/O ports supported by the driver you can control the remaining ports via M62-M66 commands, no plugin is needed for that.

This plugin can be enabled alongside other plugin , but the driver must have support for enough I/O ports. Most drivers can easily be changed to support more ports, especially so if a custom board map file is used.

BTW the core supports tool changes via an ATC, but you will have to write a dedicated plugin for the one you have.

MisterDiz commented 2 years ago

I am using the iMXRT1062 driver on a Teensy 4.1 with a custom board map. I'm going around in circles trying as you suggest to tweak the driver, any help would be greatly received.

As an example, to add one more output, presumably I add to _my_boardmap.h

    #define AUXOUTPUT4_PIN      (24u) // AUX4

and then to driver.c

    #ifdef AUXOUTPUT4_PIN
      static gpio_t AuxOut4;
    #endif

and then under

   static output_signal_t outputpin[] = {

...

   #ifdef AUXOUTPUT3_PIN
      { .id = Output_Aux3,            .port = &AuxOut3,       .pin = AUXOUTPUT3_PIN,          .group = PinGroup_AuxOutput }
   #endif

.id .port and .group aren't showing as referencing anything in Platform IO, so presumably there's more to do or I'm barking up the wrong tree?

Any simple way around the problem of defining more out ports would be most welcome.

terjeio commented 2 years ago

Any simple way around the problem of defining more out ports would be most welcome.

I have now added definitions for aux inputs and outputs up to #7 (8 ports) in driver.c. If more than that is needed the core has to be updated.

MisterDiz commented 2 years ago

That is wonderful. Works great. Thanks so much.

Because I am using the RGB plugin, which out of the box works nicely with ports AuxOut0-2, can I easily move the ports of the M62-65 commands to AuxOut4-7? Presumably I just shuffle things around the port definitions in lines 472-478 in driver.c?

terjeio commented 2 years ago

Because I am using the RGB plugin, which out of the box works nicely with ports AuxOut0-2, can I easily move the ports of the M62-65 commands to AuxOut4-7?

Aux 4-7 will be moved to the lowest M62-65 port numbers automatically, check with the $pins command for how they are assigned.

Presumably I just shuffle things around the port definitions in lines 472-478 in driver.c?

No, there is no need for that.

MisterDiz commented 2 years ago

My problem is that the RGB plugin defaults to status changes reading on Auxout0-2 (which also is controlled by M62-65 commands). If I change it so that the RGB pins are on auxoutput 4, 5, 6 I can't see an easy way to make that plugin read the corresponding higher ports, so I was thinking that it would be easier to adjust the driver.

terjeio commented 2 years ago

Ouch, I see now that the RGB plugin does not claim the ports with the new method that shuffles the M62-M65 port numbers. The fans plugin does, and adds settings for the end user to select port > pin bindings. The best way is to ask the author to upgrade or for you to submit a pull request with the changes needed? You may also change it to suit your needs - this way there is no need to modify the driver, which will not solve your problem anyway?

If modifying the plugin the base_port_out variable has to changed to an array of ports, then required ports can be claimed like this:

base_port_out[0] = 0;
ioport_claim(Port_Digital, Port_Output, &base_port_out[0], "pin description1");
base_port_out[1] = 1;
ioport_claim(Port_Digital, Port_Output, &base_port_out[1], "pin description2");
etc...
MisterDiz commented 2 years ago

Great stuff, its really amazing to have a Grbl variant with so much power. I have given 5ocworkshop a gentle nudge so hopefully he can update the RGB status plugin.

Now that I have 4 ports for my ATC controlled by M62-66 and 3 ports awaiting RGB, I have also added the Fans plugin. I have defined 1 fan on port 7 in my board map, which shows up as Auxout7 using $pins. Do I need to do anything else? I was expecting that issuing M106 P7 and M106 P7 would turn the fan on/off.

terjeio commented 2 years ago

I was expecting that issuing M106 P7 and M106 P7 would turn the fan on/off.

The P parameter value for fans always starts from 0 regardless of which port they are mapped to. And for fan 0 you can skip the P parameter and just use M106/M107.

MisterDiz commented 2 years ago

Unfortunately when sending M106/M107, IoSender reports Unsupported or Invalid g-code command found in block

I have dropped the RGB plugin for the time being and not sent any $-settings (I didn't quite understand the significance in the read me). The only thing I've done is define AUXOUTPUT7_PIN in the board map.

terjeio commented 2 years ago

Does Fan 0 show up in the $pins list? This is what I get when fan 0 is bound to port 0:

...
[PIN:34,Aux out 0,Fan 0]
[PIN:32,Aux out 1,P0]
[PIN:33,Aux out 2,P1]
...

and when bound to port 2 by setting $386 to 2:

...
[PIN:34,Aux out 0,P0]
[PIN:32,Aux out 1,P1]
[PIN:33,Aux out 2,Fan 0]
...

Is $386 set to the correct and available Aux port?

image

With the edge build of ioSender I get a checkbox for switching the fan on/off, this can be done even when a gode program is running:

image

MisterDiz commented 2 years ago

Not quite like that! regardless of $386 settings, I get this

[PIN:41,Aux out 0,] [PIN:40,Aux out 1,] [PIN:39,Aux out 2,P2] [PIN:38,Aux out 3,P3] [PIN:27,Aux out 7,P4]

M64-65 Commands still working with Aux Out 0-3 Flood & Mist Checkboxes are working, fans not so much.

terjeio commented 2 years ago

Ok, there is a memory leak at play - and an issue when aux pins are not contiguous.

The memory leak can be fixed by replacing this code with

    if((hal.port.num_digital_in = aux_n_in = aux_inputs->n_pins)) {
        hal.port.wait_on_input = wait_on_input;
        hal.port.register_interrupt_handler = register_interrupt_handler;
        in_map = malloc(aux_n_in * sizeof(aux_n_in));
    }

    if((hal.port.num_digital_out = aux_n_out = aux_outputs->n_pins)) {
        hal.port.digital_out = digital_out;
        out_map = malloc(aux_n_out * sizeof(aux_n_out));
    }

Assign pin 27 as AUXOUTPUT4_PIN until I can figure out how to solve non-contiguous definitions.

Be aware when changing $386 the controller has to be power cycled as the Teensy does not have a reset button..

MisterDiz commented 2 years ago

Sweet, now I have M106/7 and M62-M65 commands working. Thanks once again.

The Fans plug in wanted to take port priority, so I defined AUXOUTPUT0_PIN for it to behave as desired...

[PIN:27,Aux out 0,Fan 0]
[PIN:41,Aux out 1,P0]
[PIN:40,Aux out 2,P1]
[PIN:39,Aux out 3,P2]
[PIN:38,Aux out 4,P3]

I hadn't clocked that $386 needed reboot to take effect. Not sure if this affected my previous reportings, apologies if so. Is it now the case that $390-$393 can assign to later ports? (I assume not, just curious)

I haven't heard back yet from the developer of the RGB plugin, so I thought that I'd follow your suggestion to modify. I'm not familiar with the syntax (programming is not my first language!), should the code look something like this...

// DRIVER RESET - Release ports
static void driverReset (void)
{
    driver_reset();

    int32_t idx_out = 2; // Ports count start at 0
    do {
        base_port_out[0] = 0;
        ioport_claim(Port_Digital, Port_Output, &base_port_out[0], "pin description1");
        base_port_out[1] = 1;
        ioport_claim(Port_Digital, Port_Output, &base_port_out[1], "pin description2");
} while(idx_out);

    // Be aware that changing things here can lead to debugging challenges
    (inspection_light_on = 0);
}

At this stage I am gunning for ports/auxouts 5-7

terjeio commented 2 years ago

Not sure if this affected my previous reportings, apologies if so. Is it now the case that $390-$393 can assign to later ports?

Correct, $390 is for binding Fan 0 to the Aux port number of your choice. $391 for Fan 1 if enabled etc...

I have just committed an update that forces the reported Aux port numbers to be contiguous regardless of the definition in the map file. This makes handling simpler in the code but may be confusing when creating a map file. End users should use the $pins command to find out which Aux port number is assigned to which pin (and to which function) - not the map file.

I'll come back to the RGB plugin code, it is late evening here.

MisterDiz commented 2 years ago

Great stuff once again Terjeio. Please don't worry about when you can look at the RGB code, it is definitely outside your remit and I'm sure you have way more important things to do. Thanks for all your diligent hard work.

terjeio commented 2 years ago

Try this:

rgb.zip

I have changed the enable define to the "official" #define STATUS_LIGHT_ENABLE 1 and added defines for the port numbers to use in line 64-66. I leave it to you to test.

MisterDiz commented 2 years ago

Thanks Terjeio, I get compile errors of this nature:

.../rgb.c:995:22: error: subscripted value is neither array nor pointer nor vector base_port_out[0] = 0;

etc

Sorry again for my ignorance, are you saying that the array code that you added to rgb.c is picked up by lines 64-66 in ioports.c? Do I need to do something like add #define STATUS_LIGHT_ENABLE 1 to _mymachine.h so that it is initialised in _pluginsinit.h?

btw loving how easy IoSender makes it to invert my required selection of aux out pins in the settings GUI :)

terjeio commented 2 years ago

... I get compile errors

This cannot be with the code I posted above in rgb.zip... Have you updated the correct file?

There was a mix of array values and separate values for each port, I opted to use the separate values instead as theye were used more places than the array and is easier to read.

Sorry again for my ignorance, are you saying that the array code that you added to rgb.c is picked up by lines 64-66 in ioports.c?

In the file I posted above I added these defines for mapping the port number to the LED:

// If driver supports explicit port claiming specify which aux port numbers to use here.
// If not the last three available ports are claimed.
#define PORT_RED_LED    0
#define PORT_GREEN_LED  1
#define PORT_BLUE_LED   2

It is not picked up by the ioports.c code directly, assignment is through a layered API. Calling ioport_claim() in the plugin init does the trick:

        ok = ioport_claim(Port_Digital, Port_Output, &red_port, rgb_aux_out[0]);
        ok &= ioport_claim(Port_Digital, Port_Output, &green_port, rgb_aux_out[1]);
        ok &= ioport_claim(Port_Digital, Port_Output, &blue_port, rgb_aux_out[2]);

Do I need to do something like add #define STATUS_LIGHT_ENABLE 1 to my_machine.h so that it is initialised in plugins_init.h?

Yes.

MisterDiz commented 2 years ago

Have you updated the correct file?

Duh! Clearly not! That heinous crime and also failing to comment out the old plugin. $pins never looked so good

[PIN:27,Aux out 0,Fan 0]
[PIN:41,Aux out 1,P0]
[PIN:40,Aux out 2,P1]
[PIN:39,Aux out 3,P2]
[PIN:38,Aux out 4,P3]
[PIN:29,Aux out 5,LED Red]
[PIN:31,Aux out 6,LED Green]
[PIN:32,Aux out 7,LED Blue]

I'm off to do my happy dance. Terje you are a rock star.

Juank23 commented 1 year ago

good afternoon, I have a rp2040 zero which has a rgb ws2812 and currently has worked perfect with grblHal and I would like to add this plugin to work the rgb led I have no idea how to do it, I managed to install and configure the grblhal thanks to the help of Terje Io, I hope you can help me thanks. RP2040-Zero-details-7

terjeio commented 1 year ago

WS2812 uses a serial interface over a single pin for control, thus it cannot be controlled via the I/O ports interface.

Juank23 commented 1 year ago

Thanks again Terjeio, I mean the RGB plugin to work with my pico zero, I can't find a way to assign the GP16 pin to make the RGB led work.

terjeio commented 1 year ago

To make the RGB plugin work with a WS2812 LED it has to be modified to control it via the single pin WS2812 serial interface. The RGB plugin uses three pins to control each LED (Red, Green and Blue) individually on/off. I do not have a WS2812 LED/breakout board at hand so I am not able to write and test the required code.

Juank23 commented 1 year ago

Terjeio, to send you one, or through paypal so you can buy it I remain attentive thanks for your help.

terjeio commented 1 year ago

Try this code, it should set the LED to a not too strong red colour:

my_plugin.zip

Add the files to the root of the project (in the same directory as main.c is located) and enable compilation of my_plugin.c.

I found the code in a Pi Pico example and have modified it for grblHAL, I leave it to you to test it and expand on it.

Juank23 commented 1 year ago

Good morning Terjeio, I tell you that I added the plugin to grblHAL and it works fine, the rgb led turns red, and at the end of the code change the value and change the color it works, but for the functions that the rgb datron plugin has to work , ?? thanks for your help....

terjeio commented 1 year ago

but for the functions that the rgb datron plugin has to work , ??

Replace the code that claims the io ports for the LED with init code from the above example and replace this code with call to urgb_u32().

Juank23 commented 1 year ago

good morning, Terjeio, I didn't understand :(

terjeio commented 1 year ago

I didn't understand

Change:

void status_light_init() {

    uint32_t offset = pio_add_program(pio0, &ws2812_program);

    ws2812_program_init(pio0, 3, offset, WS2812_PIN, 800000, true);

    last_state == STATE_CHECK_MODE;

    // Save away current HAL pointers so that we can use them to keep
    // any chain of M-code handlers intact.
    memcpy(&user_mcode, &hal.user_mcode, sizeof(user_mcode_ptrs_t));

    // Redirect HAL pointers to our code.
    hal.user_mcode.check = check;
    hal.user_mcode.validate = validate;
    hal.user_mcode.execute = execute;

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

    on_report_options = grbl.on_report_options;         // Subscribe to report options event
    grbl.on_report_options = onReportOptions;           // Nothing here yet

    on_state_change = grbl.on_state_change;             // Subscribe to the state changed event by saving away the original
    grbl.on_state_change = RGBonStateChanged;              // function pointer and adding ours to the chain.

    on_realtime_report = grbl.on_realtime_report;       // Subscribe to realtime report events AKA ? reports
    grbl.on_realtime_report = onRealtimeReport;         // Nothing here yet

    on_program_completed = grbl.on_program_completed;   // Subscribe to on program completed events (lightshow on complete?)
    grbl.on_program_completed = onProgramCompleted;     // Checkered Flag for successful end of program lives here

    on_execute_realtime = grbl.on_execute_realtime;     // Subscribe to the realtime execution event
    grbl.on_execute_realtime = realtimeIndicators;      // Spindle monitoring, flashing LEDs etc live here

    state_start_timestamp = hal.get_elapsed_ticks();    // Initialize timer for flash loop, timestamp?

}

and

// Accessed as RGB_MASKS[RGB_YELLOW].R for the red value, RGB_MASKS[RGB_YELLOW].G for green etc.
static COLOR_LIST RGB_MASKS[8] = {
        { 0, 0, 0 },  // Off [0]
        { 100, 0, 0 },  // Red [1]
        { 0, 100, 0 },  // Green [2]
        { 0, 0, 100 },  // Blue [3]
        { 100, 100, 0 },  // Yellow [4]
        { 100, 0, 100 },  // Magenta [5]
        { 0, 100, 100 },  // Cyan [6]
        { 100, 100, 100 },  // White [7]
};

You may have to change values here to match the LED/for the intensity and or colour you want. and

// Physically sets the requested RGB light combination.
// Always sets all three LEDs to avoid unintended light combinations
static void rgb_set_led (uint8_t reqColor) { 
    static uint8_t currColor = 99;
    if ( currColor != reqColor) {
        currColor = reqColor;
        put_pixel(urgb_u32(RGB_MASKS[reqColor].R, RGB_MASKS[reqColor].G, RGB_MASKS[reqColor].B));
        state_start_timestamp = hal.get_elapsed_ticks();        // Update start time for state
    }
}

add put put_pixel() and urgb_u32() from the zip to the code as well.

Juank23 commented 1 year ago

terjeio, I change these values in rgb.c? I remain attentive thank you

terjeio commented 1 year ago

terjeio, I change these values in rgb.c?

Yes.

Juank23 commented 1 year ago

Good morning terjeio, it doesn't work :(

terjeio commented 1 year ago

@Juank23 The rgb.c code will not compile against recent core versions, I have added a PR with a fix - hopefully it will be accepted. Here is a working version without the WS2812 changes:

rgb.zip

Juank23 commented 1 year ago

Good morning, I tell you that I changed the code, it compiles but does nothing else I remain attentive thanks rgb

terjeio commented 1 year ago

@Juank23 Zip your modified code and upload to a comment in the new issue I've created - I am closing this as the original issue has been resolved.