From 55ce426476c2719365769c2f6ba4ff7031f57429 Mon Sep 17 00:00:00 2001 From: Anders Sandstrom Date: Wed, 26 Jan 2022 15:08:24 +0100 Subject: [PATCH] Add plc-commands WIOP --- ecmc_plugin_grbl/.vscode/settings.json | 6 +- ecmc_plugin_grbl/ecmcGrbl.cpp | 276 +++++++++++++++++-------- ecmc_plugin_grbl/ecmcGrbl.h | 75 ++++--- ecmc_plugin_grbl/ecmcGrblDefs.h | 2 + ecmc_plugin_grbl/ecmcGrblWrap.cpp | 28 +++ ecmc_plugin_grbl/ecmcGrblWrap.h | 18 +- ecmc_plugin_grbl/ecmcPluginGrbl.c | 106 +++++++++- grbl/grbl_gcode.c | 2 +- iocsh/test.script | 36 +--- 9 files changed, 387 insertions(+), 162 deletions(-) diff --git a/ecmc_plugin_grbl/.vscode/settings.json b/ecmc_plugin_grbl/.vscode/settings.json index ddceb65..1e94aca 100644 --- a/ecmc_plugin_grbl/.vscode/settings.json +++ b/ecmc_plugin_grbl/.vscode/settings.json @@ -14,6 +14,10 @@ "regex": "cpp", "tuple": "cpp", "type_traits": "cpp", - "utility": "cpp" + "utility": "cpp", + "bitset": "cpp", + "memory": "cpp", + "random": "cpp", + "future": "cpp" } } \ No newline at end of file diff --git a/ecmc_plugin_grbl/ecmcGrbl.cpp b/ecmc_plugin_grbl/ecmcGrbl.cpp index 5d1427b..d14e19b 100644 --- a/ecmc_plugin_grbl/ecmcGrbl.cpp +++ b/ecmc_plugin_grbl/ecmcGrbl.cpp @@ -43,8 +43,8 @@ volatile uint8_t sys_rt_exec_accessory_override; // Global realtime executor bit // Start worker for socket read() void f_worker_read(void *obj) { if(!obj) { - printf("%s/%s:%d: Error: Worker read thread ecmcGrbl object NULL..\n", - __FILE__, __FUNCTION__, __LINE__); + printf("%s/%s:%d: Error: Worker read thread ecmcGrbl object NULL..\n", + __FILE__, __FUNCTION__, __LINE__); return; } ecmcGrbl * grblObj = (ecmcGrbl*)obj; @@ -98,9 +98,15 @@ ecmcGrbl::ecmcGrbl(char* configStr, // Init cfgDbgMode_ = 0; + cfgAutoStart_ = 0; destructs_ = 0; - connected_ = 0; + executeCmd_ = 0; + resetCmd_ = 0; + haltCmd_ = 0; + resumeCmd_ = 0; errorCode_ = 0; + ecmcError_ = 0; + errorCodeOld_ = 0; exeSampleTimeMs_ = exeSampleTimeMs; cfgXAxisId_ = -1; cfgYAxisId_ = -1; @@ -124,6 +130,11 @@ ecmcGrbl::ecmcGrbl(char* configStr, autoEnableExecuted_ = 1; } + // auto execute + if(cfgAutoStart_) { + executeCmd_ = 1; + } + // global varaible in grbl enableDebugPrintouts = cfgDbgMode_; @@ -132,14 +143,14 @@ ecmcGrbl::ecmcGrbl(char* configStr, throw std::out_of_range("No valid axis choosen."); } - // Create worker thread for reading socket - std::string threadname = "ecmc.grbl.read"; - if(epicsThreadCreate(threadname.c_str(), 0, 32768, f_worker_read, this) == NULL) { - throw std::runtime_error("Error: Failed create worker thread for read()."); - } + //// Create worker thread for reading socket + //std::string threadname = "ecmc.grbl.read"; + //if(epicsThreadCreate(threadname.c_str(), 0, 32768, f_worker_read, this) == NULL) { + // throw std::runtime_error("Error: Failed create worker thread for read()."); + //} // Create worker thread for main grbl loop - threadname = "ecmc.grbl.main"; + std::string threadname = "ecmc.grbl.main"; if(epicsThreadCreate(threadname.c_str(), 0, 32768, f_worker_main, this) == NULL) { throw std::runtime_error("Error: Failed create worker thread for main()."); } @@ -209,12 +220,18 @@ void ecmcGrbl::parseConfigStr(char *configStr) { cfgSpindleAxisId_ = atoi(pThisOption); } - // ECMC_PLUGIN_AUTO_ENABLE_AT_START_OPTION_CMD (1..ECMC_MAX_AXES) + // ECMC_PLUGIN_AUTO_ENABLE_AT_START_OPTION_CMD if (!strncmp(pThisOption, ECMC_PLUGIN_AUTO_ENABLE_AT_START_OPTION_CMD, strlen(ECMC_PLUGIN_AUTO_ENABLE_AT_START_OPTION_CMD))) { pThisOption += strlen(ECMC_PLUGIN_AUTO_ENABLE_AT_START_OPTION_CMD); cfgAutoEnableAtStart_ = atoi(pThisOption); } + // ECMC_PLUGIN_AUTO_START_OPTION_CMD + if (!strncmp(pThisOption, ECMC_PLUGIN_AUTO_START_OPTION_CMD, strlen(ECMC_PLUGIN_AUTO_START_OPTION_CMD))) { + pThisOption += strlen(ECMC_PLUGIN_AUTO_START_OPTION_CMD); + cfgAutoStart_ = atoi(pThisOption); + } + pThisOption = pNextOption; } free(pOptions); @@ -223,22 +240,26 @@ void ecmcGrbl::parseConfigStr(char *configStr) { // Read socket worker void ecmcGrbl::doReadWorker() { - // simulate serial connection here (need mutex) - printf("%s:%s:%d\n",__FILE__,__FUNCTION__,__LINE__); - for(;;) { - //while(serial_get_tx_buffer_count()==0) { - // delay_ms(1); - //} - //printf("%c",ecmc_get_char_from_grbl_tx_buffer()); - delay_ms(100); - } +// // simulate serial connection here (need mutex) +// if(cfgDbgMode_){ +// printf("%s:%s:%d\n",__FILE__,__FUNCTION__,__LINE__); +// } +// for(;;) { +// //while(serial_get_tx_buffer_count()==0) { +// // delay_ms(1); +// //} +// //printf("%c",ecmc_get_char_from_grbl_tx_buffer()); +// delay_ms(100); +// } } // Write socket worker void ecmcGrbl::doWriteWorker() { // simulate serial connection here (need mutex) std::string reply = ""; - printf("%s:%s:%d\n",__FILE__,__FUNCTION__,__LINE__); + if(cfgDbgMode_){ + printf("%s:%s:%d\n",__FILE__,__FUNCTION__,__LINE__); + } // Wait for grbl startup string before send comamnds"['$' for help]" // basically flush buffer @@ -249,15 +270,21 @@ void ecmcGrbl::doWriteWorker() { char c = ecmc_get_char_from_grbl_tx_buffer(); reply += c; if(c == '\n' && - reply.find(ECMC_PLUGIN_GRBL_GRBL_STARTUP_STRING) != std::string::npos ) { - printf("GRBL READY FOR COMMANDS: %s\n",reply.c_str()); - break; + reply.find(ECMC_PLUGIN_GRBL_GRBL_STARTUP_STRING) != std::string::npos ) { + if(cfgDbgMode_){ + printf("GRBL READY FOR COMMANDS: %s\n",reply.c_str()); + } + break; } } // GRBL ready, now we can send comamnds for(;;) { - if(grblCommandBuffer_.size() > grblCommandBufferIndex_ && getEcmcEpicsIOCState()==16 && autoEnableExecuted_) { + if( (grblCommandBuffer_.size() > grblCommandBufferIndex_) && + getEcmcEpicsIOCState()==16 && + autoEnableExecuted_ && + executeCmd_) { + epicsMutexLock(grblCommandBufferMutex_); std::string command = grblCommandBuffer_[grblCommandBufferIndex_]; @@ -266,10 +293,13 @@ void ecmcGrbl::doWriteWorker() { while(serial_get_rx_buffer_available() <= strlen(command.c_str())+1) { delay_ms(1); } - printf("Write command to grbl: %s\n",command.c_str()); + if(cfgDbgMode_){ + printf("Write command to grbl (command[%d] = %s)\n", + grblCommandBufferIndex_, + command.c_str()); + } ecmc_write_command_serial(strdup(command.c_str())); - reply = ""; - grblCommandBufferIndex_++; + reply = ""; // Wait for reply! for(;;) { while(serial_get_tx_buffer_count()==0) { @@ -278,20 +308,31 @@ void ecmcGrbl::doWriteWorker() { char c = ecmc_get_char_from_grbl_tx_buffer(); reply += c; if(c == '\n'&& reply.length() > 1) { - if(reply.find(ECMC_PLUGIN_GRBL_GRBL_OK_STRING) != std::string::npos) { - printf("GRBL Reply: OK: %s\n",reply.c_str()); + if(reply.find(ECMC_PLUGIN_GRBL_GRBL_OK_STRING) != std::string::npos) { + if(cfgDbgMode_){ + printf("GRBL Reply: OK (command[%d] = %s)\n", + grblCommandBufferIndex_, + command.c_str()); + } break; } else if(reply.find(ECMC_PLUGIN_GRBL_GRBL_ERR_STRING) != std::string::npos) { - printf("GRBL Reply: ERROR: %s (%s)\n",reply.c_str(),command.c_str()); + if(cfgDbgMode_){ + printf("GRBL Reply: ERROR (command[%d] = %s)\n", + grblCommandBufferIndex_, + command.c_str()); + } errorCode_ = ECMC_PLUGIN_GRBL_COMMAND_ERROR_CODE; // Stop Motion here!! break; } else { // keep waiting (no break) - printf("GRBL Reply: Non protocol: %s\n",reply.c_str()); + if(cfgDbgMode_){ + printf("GRBL Reply: Non protocol related: %s\n",reply.c_str()); + } } } } + grblCommandBufferIndex_++; } else { delay_ms(5); @@ -301,7 +342,9 @@ void ecmcGrbl::doWriteWorker() { // Main grbl worker (copied from grbl main.c) void ecmcGrbl::doMainWorker() { - printf("%s:%s:%d\n",__FILE__,__FUNCTION__,__LINE__); + if(cfgDbgMode_){ + printf("%s:%s:%d\n",__FILE__,__FUNCTION__,__LINE__); + } // Initialize system upon power-up. serial_init(); // Setup serial baud rate and interrupts @@ -373,36 +416,28 @@ void ecmcGrbl::doMainWorker() { if(destructs_) { return; } - printf("********************after protocol_main_loop()********************************\n"); + if(cfgDbgMode_){ + printf("********************after protocol_main_loop()********************************\n"); + } delay_ms(1); } } -void ecmcGrbl::autoEnableAtStart() { +void ecmcGrbl::autoEnableAxisAtStart(int ecmcAxisId) { if(!cfgAutoEnableAtStart_ || autoEnableExecuted_ || getEcmcEpicsIOCState()!=16) { return; } // write to ecmc - if(cfgXAxisId_>=0) { - setAxisEnable(cfgXAxisId_,1); - } - if(cfgYAxisId_>=0) { - setAxisEnable(cfgYAxisId_,1); - } - if(cfgZAxisId_>=0) { - setAxisEnable(cfgZAxisId_,1); - } - - if(getAllConfiguredAxisEnabled()) { - autoEnableExecuted_ = 1; - } + if(ecmcAxisId>=0) { + setAxisEnable(ecmcAxisId,1); + } } -bool ecmcGrbl::getEcmcAxisEnabled(int axis) { +bool ecmcGrbl::getEcmcAxisEnabled(int ecmcAxisId) { int ena=0; - getAxisEnabled(axis, &ena); + getAxisEnabled(ecmcAxisId, &ena); return ena; } @@ -430,50 +465,71 @@ double ecmcGrbl::getEcmcAxisActPos(int axis) { return pos; } -void ecmcGrbl::syncPositionIfNotEnabled() { +void ecmcGrbl::preExeAxes() { + preExeAxis(cfgXAxisId_,X_AXIS); + preExeAxis(cfgYAxisId_,Y_AXIS); + preExeAxis(cfgZAxisId_,Z_AXIS); + //spindle + autoEnableAxisAtStart(cfgSpindleAxisId_); + if(getAllConfiguredAxisEnabled()) { + autoEnableExecuted_ = 1; + } +} + +void ecmcGrbl::preExeAxis(int ecmcAxisId, int grblAxisId) { + syncAxisPositionIfNotEnabled(ecmcAxisId, grblAxisId); + autoEnableAxisAtStart(ecmcAxisId); +} + +void ecmcGrbl::syncAxisPositionIfNotEnabled(int ecmcAxisId, int grblAxisId) { + // sync positions when not enabled bool sync = 0; - if(cfgXAxisId_>=0) { - if(!getEcmcAxisEnabled(cfgXAxisId_)) { - sys_position[X_AXIS] = (int32_t)(double(settings.steps_per_mm[X_AXIS])*getEcmcAxisActPos(cfgXAxisId_)); - sync = 1; - } - } - if(cfgYAxisId_>=0) { - if(!getEcmcAxisEnabled(cfgYAxisId_)) { - sys_position[Y_AXIS] = (int32_t)(double(settings.steps_per_mm[Y_AXIS])*getEcmcAxisActPos(cfgYAxisId_)); - sync = 1; - } - } - if(cfgZAxisId_>=0) { - if(!getEcmcAxisEnabled(cfgZAxisId_)) { - sys_position[Z_AXIS] = (int32_t)(double(settings.steps_per_mm[Z_AXIS])*getEcmcAxisActPos(cfgZAxisId_)); - sync = 1; - } + if(ecmcAxisId<0) { + return; } + if(!getEcmcAxisEnabled(ecmcAxisId)) { + sys_position[grblAxisId] = (int32_t)(double(settings.steps_per_mm[grblAxisId])*getEcmcAxisActPos(ecmcAxisId)); + sync = 1; + } + if(sync) { plan_sync_position(); + gc_sync_position(); } } // prepare for rt here -int ecmcGrbl::enterRT() { +int ecmcGrbl::enterRT() { return 0; } // grb realtime thread!!! int ecmcGrbl::grblRTexecute(int ecmcError) { - if(ecmcError) { - //Stop motion here!!! + if(getEcmcEpicsIOCState()!=16) { + return 0; + } + + if((ecmcError_ == 0 && ecmcError>0) || (errorCode_>0 && errorCodeOld_ == 0)) { + setHalt(0); + setHalt(1); + setReset(0); + setReset(1); + setExecute(0); + printf("Error encountered: ecmc 0x%x, plugin 0x%x\n",ecmcError,errorCode_); + ecmcError_ = ecmcError; + errorCodeOld_ = errorCode_; return errorCode_; } - syncPositionIfNotEnabled(); - autoEnableAtStart(); + ecmcError_ = ecmcError; + errorCodeOld_ = errorCode_; + //auto enable, sync positions + preExeAxes(); + double sampleRateMs = 0.0; - if(grblInitDone_ && autoEnableExecuted_) { while(timeToNextExeMs_ < exeSampleTimeMs_ && sampleRateMs >= 0) { sampleRateMs = ecmc_grbl_main_rt_thread(); @@ -487,25 +543,59 @@ int ecmcGrbl::grblRTexecute(int ecmcError) { timeToNextExeMs_-= exeSampleTimeMs_; } } - // write to ecmc - if(cfgXAxisId_>=0) { - setAxisExtSetPos(cfgXAxisId_,double(sys_position[X_AXIS])/double(settings.steps_per_mm[X_AXIS])); - } - if(cfgYAxisId_>=0) { - setAxisExtSetPos(cfgYAxisId_,sys_position[Y_AXIS]/settings.steps_per_mm[Y_AXIS]); - } - if(cfgZAxisId_>=0) { - setAxisExtSetPos(cfgZAxisId_,sys_position[Z_AXIS]/settings.steps_per_mm[Z_AXIS]); - } -// if(cfgSpindleAxisId_>=0) { -// setAxisTargetVel(xxx); -// } + + //update setpoints + postExeAxes(); return errorCode_; } -//void ecmcGrbl::setExecute(int execute) { -// -//} +void ecmcGrbl::postExeAxis(int ecmcAxisId, int grblAxisId) { + if(ecmcAxisId>=0) { + setAxisExtSetPos(ecmcAxisId,double(sys_position[grblAxisId])/double(settings.steps_per_mm[grblAxisId])); + } +} + +void ecmcGrbl::postExeAxes() { + postExeAxis(cfgXAxisId_,X_AXIS); + postExeAxis(cfgYAxisId_,Y_AXIS); + postExeAxis(cfgZAxisId_,Z_AXIS); + // if(cfgSpindleAxisId_>=0) { + // setAxisTargetVel(xxx); + // } +} + +// trigg start of g-code +int ecmcGrbl::setExecute(int exe) { + if(!executeCmd_ && exe) { + // + } + executeCmd_ = exe; + return 0; +} + +int ecmcGrbl::setHalt(int halt) { + if(!haltCmd_ && halt) { + //suspend with a "CMD_FEED_HOLD" command maybe? + } + haltCmd_ = halt; + return 0; +} + +int ecmcGrbl::setResume(int resume) { + if(!resumeCmd_ && resume) { + //hepp + } + resumeCmd_ = resume; + return 0; +} + +int ecmcGrbl::setReset(int reset) { + if(!resetCmd_ && reset) { + mc_reset(); + } + resetCmd_ = reset; + return 0; +} // Avoid issues with std:to_string() std::string ecmcGrbl::to_string(int value) { @@ -515,9 +605,13 @@ std::string ecmcGrbl::to_string(int value) { } void ecmcGrbl::addCommand(std::string command) { - printf("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__); + if(cfgDbgMode_){ + printf("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__); + } epicsMutexLock(grblCommandBufferMutex_); grblCommandBuffer_.push_back(command.c_str()); epicsMutexUnlock(grblCommandBufferMutex_); - printf("%s:%s:%d: Buffer size %d\n",__FILE__,__FUNCTION__,__LINE__,grblCommandBuffer_.size()); + if(cfgDbgMode_){ + printf("%s:%s:%d: Buffer size %d\n",__FILE__,__FUNCTION__,__LINE__,grblCommandBuffer_.size()); + } } diff --git a/ecmc_plugin_grbl/ecmcGrbl.h b/ecmc_plugin_grbl/ecmcGrbl.h index 1084647..7fb71b9 100644 --- a/ecmc_plugin_grbl/ecmcGrbl.h +++ b/ecmc_plugin_grbl/ecmcGrbl.h @@ -40,39 +40,52 @@ class ecmcGrbl : public asynPortDriver { double exeSampelTimeMs); ~ecmcGrbl(); - void doReadWorker(); - void doMainWorker(); - void doWriteWorker(); - int enterRT(); - int grblRTexecute(int ecmcError); - void addCommand(std::string command); - + void doReadWorker(); + void doMainWorker(); + void doWriteWorker(); + int enterRT(); + int grblRTexecute(int ecmcError); + void addCommand(std::string command); + int setExecute(int exe); + int setHalt(int halt); + int setResume(int resume); + int setReset(int reset); private: - void parseConfigStr(char *configStr); - void autoEnableAtStart(); - bool getEcmcAxisEnabled(int axis_id); - bool getAllConfiguredAxisEnabled(); - double getEcmcAxisActPos(int axis); - void syncPositionIfNotEnabled(); - static std::string to_string(int value); - int cfgDbgMode_; - int cfgXAxisId_; - int cfgYAxisId_; - int cfgZAxisId_; - int cfgSpindleAxisId_; - int cfgAutoEnableAtStart_; - int destructs_; - int connected_; - int errorCode_; - double exeSampleTimeMs_; - int grblInitDone_; + void parseConfigStr(char *configStr); + void preExeAxes(); + void postExeAxes(); + void preExeAxis(int ecmcAxisId, int grblAxisId); + void postExeAxis(int ecmcAxisId, int grblAxisId); + void autoEnableAxisAtStart(int ecmcAxisId); + bool getEcmcAxisEnabled(int ecmcAxisId); + bool getAllConfiguredAxisEnabled(); + double getEcmcAxisActPos(int axis); + void syncAxisPositionIfNotEnabled(int ecmcAxisId, int grblAxisId); + static std::string to_string(int value); + int cfgDbgMode_; + int cfgXAxisId_; + int cfgYAxisId_; + int cfgZAxisId_; + int cfgSpindleAxisId_; + int cfgAutoEnableAtStart_; + int cfgAutoStart_; + int destructs_; + int executeCmd_; + int resetCmd_; + int haltCmd_; + int resumeCmd_; + int errorCode_; + int ecmcError_; + int errorCodeOld_; + double exeSampleTimeMs_; + int grblInitDone_; std::vector grblCommandBuffer_; - int grblCommandBufferIndex_; - epicsMutexId grblCommandBufferMutex_; - bool firstCommandWritten_; - int autoEnableExecuted_; - int grblExeCycles_; - double timeToNextExeMs_; + unsigned int grblCommandBufferIndex_; + epicsMutexId grblCommandBufferMutex_; + bool firstCommandWritten_; + int autoEnableExecuted_; + int grblExeCycles_; + double timeToNextExeMs_; }; #endif /* ECMC_GRBL_H_ */ diff --git a/ecmc_plugin_grbl/ecmcGrblDefs.h b/ecmc_plugin_grbl/ecmcGrblDefs.h index 464c3d0..a07bf82 100644 --- a/ecmc_plugin_grbl/ecmcGrblDefs.h +++ b/ecmc_plugin_grbl/ecmcGrblDefs.h @@ -20,11 +20,13 @@ #define ECMC_PLUGIN_Z_AXIS_ID_OPTION_CMD "Z_AXIS=" #define ECMC_PLUGIN_SPINDLE_AXIS_ID_OPTION_CMD "SPINDLE_AXIS=" #define ECMC_PLUGIN_AUTO_ENABLE_AT_START_OPTION_CMD "AUTO_ENABLE=" +#define ECMC_PLUGIN_AUTO_START_OPTION_CMD "AUTO_START=" #define ECMC_PLUGIN_ASYN_PREFIX "plugin.grbl" #define ECMC_PLUGIN_GRBL_GENERAL_ERROR_CODE 0x100 #define ECMC_PLUGIN_GRBL_COMMAND_ERROR_CODE 0x101 +#define ECMC_PLUGIN_AXIS_AT_LIMIT_ERROR_CODE 0x102 #define ECMC_PLUGIN_GRBL_GRBL_STARTUP_STRING "for help]" #define ECMC_PLUGIN_GRBL_GRBL_OK_STRING "ok" #define ECMC_PLUGIN_GRBL_GRBL_ERR_STRING "error" diff --git a/ecmc_plugin_grbl/ecmcGrblWrap.cpp b/ecmc_plugin_grbl/ecmcGrblWrap.cpp index 6608531..2a88cda 100644 --- a/ecmc_plugin_grbl/ecmcGrblWrap.cpp +++ b/ecmc_plugin_grbl/ecmcGrblWrap.cpp @@ -71,6 +71,34 @@ int realtime(int ecmcError) { return 0; } +int setExecute(int exe) { + if(grbl){ + return grbl->setExecute(exe); + } + return 0; +} + +int setHalt(int halt) { + if(grbl){ + return grbl->setHalt(halt); + } + return 0; +} + +int setResume(int resume) { + if(grbl){ + return grbl->setResume(resume); + } + return 0; +} + +int setReset(int reset) { + if(grbl){ + return grbl->setReset(reset); + } + return 0; +} + void deleteGrbl() { if(grbl) { delete (grbl); diff --git a/ecmc_plugin_grbl/ecmcGrblWrap.h b/ecmc_plugin_grbl/ecmcGrblWrap.h index 2dd15c3..ad4b3e3 100644 --- a/ecmc_plugin_grbl/ecmcGrblWrap.h +++ b/ecmc_plugin_grbl/ecmcGrblWrap.h @@ -34,10 +34,26 @@ int createGrbl(char *configStr, int exeSampleTimeMs); */ int enterRT(); -/** \brief execute from rt loop\n +/** \brief rt loop\n */ int realtime(int ecmcError); +/** \brief execute g-code\n + */ +int setExecute(int exe); + +/** \brief halt motion\n + */ +int setHalt(int halt); + +/** \brief resume grbl\n + */ +int setResume(int resume); + +/** \brief reset grbl\n + */ +int setReset(int reset); + // Delete object void deleteGrbl(); diff --git a/ecmc_plugin_grbl/ecmcPluginGrbl.c b/ecmc_plugin_grbl/ecmcPluginGrbl.c index 8ea8649..d63b691 100644 --- a/ecmc_plugin_grbl/ecmcPluginGrbl.c +++ b/ecmc_plugin_grbl/ecmcPluginGrbl.c @@ -98,9 +98,25 @@ int grblEnterRT(){ int grblExitRT(void){ return 0; } -// Plc function for connect to can -double grbl_connect() { - return 0; + +// Plc function for execute grbl code +double grbl_set_execute(double exe) { + return setExecute((int)exe); +} + +// Plc function for halt grbl +double grbl_mc_halt(double halt) { + return setHalt((int)halt); +} + +// Plc function for resume grbl +double grbl_mc_resume(double halt) { + return setResume((int)halt); +} + +// Plc function for reset grbl +double grbl_mc_reset(double halt) { + return setReset((int)halt); } // Register data for plugin so ecmc know what to use @@ -117,7 +133,8 @@ struct ecmcPluginData pluginDataDef = { " "ECMC_PLUGIN_Y_AXIS_ID_OPTION_CMD": Ecmc Axis id for use as grbl Y axis, default = disabled (=-1).\n" " "ECMC_PLUGIN_Z_AXIS_ID_OPTION_CMD": Ecmc Axis id for use as grbl Z axis, default = disabled (=-1).\n" " "ECMC_PLUGIN_SPINDLE_AXIS_ID_OPTION_CMD": Ecmc Axis id for use as grbl spindle axis, default = disabled (=-1).\n" - " "ECMC_PLUGIN_AUTO_ENABLE_AT_START_OPTION_CMD"<1/0>: Auto enable the linked ecmc axes autmatically before start, default = disabled (=0).\n" + " "ECMC_PLUGIN_AUTO_ENABLE_AT_START_OPTION_CMD"<1/0>: Auto enable the linked ecmc axes autmatically before start, default = disabled (=0).\n" + " "ECMC_PLUGIN_AUTO_START_OPTION_CMD"<1/0>: Auto start g-code at ecmc start, default = disabled (=0).\n" , // Plugin version .version = ECMC_EXAMPLE_PLUGIN_VERSION, @@ -133,17 +150,17 @@ struct ecmcPluginData pluginDataDef = { .realtimeExitFnc = grblExitRT, // PLC funcs .funcs[0] = - { /*----can_connect----*/ + { /*----grbl_set_execute----*/ // Function name (this is the name you use in ecmc plc-code) - .funcName = "grbl_connect", + .funcName = "grbl_set_execute", // Function description - .funcDesc = "double grbl_connect() : Connect to grbl interface (from config str).", + .funcDesc = "double grbl_set_execute() : Trigg execution of loaded g-code at positive edge of ", /** * 7 different prototypes allowed (only doubles since reg in plc). * Only funcArg${argCount} func shall be assigned the rest set to NULL. **/ - .funcArg0 = grbl_connect, - .funcArg1 = NULL, + .funcArg0 = NULL, + .funcArg1 = grbl_set_execute, .funcArg2 = NULL, .funcArg3 = NULL, .funcArg4 = NULL, @@ -155,7 +172,76 @@ struct ecmcPluginData pluginDataDef = { .funcArg10 = NULL, .funcGenericObj = NULL, }, - .funcs[1] = {0}, // last element set all to zero.. + .funcs[1] = + { /*----can_connect----*/ + // Function name (this is the name you use in ecmc plc-code) + .funcName = "grbl_mc_halt", + // Function description + .funcDesc = "double grbl_mc_halt() : Halt grbl motion at positive edge of ", + /** + * 7 different prototypes allowed (only doubles since reg in plc). + * Only funcArg${argCount} func shall be assigned the rest set to NULL. + **/ + .funcArg0 = NULL, + .funcArg1 = grbl_mc_halt, + .funcArg2 = NULL, + .funcArg3 = NULL, + .funcArg4 = NULL, + .funcArg5 = NULL, + .funcArg6 = NULL, + .funcArg7 = NULL, + .funcArg8 = NULL, + .funcArg9 = NULL, + .funcArg10 = NULL, + .funcGenericObj = NULL, + }, + .funcs[2] = + { /*----grbl_mc_resume----*/ + // Function name (this is the name you use in ecmc plc-code) + .funcName = "grbl_mc_resume", + // Function description + .funcDesc = "double grbl_mc_resume() : Resume halted grbl motion at positive edge of ", + /** + * 7 different prototypes allowed (only doubles since reg in plc). + * Only funcArg${argCount} func shall be assigned the rest set to NULL. + **/ + .funcArg0 = NULL, + .funcArg1 = grbl_mc_resume, + .funcArg2 = NULL, + .funcArg3 = NULL, + .funcArg4 = NULL, + .funcArg5 = NULL, + .funcArg6 = NULL, + .funcArg7 = NULL, + .funcArg8 = NULL, + .funcArg9 = NULL, + .funcArg10 = NULL, + .funcGenericObj = NULL, + }, + .funcs[3] = + { /*----can_connect----*/ + // Function name (this is the name you use in ecmc plc-code) + .funcName = "grbl_mc_reset", + // Function description + .funcDesc = "double grbl_mc_reset() : Reset grbl at positive edge of ", + /** + * 7 different prototypes allowed (only doubles since reg in plc). + * Only funcArg${argCount} func shall be assigned the rest set to NULL. + **/ + .funcArg0 = NULL, + .funcArg1 = grbl_mc_reset, + .funcArg2 = NULL, + .funcArg3 = NULL, + .funcArg4 = NULL, + .funcArg5 = NULL, + .funcArg6 = NULL, + .funcArg7 = NULL, + .funcArg8 = NULL, + .funcArg9 = NULL, + .funcArg10 = NULL, + .funcGenericObj = NULL, + }, + .funcs[4] = {0}, // last element set all to zero.. // PLC consts .consts[0] = {0}, // last element set all to zero.. }; diff --git a/grbl/grbl_gcode.c b/grbl/grbl_gcode.c index 250db1d..6770817 100644 --- a/grbl/grbl_gcode.c +++ b/grbl/grbl_gcode.c @@ -56,7 +56,7 @@ void gc_init() // limit pull-off routines. void gc_sync_position() { - PRINTF_DEBUG(""); + //PRINTF_DEBUG(""); system_convert_array_steps_to_mpos(gc_state.position,sys_position); } diff --git a/iocsh/test.script b/iocsh/test.script index 946f556..44035a8 100644 --- a/iocsh/test.script +++ b/iocsh/test.script @@ -59,7 +59,7 @@ epicsEnvSet("PLUGIN_VER" ,"develop") require ecmc_plugin_grbl $(PLUGIN_VER) epicsEnvSet(ECMC_PLUGIN_FILNAME,"/home/pi/epics/base-7.0.5/require/${E3_REQUIRE_VERSION}/siteMods/ecmc_plugin_grbl/$(PLUGIN_VER)/lib/${EPICS_HOST_ARCH=linux-x86_64}/libecmc_plugin_grbl.so") -epicsEnvSet(ECMC_PLUGIN_CONFIG,"DBG_PRINT=0;X_AXIS=1;Y_AXIS=2;AUTO_ENABLE=1;") # Only one option implemented in this plugin +epicsEnvSet(ECMC_PLUGIN_CONFIG,"DBG_PRINT=1;X_AXIS=1;Y_AXIS=2;AUTO_ENABLE=1;AUTO_START=1;") # Only one option implemented in this plugin ${SCRIPTEXEC} ${ecmccfg_DIR}loadPlugin.cmd, "PLUGIN_ID=0,FILE=${ECMC_PLUGIN_FILNAME},CONFIG='${ECMC_PLUGIN_CONFIG}', REPORT=1" epicsEnvUnset(ECMC_PLUGIN_FILNAME) epicsEnvUnset(ECMC_PLUGIN_CONFIG) @@ -68,32 +68,14 @@ epicsEnvUnset(ECMC_PLUGIN_CONFIG) ecmcGrblAddCommand("G1X20Y20F180"); ecmcGrblAddCommand("G2X0Y0R20"); ecmcGrblAddCommand("G0X10Y10"); -#ecmcGrblAddCommand("G2X0adadsdY0R20"); -ecmcGrblAddCommand("G1X0Y20"); -ecmcGrblAddCommand("G1X10Y0F360"); -ecmcGrblAddCommand("G4P1"); -ecmcGrblAddCommand("G1X50Y50F180"); -ecmcGrblAddCommand("G4P1"); -ecmcGrblAddCommand("G1X0Y0F360"); -ecmcGrblAddCommand("G1X20Y20F180"); -ecmcGrblAddCommand("G2X0Y0R20"); -ecmcGrblAddCommand("G0X10Y10"); -ecmcGrblAddCommand("G1X0Y20"); -ecmcGrblAddCommand("G1X10Y0F360"); -ecmcGrblAddCommand("G4P1"); -ecmcGrblAddCommand("G1X50Y50F180"); -ecmcGrblAddCommand("G4P1"); -ecmcGrblAddCommand("G1X0Y0F360"); -ecmcGrblAddCommand("G1X20Y20F180"); -ecmcGrblAddCommand("G2X0Y0R20"); -ecmcGrblAddCommand("G0X10Y10"); -ecmcGrblAddCommand("G1X0Y20"); -ecmcGrblAddCommand("G1X10Y0F360"); -ecmcGrblAddCommand("G4P1"); -ecmcGrblAddCommand("G1X50Y50F180"); -ecmcGrblAddCommand("G4P1"); -ecmcGrblAddCommand("G1X0Y0F360"); +ecmcGrblAddCommand("G2X0adadsdY0R20"); +ecmcGrblAddCommand("G1X0Y0"); +#ecmcGrblAddCommand("G1X0Y20"); +#ecmcGrblAddCommand("G1X10Y0F360"); +#ecmcGrblAddCommand("G4P1"); +#ecmcGrblAddCommand("G1X50Y50F180"); +#ecmcGrblAddCommand("G1X0Y0"); ############################################################################## ## PLC 0 @@ -114,7 +96,7 @@ $(SCRIPTEXEC) ($(ecmccfg_DIR)setAppMode.cmd) #asynSetTraceMask(MC_CPU1, -1, 0x41) # Note need to test 0x21 later.. #asynSetTraceMask(MC_CPU1, -1, 0x21) -asynSetTraceMask(MC_CPU1, -1, 0x41) +asynSetTraceMask(MC_CPU1, -1, 0x0) iocInit() dbpf $(IOC):Axis1.SPAM 0