Perfect! Thanks Brandon!
Since the com ports are sticky, that’s good enough for me. And I suspected the averaging/scaling was in the scaledFeedback but wanted to check.
I’m a little leery about sending stuff out to see if/what response I get. I know odds are small that I would put anything into a weird state, but I’d rather not risk it and the com ports being sticky means I don’t need to.
By the way, here is the code I came up with to soft start the JRKs for motion platform use with SimTools from xsimulator.net in case anyone else would find it useful. It’s all based on the example in the 12v12 manual with only a few changes/additions. Thanks to you guys for the head start!
Built using MinGW on Win10 worked great! It’s certainly not pretty. I was just trying to get things to work and haven’t had time to really comment or clean up.
The source:
// Uses POSIX functions to send and receive data from a jrk.
// NOTE: The jrk's input mode must be "Serial".
// NOTE: The jrk's serial mode must be set to "USB Dual Port".
// NOTE: You must change the 'const char * device' line below.
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#ifdef _WIN32
#define O_NOCTTY 0
#else
#include <termios.h>
#endif
char version[10] = "0.2b";
// Reads a variable from the jrk.
// The 'command' argument must be one of the two-byte variable-reading
// commands documented in the "Variable Reading Commands" section of
// the jrk user's guide.
int jrkGetVariable(int fd, unsigned char command)
{
if(write(fd, &command, 1) == -1)
{
perror("error writing");
return -1;
}
unsigned char response[2];
if(read(fd,response,2) != 2)
{
perror("error reading");
return -1;
}
return response[0] + 256*response[1];
}
// Gets the value of the jrk's Feedback variable (0-4095).
int jrkGetFeedback(int fd)
{
return jrkGetVariable(fd, 0xA5);
}
// Gets the value of the jrk's Scaled Feedback variable (0-4095).
int jrkGetScaledFeedback(int fd)
{
return jrkGetVariable(fd, 0xA7);
}
// Gets the value of the jrk's Target variable (0-4095).
int jrkGetTarget(int fd)
{
return jrkGetVariable(fd, 0xA3);
}
// Sets the jrk's Target variable (0-4095).
int jrkSetTarget(int fd, unsigned short target)
{
unsigned char command[] = {0xC0 + (target & 0x1F), (target >> 5) & 0x7F};
if (write(fd, command, sizeof(command)) == -1)
{
perror("error writing"); return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
printf("Home vers. %s\n", version);
// Validate inputs
printf("Inputs = %d.\n", argc);
if (argc != 4)
{
printf("Usage is home.exe <step size> <com1> <com2> eg: home.exe 2 COM4 COM7\n");
return -1;
}
printf("%s %s %s %s\n", argv[0], argv[1], argv[2], argv[3]);
int step = atoi(argv[1]);
if ((step < 1) || (step > 10))
{
step = 1;
}
printf("Using step size of %d.\n", step);
// Open the 1st Jrk's virtual COM port.
char dev1[10];
char dev2[10];
sprintf (dev1, "\\\\.\\%s", argv[2]);
sprintf (dev2, "\\\\.\\%s", argv[3]);
const char * device1 = dev1;
int fd1 = open(device1, O_RDWR | O_NOCTTY);
if (fd1 == -1)
{
perror(device1);
return 1;
}
// Open the 2nd Jrk's virtual COM port.
const char * device2 = dev2;
int fd2 = open(device2, O_RDWR | O_NOCTTY);
if (fd2 == -1)
{
perror(device2);
return 1;
}
#ifndef _WIN32
struct termios options;
tcgetattr(fd, &options);
options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
options.c_oflag &= ~(ONLCR | OCRNL);
tcsetattr(fd, TCSANOW, &options);
#endif
int sfeedback1 = jrkGetScaledFeedback(fd1);
printf("Current Scaled Feedback1 is %d.\n", sfeedback1);
int sfeedback2 = jrkGetScaledFeedback(fd2);
printf("Current Scaled Feedback2 is %d.\n", sfeedback2);
int setting1 = jrkGetTarget(fd1);
printf("Old Setting1 is %d.\n", setting1);
int setting2 = jrkGetTarget(fd2);
printf("Old Setting2 is %d.\n", setting2);
// Starting positions
int target1 = sfeedback1;
int target2 = sfeedback2;
int final1 = 2048;
int final2 = 2048;
int working1 = 1;
int working2 = 1;
while ((working1 == 1) || (working2 == 1))
{
if (target1 > final1)
{
target1 -= step;
jrkSetTarget(fd1, target1);
if (target1 <= final1)
{
jrkSetTarget(fd1, final1);
working1 = 0;
}
}
else
{
target1 += step;
jrkSetTarget(fd1, target1);
if (target1 >= final1)
{
jrkSetTarget(fd1, final1);
working1 = 0;
}
}
if (target2 > final2)
{
target2 -= step;
jrkSetTarget(fd2, target2);
if (target2 <= final2)
{
jrkSetTarget(fd2, final2);
working2 = 0;
}
}
else
{
target2 += step;
jrkSetTarget(fd2, target2);
if (target2 >= final2)
{
jrkSetTarget(fd2, final2);
working2 = 0;
}
}
usleep (5);
}
setting1 = jrkGetTarget(fd1);
printf("New Setting1 is %d.\n", setting1);
setting2 = jrkGetTarget(fd2);
printf("New Setting2 is %d.\n", setting2);
close(fd1);
close(fd2);
printf("Done!\n");
return 0;
}