Hello-
I am using c-code in Linux and TCP/IP to communicate with a T7. I am creating a pulse on a DIO channel with a predetermined frequency, duty cycle, and pulse count. I am not doing any counting. I have a wait interval to allow the pulses to be generated before shutting down the dio section. How can I safely kill the output of the pulses using for example cntl-c? I am observing that even when I use the ljm_handler routine, the pulses continue to completion after the cntl-c. I am driving a stepper motor; if I issue an incorrect motion command, I would like to be able to immediately kill the output for safety reasons. What's the correct way to do this?
Thank you.
relevant code section:
err = LJM_StartInterval(INTERVAL_HANDLE, 1000 * delay_time);
ErrorCheck(err, "LJM_StartInterval");
err = LJM_eWriteNames(handle, NUM_FRAMES_CONFIGURE, aNamesConfigure,
aValuesConfigure, &errAddress);
ErrorCheckWithAddress(err, errAddress, "LJM_eWriteNames - aNamesConfigure");
err = LJM_WaitForNextInterval(INTERVAL_HANDLE, &SkippedIntervals);
ErrorCheck(err, "LJM_WaitForNextInterval");
if (SkippedIntervals > 0) {
printf("SkippedIntervals: %d\n", SkippedIntervals);
}
//MillisecondSleep(delay_time);
// Turn off pulses
err = LJM_eWriteNames(handle, NUM_FRAMES_DISABLE, aNamesDisable,
aValuesDisable, &errAddress);
ErrorCheckWithAddress(err, errAddress, "LJM_eWriteNames - aNamesDisable");
err = LJM_CleanInterval(INTERVAL_HANDLE);
ErrorCheck(err, "LJM_CleanInterval");
You mention ljm_handler. Does that mean you're using code like what's described in the "Custom Cleanup on Linux/macOS" section of the following page?
https://labjack.com/support/software/api/ljm/does-ljm-handle-signals
If you're using sigaction, are you able to see output from your handler? If so, you should be able to call LJM_eWriteNames to disable the pulse.
Please assess your application's risk responsibly. It may be important for your application to stop stream in the event of a computer crash or communication failure.
You can use the Watchdog to reconfigure DIO after a delay period of no communication:
https://labjack.com/support/datasheets/t-series/watchdog
On-board Lua scripting can also be used in a similar way:
https://labjack.com/support/datasheets/t-series/lua-scripting
Thanks for your response and suggestion regarding implementing Watchdog; I will consider that.
Yes, I am using the implementation in the provided link for ljm_handler, and I am seeing a response from it when I execute cntl-c. However, it was unclear to me how to implement LJM_eWriteNames from the handler routine since, as I understand it, no arguments (such as "handle") can be passed to the handler routine. I would have to store "handle", (as well as NUM_FRAMES_DISABLE, aNamesDisable, aValuesDisable, &errAddress) as global variables, which you don't currently do in the C examples. Is that correct, and if so, advisable?
You can use static global variables. I've updated the example:
https://labjack.com/support/software/api/ljm/does-ljm-handle-signals
This didn't work, but perhaps I'm doing it incorrectly. Firstly, there's a typo in the example you linked, it should read: int err = LJM_eWriteName(handleToCleanUp, "DIO_DIRECTION", 0x0000); (notice the "e" infront of WriteName.
Secondly, the pulse I am generating is not effected by the modification to the example. I have my pulse on FIO3. I noticed FIO1 is going high when I hit cntl-c, but nothing happens to FIO3. As written, does the example handle my configuration?
You may also want to consider a hard-wired, as opposed to software based method for mitigating risk. That's almost always a more direct and simpler method.
Whatever the approach you take depends on the risk assessment of the application (as well as the legislation that your equipment operates under).
Thanks for pointing out the typo. I've fixed it.
The example was a demonstration of what could be done. I've updated it to make that more clear:
int err = LJM_eWriteName(handleToCleanUp, ...);
In your first post, you gave your code for turning off the pulses:
// Turn off pulses
err = LJM_eWriteNames(handle, NUM_FRAMES_DISABLE, aNamesDisable,
aValuesDisable, &errAddress);
Does that work outside of your signal handler? When you add it into your signal handler, does it work?
So adding the disable statement via LJM_eWriteNames within the handler routine successfully kills the pulses when I issue cntl-c. However, in the code I am explicitely disabling a specific DIO output channel. In my application, the user may select any of the available output DIO channels depending on which stepper motor is to be used. Is there a way of disabling all the channels with one statement using LJM_eWriteNames, or do I need to handle all possible scenarios by disabling all the channels regardless of which one was actually in use? I've attached my code below for reference.
Thanks for all your help.
For each DIO# that are possible in your application, setting DIO#_EF_ENABLE to 0 would disable each of the pulse outs. You could write each of the DIO#_EF_ENABLEs in a single eWriteNames call.