M100 to M199 User-Defined Commands Return Value

More
31 Oct 2013 02:02 #40432 by guru_florida
Hi,

I would like to use the M1xx codes to execute a batch file. No problem figuring that out, but when the batch file returns does the value get inserted into any of the variable positions? I would like to test for command SUCCESS/FAIL.

I am going to attach an atmel programmer to my CNC head and have it program all the units in my PCB panel. Batch file would run the avr command, and if it failed I'd have it print what position failed so I can mark it for later. I might also have it do a POT (Power-ON test) and sensor test in the process. I could get even more fancy and have it laser etch a BAD MARK area...but probably not worth the time.

C

Please Log in or Create an account to join the conversation.

More
31 Oct 2013 06:20 #40435 by andypugh

Hi,I would like to use the M1xx codes to execute a batch file. No problem figuring that out, but when the batch file returns does the value get inserted into any of the variable positions? I would like to test for command SUCCESS/FAIL.


Is the M1xx running bash or something like Python?

If bash, then
halcmd setp motion.analog-in-00 25
would put the value 25 somewhere where the M66 code could see it.

I don't think you can set parameters with halcmd (but I might be wrong). I think is is possible in python (linuxcnc.command.mdi("#100 = 25") but I have not tried that.
The following user(s) said Thank You: guru_florida

Please Log in or Create an account to join the conversation.

More
31 Oct 2013 22:29 #40454 by ArcEye
Hi

The question of return values from user M codes comes up at frequent intervals and is the source of some frustration.

At present the only options are as Andy describes, the most useful probably being the M66 one, if it is to be read in GCode.
With the increasing access being provided to internal values, primarily via python, in the master, hopefully a more logical method will be arrived at soon.

If you want to capture the system retval from a command inside a user M code script, this becomes even more convolute.

The reason for this is the way that the M Code commands are executed.

emctask.cc takes the command and formats it to add to the interp_list
static void user_defined_add_m_code(int num, double arg1, double arg2)
{
    // num      is the m_code number, typically 00-99 corresponding to M100-M199
    char fmt[EMC_SYSTEM_CMD_LEN];
    EMC_SYSTEM_CMD system_cmd;

    //we call FINISH() to flush any linked motions before the M1xx call, 
    //otherwise they would mix badly
    FINISH();
    strcpy(fmt, user_defined_fmt[user_defined_function_dirindex[num]]);
    strcat(fmt, " %f %f");
    snprintf(system_cmd.string, sizeof(system_cmd.string), fmt, num, arg1, arg2);
    interp_list.append(system_cmd);
}
There is no return from this function

After the command goes through the NML messaging system it is eventually executed in emctaskmain.cc
Having determined that the command is of type EMC_SYSTEM_CMD, it is forked and the only return value refers to an error with the fork process, not the retval of the actual command,
so that is completely lost.
int emcSystemCmd(char *s)
{
    char buffer[EMC_SYSTEM_CMD_LEN];
    char *argv[EMC_SYSTEM_CMD_LEN / 2 + 1];

    if (0 != emcSystemCmdPid) {
	// something's already running, and we can only handle one
	if (emc_debug & EMC_DEBUG_TASK_ISSUE) {
	    rcs_print
		("emcSystemCmd: abandoning process %d, running ``%s''\n",
		 emcSystemCmdPid, s);
	}
    }

    emcSystemCmdPid = fork();

    if (-1 == emcSystemCmdPid) {
	// we're still the parent, with no child created
	if (emc_debug & EMC_DEBUG_TASK_ISSUE) {
	    rcs_print("system command ``%s'' can't be executed\n", s);
	}
	return -1;
    }

    if (0 == emcSystemCmdPid) {
	// we're the child
	// convert string to argc/argv
	argvize(s, buffer, argv, EMC_SYSTEM_CMD_LEN);
	// drop any setuid privileges
	setuid(getuid());
	execvp(argv[0], argv);
	// if we get here, we didn't exec
	if (emc_debug & EMC_DEBUG_TASK_ISSUE) {
	    rcs_print("emcSystemCmd: can't execute ``%s''\n", s);
	}
	exit(-1);
    }
    // else we're the parent
    return 0;
}


What I have done in the past where the system return is important, is to write it to a file from the user M Code script.
This file can then be read from a userspace component or whatever as required.

Ideally the user MCode would take several more parameters and there would be one or more fixed return value addresses which can be acccessed through GCode.

At present we are working with what we have B)

regards
The following user(s) said Thank You: guru_florida

Please Log in or Create an account to join the conversation.

More
31 Oct 2013 22:31 #40455 by guru_florida
I was thinking bash, but I would be fine learning a bit of python to do it too. I also figured the answer might be halcmd, which is fine if that is the only way. Would be nice if linuxcnc did put the return value in #00 which are reserved for O parameters anyway. (if I remember right.)

Thanks for the tip!

Please Log in or Create an account to join the conversation.

More
31 Oct 2013 22:43 #40456 by guru_florida
Thanks ArcEye for the explanation of why and I get why it isn't so simple. I can make do with the M66 work-around.

Please Log in or Create an account to join the conversation.

Time to create page: 0.123 seconds
Powered by Kunena Forum