开源改变世界!!

用户 MCode 模板问题 #50

推推 grbl 2年前 (2023-02-08) 182次浏览
关闭
5ocworkshop 开了这个issue 2021 年 7 月 29 日 · 7条评论
关闭

用户 MCode 模板问题#50

5ocworkshop 开了这个issue 2021 年 7 月 29 日 · 7条评论

评论

用户 MCode 模板问题 #50

您最近添加的模板很棒,但我无法让用户 mcode 示例 1 正常工作。我想知道你是否可以看一下,看看是否有明显的错误。我复制并编辑了你的代码。它在我的树中编译得很好。

我在 IOSender 中从 MDI 调用 mcode:M356 Q1我收到ok但没有任何可见的事情发生。

这是正确的调用方式吗?我是用户 mcode 的新手。

我在 gcode.h 中临时添加了一个条目,如下所示:
RGB_Inspection_Light = 356, //!< 356 - M356 // ** Collides with Plasma ** On = 1, Off = 2, RGB white LED inspection light in RGB plugin

我目前不包括 plasma 模块,我没有看到此文件中定义的 plasma 代码,但我确实注意到 github 摘要页面上提到了 356 美元。这可能是问题所在吗?

这是代码部分:

// check - check if M-code is handled here.
// parameters: mcode - M-code to check for (some are predefined in user_mcode_t in grbl/gcode.h), use a cast if not.
// returns:    mcode if handled, UserMCode_Ignore otherwise (UserMCode_Ignore is defined in grbl/gcode.h).
static user_mcode_t check (user_mcode_t mcode)
{
    return mcode == RGB_Inspection_Light 
                     ? mcode                                                            // Handled by us.
                     : (user_mcode.check ? user_mcode.check(mcode) : UserMCode_Ignore); // If another handler present then call it or return ignore.
}

// validate - validate parameters
// parameters: gc_block - pointer to parser_block_t struct (defined in grbl/gcode.h).
//             gc_block->words - holds a bitfield of parameter words available.
//             If float values are NAN (Not A Number) this means they are not available.
//             If integer values has all bits set to 1 this means they are not available.
// returns:    status_code_t enum (defined in grbl/gcode.h): Status_OK if validated ok, appropriate status from enum if not.

static status_code_t validate (parser_block_t *gc_block, parameter_words_t *deprecated)
{
    status_code_t state = Status_GcodeValueWordMissing;

    switch(gc_block->user_mcode) {

        case RGB_Inspection_Light:
            if(gc_block->words.p && !isnan(gc_block->values.p))             // Check if P parameter value is supplied.
                state = Status_BadNumberFormat;                             // Return error if so.

            if(gc_block->words.q && isnan(gc_block->values.q))              // Check if Q parameter value is supplied.
                state = Status_BadNumberFormat;                             // Return error if not.

            if(state != Status_BadNumberFormat && gc_block->words.q) {      // Are required parameters provided?
                if(gc_block->values.q > 0.0f && gc_block->values.q <= 5.0f) // Yes, is Q parameter value in range (1-5)?
                    state = Status_OK;                                      // Yes - return ok status.
                else
                    state = Status_GcodeValueOutOfRange;                    // No - return error status.
                if(gc_block->words.q)                                       // If P parameter is present set
                    gc_block->values.p = 1.0f;                              // value to 1 for execution.
                gc_block->words.p = gc_block->words.q = Off;                // Claim parameters.
                gc_block->user_mcode_sync = true;                           // Optional: execute command synchronized
            }
            break;

        default:
            state = Status_Unhandled;
            break;
    }

    // If not handled by us and another handler present then call it.
    return state == Status_Unhandled && user_mcode.validate ? user_mcode.validate(gc_block, deprecated) : state;
}

// execute - execute M-code
// parameters: state - sys.state (bitmap, defined in system.h)
//             gc_block - pointer to parser_block_t struct (defined in grbl/gcode.h).
// returns:    -
static void execute (sys_state_t state, parser_block_t *gc_block) {

    bool handled = true;

    switch(gc_block->user_mcode) {

        case RGB_Inspection_Light:
            // do something: Q parameter value can be found in gc_block->values.q.
            //               P parameter has its value in gc_block->values.p set to 1 if present, NAN if not.
            if (gc_block->values.q == 1) {
                rgb_set_state(RGB_WHITE);
            }
            else {
                if (gc_block->values.q == 2)
                   rgb_set_state(RGB_OFF);
            }
            break;

        default:
            handled = false;
            break;
    }


    if(!handled && user_mcode.execute)          // If not handled by us and another handler present
        user_mcode.execute(state, gc_block);    // then call it.
}

And I have the relevant sections in my init function:

`void my_plugin_init() // Init function called from drivers_init()
{
    if(hal.port.num_digital_out >= 3) {

        hal.port.num_digital_out -= 3;  // Remove the our outputs from the list of available outputs
        base_port = hal.port.num_digital_out;

        if(hal.port.set_pin_description) {  // Viewable from $PINS command in MDI
            uint32_t idx = 0;
            do {
                hal.port.set_pin_description(true, true, base_port + idx, rgb[idx]);
                if (idx == 0) { red_port = idx; } else
                if (idx == 1) { blue_port = idx; } else
                if (idx == 2) { green_port = idx; }
                idx++;                
            } while(idx <= 2);
        }
        startMS = hal.get_elapsed_ticks();

        // 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;

        on_state_change = grbl.on_state_change;         // Subscribe to the state changed event by saving away the original
        grbl.on_state_change = onStateChanged;          // 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;     

        on_program_completed = grbl.on_program_completed; // Subscribe to on program completed events (lightshow on complete?)
        grbl.on_program_completed = onProgramCompleted;   // Not using this yet, will add back if needed

        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

    } else
        protocol_enqueue_rt_command(warning_msg);
}`
 
用户 MCode 模板问题 #50
作者

现在是午夜过后,我发布了消息并关闭了一切并离开了商店。当我准备晚上睡觉时,我想“我想知道我是不是不小心挡住了灯”。所以我在 rgb_set_state(RGB_WHITE) 调用之后延迟了 (2000),果然灯亮了。

我会在早上改进我的状态处理,所以你可以无视我的请求。

不过,在我忘记之前,我确实必须更改您的代码中的某些内容才能使其编译。我将您的 mcode 示例中的第 86 行更改为:

return state == Status_Unhandled && user_mcode.validate ? user_mcode.validate(gc_block, parameter_words) : state;

return state == Status_Unhandled && user_mcode.validate ? user_mcode.validate(gc_block, deprecated) : state;

这是我的猜测,请告知这是否是有效的更改。

谢谢。

用户 MCode 模板问题 #50
贡献者

所以我延迟了(2000)

如果您希望您的插件是通用的(所有具有足够 ioport 的驱动程序都可以使用),请
hal.delay_ms(2000, NULL);
改用。

这是我的猜测,请告知这是否是有效的更改。

它是有效的,我会修复模板。

用户 MCode 模板问题 #50
作者

如果您希望您的插件是通用的(所有具有足够 ioport 的驱动程序都可以使用),请
hal.delay_ms(2000, NULL);
改用。

是的,我希望所有司机都能使用它。

我只是暂时将延迟作为调试方法投入使用,因为我知道它会阻塞,但是 hal 调用是一种非阻塞方式来产生延迟吗?那将非常有帮助。

用户 MCode 模板问题 #50
作者

另外,我注意到模板存储库自述文件摘要最后一句话中的“插件”链接是一个断开的链接。

“HAL 支持广泛的扩展可能性,这不会触及核心 grbl 代码库。可以在插件文件夹中找到一些示例。”

用户 MCode 模板问题 #50
作者

我只是在浏览 Marlin 的代码,这个代码引起了我的注意(有趣的是,我选择的代码只有 1 个)。在适用的情况下,您是否更愿意采用 Marlin 已经使用的代码?这是我添加的检查灯功能的合理近似值:https ://marlinfw.org/docs/gcode/M355.html

用户 MCode 模板问题 #50
贡献者

确定新 M 代码的第一站是 LinuxCNC,然后是 Marlin。如果找不到合适的匹配项,我会尽量避免使用可能与 grblHAL 相关的 Marlin 代码。

用户 MCode 模板问题 #50
贡献者

但是 hal 调用是一种非阻塞方式来产生延迟吗

是的,如果您提供回调函数。请注意,目前任何时候只能激活一个回调 – 我打算更改此设置。